Repository navigation
Make the file counts in CLAUDE.md and README.md checkable - #297
Merged
Merged
Conversation
Seven of the nine counts these two files advertise were wrong, two of them by
more than a factor of two:
langgraph_engine/*.py 244 -> 253
repo-wide *.py 395 -> 493
test_*.py 45 -> 100 (README said 44 in two other places)
unit tests 36 -> 91
integration tests 4 -> 5
docs/ files 156 -> 255
e2e / load 3 / 1 (correct by coincidence, not by check)
Correcting them is the smaller half. They went stale because nothing could tell
that they had, and README and CLAUDE.md had drifted to different wrong values
for the same figure -- 44 against 45 -- which is only possible when neither is
checked against anything.
docs/README.md carries the same kind of per-folder counts and they are right,
because test_docs_index_matches_the_tree.py compares them to a live enumeration.
This applies that technique to the remaining two files, so the drift cannot
recur rather than merely being fixed once.
Counts come from `git ls-files`, not the filesystem, for the reason the docs
index test records in its own docstring: the documentation describes the
repository, not whoever's working tree is on disk. A gitignored scratch file
would otherwise make every claim wrong in every clone but the author's.
Deliberately unchecked: CLAUDE.md's "578 classes, 3,985 methods" call-graph
figures, which would need a full AST build per test run and would churn on any
code change, and its "13 servers" MCP count, which describes repositories that
cannot be enumerated from here. A check that is expensive, or that cannot see
its subject, teaches people to ignore it.
Three things this was verified against rather than assumed:
The test was written first and watched fail on all fourteen claims before any
number was corrected, so it is known to read the real files rather than pass
vacuously. test_every_claim_pattern_matches_its_file guards the same property
permanently -- a regex that stops matching its file is a silent pass otherwise.
test_no_counter_returns_zero caught a bug in this file's own counters:
_test_modules_in added one to the prefix depth, so "unit tests" reported the
nine files one level deeper and the three per-directory counters reported zero.
The arithmetic guard alone would not have caught it -- 9 + 0 + 0 + 0 still equals
9 -- which is why both guards exist.
Adding this file changes the numbers it checks. It is a tracked test_*.py, so
the totals it must assert are the post-commit ones (100/91/121/493), not the
ones measured before staging it. Verified by staging the file and recomputing
from the index rather than by predicting the increment.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
piyushmakhija28
added a commit
that referenced
this pull request
Aug 7, 2026
…ections langgraph_engine/helper_nodes/ held five modules and 538 lines that nothing imported. CLAUDE.md has described it as "scheduled for removal in a follow-up cleanup" since the subpackage migration; this is that cleanup. Closes item 3 of issue #296. "No importers" was not the whole justification, and checking further changed what this commit does. All nine of the package's public node functions are also defined in orchestrator.py -- the module create_flow_graph actually wires -- so this was an extraction that was begun and never finished, not a component that lost its callers. Both copies were last touched by the same commit (06b0463, the Level/Step rename), which had been maintaining them in lockstep. Comparing the two copies function by function found five character-identical and four divergent. The divergences are mostly the adaptations a deeper package needs -- parent.parent.parent instead of parent.parent, renamed module constants, different log tags -- but two of them are documentation corrections that exist ONLY in the orphaned copy, with the stale text in the live one: save_workflow_memory's comment named ~/.claude/memory/sessions/ while the code beneath it writes to memory/logs/sessions/. The comment contradicted the line it described. optimize_context_after_level1 said "Level 3" in a docstring line, a summary line and an inline comment. Level 3 stopped existing in 06b0463, which renamed it to Level 2. The orphan's docstring was updated by that rename; the live one's was not. Both are ported into orchestrator.py here, before the deletion rather than alongside it, so nothing is discarded that the live module lacked. Deleting the package first and noticing afterwards is how a fix disappears without anyone recording that it ever existed. The Quick Info counts move 253 -> 248 and 493 -> 488. That was not spotted by hand: tests/test_doc_counts_match_the_tree.py, merged one commit ago in #297, failed on the deletion and named both figures. It is the first thing that enforcement caught, and it caught it immediately. Verified: orchestrator imports and create_flow_graph(hook_mode=True) builds a graph, every test that touches the orchestrator passes, all six CI gates pass, test collection is clean, and no .py file anywhere still names helper_nodes. CHANGELOG.md, docs/orchestration_prompt.md and docs/architecture/ still refer to the package. The CHANGELOG entry and the architecture draft are point-in-time records; orchestration_prompt.md explicitly sequenced this removal as separate work, which is exactly what happened. Rewriting any of them would falsify the history rather than correct it. Co-Authored-By: Claude Opus 5 (1M context) <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.
Closes item 1 of #296.
Seven of the nine file counts
CLAUDE.mdandREADME.mdadvertise were wrong, two by more than a factor of two:langgraph_engine/*.py*.pytest_*.pydocs/filesREADME.mdseparately claimed 44 for the same figureCLAUDE.mdput at 45, in two different places. Two documents drifting to different wrong values for one number is only possible when neither is checked against anything, and that — not the arithmetic — is what this PR is about.The approach is borrowed, not invented
docs/README.mdcarries the same kind of counts and they are correct, becausetests/test_docs_index_matches_the_tree.pycompares them against a live enumeration of the tree. This applies that technique to the remaining two files so the drift cannot recur, rather than fixing it once and waiting for it to happen again.Counts come from
git ls-files, not the filesystem, for the reason that test records in its own docstring: the documentation describes the repository, not whoever's working tree is on disk. Its first version countedos.listdirand passed locally while failing in CI, because a gitignored analysis dump existed on one machine and in no clone.What is deliberately not checked
CLAUDE.md's578 classes, 3,985 methodscall-graph figures would need a full AST build per test run and would churn on any code change. Its13 serversMCP count describes repositories that cannot be enumerated from here. A check that is expensive, or that cannot see its subject, teaches people to ignore it — so neither is asserted.Verified rather than assumed
The test was written first and watched fail on all fourteen claims before a single number was corrected, so it is known to read the real files rather than pass vacuously.
test_every_claim_pattern_matches_its_fileguards that property permanently — a regex that stops matching its file is otherwise a silent pass, which is exactly the failure mode being fixed.Its own guard caught a bug in its own counters.
_test_modules_inadded one to the prefix depth, so "unit tests" reported the nine files one level deeper (tests/*/test_*.py) and the three per-directory counters reported zero.test_no_counter_returns_zerofailed and named them. The arithmetic guard alone would not have caught it —9 + 0 + 0 + 0still equals9— which is why both guards exist.Adding this file changes the numbers it checks. It is a tracked
test_*.py, so the totals it must assert are the post-commit ones (100 / 91 / 121 / 493), not the ones measured before staging it. Confirmed by staging the file and recomputing from the index rather than by predicting the increment — a test that went red on its own merge commit would have been a poor advertisement for the idea.Local: the new file and
test_docs_index_matches_the_tree.pypass together (13 tests), every test that readsCLAUDE.mdorREADME.mdpasses,verify_open_encodingandverify_home_pathspass, collection is clean, andgit diff --numstatshows 2/2 and 8/8 rather than whole-file line-ending flips.CI is the authority on Linux and on py3.10/3.11 — the last PR proved that distinction the hard way.
🤖 Generated with Claude Code