Conversation
- Rewrite tutorial chapters 1–11 with hooks, structured sections, and forward-references - Add Why DI? as a top-level intro page - Add How-to with Tips and Multi-arity services (moved from Tutorial) - Add Reference section with a Middleware types stub - Reorder cljdoc.edn TOC to match the new structure - Update tutorial-to-md.sh to generate from how_to/ and reference/ - Update CI to commit the new doc subdirectories - Add planning artifacts under doc/_journey.md and doc/_structure.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrite the last tutorial chapter: rename "Graceful stop" to "Handling start failures", split the combined demo into two focused tests (built-deps-are-stopped, stop-errors-are-suppressed), and use inline ex-info throws instead of passing exceptions via the registry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
File prefixes a..l now follow the v6 chapter order alphabetically: a-your-first-system, b-dependencies, c-stopping-components, d-interactive-development, e-registries, f-abstractions, g-environment-variables, h-starting-many-keys, i-wiring-inside-data, j-transforming-values, k-composition-with-update-key, l-handling-start-failures. Namespaces, internal cross-links, cljdoc.edn paths, and doc/example.md and doc/why_di.md links are all updated. doc/example.md REPL-redef link now points at "Interactive development" instead of "Intro" since that material moved chapters. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
defmulti-as-service is a recipe, not a tutorial step. Moved the file to test/darkleaf/di/how_to/ with the matching namespace, and trimmed the intro and optional-dep prose. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename "Add a side dependency" to "Side dependencies" and move the file to test/darkleaf/di/how_to/. Reframe the recipe: tighten the hook to migrations-as-the-canonical-case and add a "Why not just list it as another root?" section that contrasts add-side-dependency with the vector-form di/start, pointing at the subsystem-registry pattern. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename "Log" to "Logging system lifecycle" and move the file to test/darkleaf/di/how_to/. Drop the "middleware" word in favour of plainer phrasing about argument order, and add a short note about why the test compares pr-str values. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename the chapter to "All public vars as a component" and move the file to test/darkleaf/di/how_to/. Cascade the namespace change through x_inspect_test.clj (which imports it) and the ns-publics docstring in core.clj. Drop the "middleware" word in the prose. Also add the chapter to cljdoc.edn — it was missing from the TOC since long before this restructure. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename "Multi system" to "Multiple systems" and move the file to test/darkleaf/di/how_to/. Replace the abstract intro with a concrete scenario — several web apps sharing the same database pool — and call out the identical-instance assertion inline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A Reference page is descriptive prose with example snippets, not a literate test file. Move the stub to a tracked plain markdown under doc/reference/middleware_types.md, drop the .clj wrapper, drop /doc/reference/ from .gitignore so the page is committed directly, and update the forward-links in the Registries, Environment variables, and Composition tutorial chapters. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bring the project notes in line with how the docs are organised now: - Mention doc/how_to/ (generated like tutorial/) and doc/reference/ (plain tracked markdown), plus the _journey.md / _structure.md planning artifacts. - Update the article cross-link example from the old a_intro_test path to the renamed a_your_first_system_test, and document the full cljdoc URL format for article-to-API-var links. - Add a new "Documentation conventions" section: audience, voice, terminology (no "middleware" in tutorial/how-to, math-style names, keyword-vs-symbol intent), directory layout, test idioms in chapter files (vs. strict regular tests), and when a Reference page earns its keep. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename middleware_types.md to middleware_argument.md and rewrite it as a reference for the values di/start/inspect/->memoize accept: function, map, sequence, nil, and java.util.function.Function. Add the order/precedence rules, the ->memoize positioning constraint, and a note on why dispatch is a cond over predicates rather than a protocol. Update the cljdoc.edn TOC label to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Capture the lessons from the design-doc work as a "Recurring mistakes to avoid" section, keyed on confident-but-wrong prose that is not grounded in the code or the author's model. Add the terminology rule that a key names a component, never a node, and point the reference link at the renamed middleware_argument.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A conceptual overview of how DI is built. A factory is what a key resolves to; a registry is a function from a key to a factory; a middleware is registry -> registry composition. The article walks the Factory protocol (dependencies/build/description), add-stop teardown, the two meanings of nil and the ::di/nil sentinel, decorator-style wrapping, di/inspect, and the running-system container, then closes on why the model has stayed stable since the first release. Link it into the cljdoc nav between Changelog and Tutorial. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Why DI? (doc/why_di.md) was written but never added to the navigation tree. It sits at a different altitude than Design — user-facing motivation vs how-it's-built — and the two cross-link, so Design did not supersede it. Place it after Changelog, before Design: motivation, then model, then the tutorial. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Design article (doc/design.md, added after the v6 plan) already covers the protocol contract, 'most things are already factories', the demolish -> add-stop history, the nil pitfall, and the decorator wrap — exactly the material that would have justified a standalone Factory reference page. Writing one on top of Design would duplicate both Design and the docstring, which the conventions forbid. Reference drops from 3 pages to 2 (Inspect, Middleware types). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document the return-value envelope: the vector of per-factory maps, the :key/:dependencies/:description entries, and the ::di/root and :undefined markers the walk itself contributes. Link the Factory protocol for the :description shapes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rename x_inspect_test.clj to reference/inspect_test.clj so the page lives under Reference and is generated by tutorial-to-md.sh like the tutorial/how-to chapters. Update the cljdoc nav, the .gitignore for generated reference pages, and the cross-links in integrant.md and log_test.clj. Document the two reference-page flavours in CLAUDE.md. Drop the variable-factory-regression test from the page: it was born in #33 to guard a custom Factory that did not implement the then separate FactoryDescription protocol. #58 merged description into Factory, so the case can no longer occur, and rendering a bare regression block in the reference article added no value. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The how-to's point is reusing one factory across several keys, not databases as a topic. Rename the file and namespace to match, reframe the intro around the pattern, and link the Factory protocol var. Also fold in the pending cljdoc nav restructure: the tutorial's Base/Advanced grouping becomes a flat Tutorial list plus a separate How-to section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Uncomment the rename-deps example so the intent is readable, and add the .disabled suffix. di/rename-deps is still commented out in core.clj, so the file cannot run as a test yet — keep it out of the runner like x_instrument_test.clj.disabled. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New How-to recipe that turns di/inspect output into Graphviz DOT and renders it. The graphviz function takes inspect data (not a root) so it composes with di/inspect. Includes a rendered SVG, a cljdoc nav entry, and marks the plan item done in _structure.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mark the planned Tutorial/How-to/Reference changes as implemented in _structure.md and _journey.md, and document the parked-draft and doc/images conventions in CLAUDE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Terminology: drop the outright ban on the word "middleware" in
tutorial/how-to chapters. It forced vague paraphrases ("shapes
di/start accepts") and contradicted the reference page's own title.
Instead introduce the term once, in the Registries chapter, then use
it plainly. Update CLAUDE.md convention accordingly.
Review fixes across the docs:
- Fix broken links to a non-existent middleware_types.md (now
middleware_argument.md) in three tutorial chapters, and a dead
anchor in middleware_argument.md (#middleware).
- Remove semicolons from prose (non-native-reader convention) in
several chapters and articles.
- Drop a TODO comment that leaked into the published Tips article,
and reframe its "group registries" tip around avoiding apply.
Remove the v6 planning artifacts (doc/_journey.md, doc/_structure.md)
and their CLAUDE.md pointers now that the restructure is done.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Record the Docker-based local preview steps and the gotchas found while previewing: articles come from a git revision (so the gitignored generated *_test.md need a throwaway force-add commit), the jar must be installed to ~/.m2, and images do not render under a local-path ingest because the raw-URL rewrite points at the local git path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Grounded in the gmonit test-suite pattern: one memoized registry for the whole suite, per-test overrides after it, a test-runner wrapper that releases the cache. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Also make the co-author trailer name the actual model instead of a hard-coded one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Also: a Tips section on conditional registry entries, the gmonit patterns research notes, and new lessons in CLAUDE.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop the documentation conventions and recurring-mistakes guides and the detailed cljdoc command listings. Keep workflow rules, a condensed cljdoc section (release flow, docs-update-without-release gotcha, cross-link rules), release/build gotchas, and Clojars notes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extend the Composition with update-key tutorial with a prose paragraph: f and args accept any factory, e.g. di/ref for a decorator with its own dependencies and di/template for an assembled options map. Mark plan items 3 and 4 as done. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hand-written recipe: put descriptions on deps-map bindings (keys are strings/keywords and can't hold metadata), then read them back via di/inspect → ::di/variable → the var's :arglists → clojure.core/destructure. Track the .md (gitignore) and add it to the cljdoc nav. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A hand-written registry middleware over p/Factory that wraps every :service at build time — tracing as the example (NewRelic SDK with its @Trace/reify-IFn tax), presented as the workable special case of the removed di/instrument. Co-Authored-By: Fable 5 <noreply@anthropic.com>
Keys are data — depend on 'other.ns/component without requiring the namespace; DI loads it at start via requiring-resolve. The example requires di itself with :as-alias, for the metadata keyword only. Co-Authored-By: Fable 5 <noreply@anthropic.com>
Read an EDN map of env vars as the last registry element — it overrides both earlier registries and the real environment, no dotenv tooling needed. Same contract as System/getenv: string values, env-parsing and :or defaults keep working. Co-Authored-By: Fable 5 <noreply@anthropic.com>
- di/start docstring: replace the removed di/instrument in the example, balance parens - di/stop docstring: document suppressed exceptions - di/derive docstring: the source key is optional, f receives nil; drop the useless -> in the example - di/add-side-dependency docstring: the example must be a component - di/env-parsing docstring: nil when the variable is not set - di/ns-publics docstring: keys are keywords, nil/unbound vars skipped - tutorial c: ::di/stop implies a component, no explicit kind needed - tutorial e: a registry group is sequential, not seqable - tutorial g: fix the next-chapter pointer - tutorial j: di/derive source key is optional, make f nil-safe - multimethods how-to: explain di/derive and the di/ref indirection - inspect: explain the #_#_:opts placeholder - why_di: link the tutorial and how-to articles from each section - instrumenting services: fix the Changelog link Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A side dependency that is built before the root and its dependencies. The implicit root now has two internal keys, ::prepended-side-dependency and ::added-side-dependency; both middlewares share one implementation and mark the pulled-in key with ::di/side-dependency true, so di/inspect output for add-side-dependency stays unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Migrations become the prepend example, the build order is stated as a fact, and the example app runs Flyway before the server via prepend-side-dependency. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Not listed in the cljdoc tree yet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- why_di: a redefined service keeps the dependencies resolved at start; adding a dependency requires a restart - di/log docstring: after-demolish! fires at stop; explain why the middleware should go last instead of demanding it - tutorial l: list where each error lives — thrown build failure, its cause, suppressed stop errors - tutorial e: the opening no longer denies that chapter b named the registry Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
darkleaf
commented
Jul 4, 2026
GITHUB_SHA is the commit the pushed tag points to, so the git dependency snippet on cljdoc now works. Readme.md on master keeps the placeholders. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Frame it as two production examples — a JVM shutdown hook and spootnik/signal — without recommending either. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.