docs: halve CLAUDE.md; disclose the release runbook - #450
Merged
Conversation
CLAUDE.md had ratcheted from 4.5 KB to 12.3 KB, with a compaction in June (#239) undone twice over. Roughly half of it cached lookups it points at: module docstrings, justfile recipe comments, pyproject settings. 12,312 B -> 6,485 B. Key files keeps only the cross-file rules a single-file read cannot give; the release runbook moves to docs/agents/release.md behind a pointer; Vocabulary folds into Project Overview; the three agent-skill subsections collapse to pointer bullets. Claude-Session: https://claude.ai/code/session_01FdBFyAZ6nntxXwPjy6Xm7p
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: 0387d0d | Previous: 1ea74ee | Ratio |
|---|---|---|---|
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type |
3150962.552859924 iter/sec (stddev: 1.1851549894469189e-8) |
3150940.0152010303 iter/sec (stddev: 1.0730284239262876e-8) |
1.00 |
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry |
3145391.77145479 iter/sec (stddev: 1.662659220005772e-8) |
3153308.3328560423 iter/sec (stddev: 1.3869427385051052e-8) |
1.00 |
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve |
22768.35790854921 iter/sec (stddev: 0.00000493342946672016) |
23399.43754533766 iter/sec (stddev: 0.000004615339361367785) |
1.03 |
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached |
17737.516297257764 iter/sec (stddev: 0.000008709434913273287) |
18258.21714941566 iter/sec (stddev: 0.000004561489209033697) |
1.03 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] |
464.64508433707266 iter/sec (stddev: 0.00007209321805544171) |
471.5927415437599 iter/sec (stddev: 0.00003828250486694024) |
1.01 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] |
444.6321812414162 iter/sec (stddev: 0.0000348048944793266) |
434.6057208849211 iter/sec (stddev: 0.00003444426182541086) |
0.98 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] |
382.56145041316813 iter/sec (stddev: 0.00005367517147349876) |
392.8902815455737 iter/sec (stddev: 0.00006907908303780609) |
1.03 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] |
2210.362277810931 iter/sec (stddev: 0.00002538488239235447) |
2152.947623918151 iter/sec (stddev: 0.000029919818633541512) |
0.97 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] |
1638.052326842746 iter/sec (stddev: 0.0001635689038616069) |
1492.0112310139875 iter/sec (stddev: 0.00020718819350787476) |
0.91 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] |
1143.7970935216567 iter/sec (stddev: 0.000037531433569632904) |
1094.9387142267738 iter/sec (stddev: 0.00004181430442129771) |
0.96 |
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container |
764442.2149950332 iter/sec (stddev: 7.794843731204289e-8) |
668555.3578371395 iter/sec (stddev: 3.9276643390822e-7) |
0.87 |
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope |
695509.5763049335 iter/sec (stddev: 3.165619866269698e-8) |
687167.058970974 iter/sec (stddev: 8.828710386969566e-8) |
0.99 |
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch |
2331.820803464456 iter/sec (stddev: 0.000020870851425105612) |
2313.7050977670237 iter/sec (stddev: 0.000014377940830019346) |
0.99 |
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control |
61954.786333179785 iter/sec (stddev: 0.0000019303053477744448) |
60846.949201084644 iter/sec (stddev: 0.000002033000360369562) |
0.98 |
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale |
46200.90365724546 iter/sec (stddev: 0.0000019529480509890943) |
46312.85170228115 iter/sec (stddev: 0.000002737063802782133) |
1.00 |
benchmarks/test_guard_resolve.py::test_g1_transient_resolve |
2009919.0510101174 iter/sec (stddev: 2.1246019626869907e-8) |
2059021.225734717 iter/sec (stddev: 3.525267068220601e-8) |
1.02 |
benchmarks/test_guard_resolve.py::test_g2_cached_resolve |
3549531.511551623 iter/sec (stddev: 8.00971141301041e-9) |
3333878.533607576 iter/sec (stddev: 9.155632916007022e-9) |
0.94 |
benchmarks/test_guard_resolve.py::test_g3_deep_chain |
756302.7053236016 iter/sec (stddev: 5.04290226160577e-8) |
752529.6472224294 iter/sec (stddev: 3.8674659173969325e-8) |
1.00 |
benchmarks/test_guard_resolve.py::test_g4_wide_resolve |
407642.0325729634 iter/sec (stddev: 1.0220917369224803e-7) |
406897.6392631225 iter/sec (stddev: 1.0525803375112558e-7) |
1.00 |
benchmarks/test_guard_resolve.py::test_g5_cross_scope |
1606704.9726527666 iter/sec (stddev: 2.3296986440126478e-8) |
1613190.1524936643 iter/sec (stddev: 2.3013119774949782e-8) |
1.00 |
benchmarks/test_guard_resolve.py::test_g9_context_resolve |
853256.6995140115 iter/sec (stddev: 3.657450489093486e-8) |
834636.1656132308 iter/sec (stddev: 4.6654796970009304e-8) |
0.98 |
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve |
502413.07745029044 iter/sec (stddev: 5.4033765793941776e-8) |
501884.23653582734 iter/sec (stddev: 7.309233830769732e-8) |
1.00 |
benchmarks/test_guard_resolve.py::test_g18_alias_hop |
2402040.004527426 iter/sec (stddev: 1.1352452224393983e-8) |
2239116.254855509 iter/sec (stddev: 1.557023081647912e-8) |
0.93 |
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain |
27244.44605168503 iter/sec (stddev: 0.000003515150280709954) |
27888.9265120092 iter/sec (stddev: 0.0000036969729607802292) |
1.02 |
benchmarks/test_guard_validate.py::test_g11_validate_wide |
16955.153612921993 iter/sec (stddev: 0.000004135922902105045) |
16748.589320779636 iter/sec (stddev: 0.000004229673015586571) |
0.99 |
This comment was automatically generated by workflow using github-action-benchmark.
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.
Why
CLAUDE.mdis loaded on every turn, and it ratchets. Size at each commit that touched it:It doubled in nine weeks; #449 alone added 39 lines by inlining
planning/README.md. Nothing in itwas stale — I re-checked every claim (justfile recipes,
asyncio_mode,line-length,select,--cov-fail-under=100, thevalidate=deprecation atmodern_di/container.py:110, the fourregistries, the 12+1 integrations). The problem is that half of it cached a lookup it already points
at, so each rule lived in two or three places and could rot in all but one:
CLAUDE.md, theresolver_compiler.pymodule docstring, andtest_resolve_costs_exactly_one_resolver_frame_per_node.wiring.py,dependency_graph.pyandintegrations.pybullets restated their module docstringsnear-verbatim;
scope.py— "Scope enum" — restated the filename.## Commandsnamed the justfile as source of truth, then copied its recipe comments verbatim.## Project OverviewduplicatedCONTEXT.md's opening plus a 13-integration roster thatls docs/integrations/gives free — a maintenance liability with no decision value.The file was failing its own admission check ("Can an agent get this by reading
modern_di/? → don'twrite it").
Design
Two moves: prune the caches, and disclose what only some runs need.
docs/agents/release.md)## Vocabulary, 240 → 0)Key fileskeeps only the five rules a single-file read cannot give: theresolver_compilerframebudget and its new-provider-type branch,
exceptions.pyowning every message and glyph, theshared-vs-per-container registry split,
dependency_graphwalkingWiringPlan.edges, andUNSETasthe shared miss marker. Everything derivable from opening the module is gone.
Cutting a releasefires a few times a year and cost every turn; it moves verbatim todocs/agents/release.md(a tree already excluded from the mkdocs site) behind a one-line pointer.The
INVARIANT:docstring-shape prose now citestests/test_invariant_census.py, which owns andenforces that shape, rather than restating it in nine lines.
Two additions rather than cuts. "Prose about mechanism has no home" now names this file as subject
to the same rule — that omission is what let it double. And the "read
CONTEXT.mdbefore naming aconcept" trigger from the deleted
## Vocabularyheading moves intoProject Overviewso thepointer survives its section.
One factual correction: the old line "Every module under
modern_di/except the package__init__.pyre-exports" reads as though every module is re-exported.__init__.pyexports onlyContainer,Group,Scope,exceptions,integrations,providers. The replacement sentencemakes no such claim.
Non-goals
relocation, not redesign.
CLAUDE.md's size or diffs it against module docstringswould stop the ratchet mechanically, but it would fail on legitimate growth and nothing in the repo
currently gates prose. Left for a follow-up if the file regrows a third time.
modern_di/. Where a bullet was the only home for a fact, the fact stayed inCLAUDE.md; nothing was pushed into a new module docstring.docs/agents/release.mdis not link-checked, same as the rest of that tree — a gap this PRdocuments in
## Commandsrather than closes.Verification
just test-ci— 512 passed, 100.00% line coverage (6030/6030). No Python changed.just lint-ci— ruff format, ruff check, ty all clean.just docs-build—mkdocs --strictbuilds;docs/agents/stays excluded from the site.root Markdown).
docs/adr/0011cites the registries entry (kept) and.github/PULL_REQUEST_TEMPLATE.mdcites "Where a fact goes" (kept).https://claude.ai/code/session_01FdBFyAZ6nntxXwPjy6Xm7p