fix(#38): single-source-of-truth for command + MCP tool counts#90
Merged
Merged
Conversation
Problem (issue #38): the CodeLens command count was hardcoded in 8 different places across the repo and had drifted to 5 different values (41, 45, 56, 57, 60). The actual runtime count is 64 commands. The existing regression test (tests/test_integration.py L281) used a loose `>= 41` assertion that would not catch silent command loss — every command could disappear and the test would still pass. Solution — single source of truth + strict enforcement: 1. scripts/sync_command_count.py (new) — reads COMMAND_REGISTRY and _TOOL_DEFINITIONS at runtime and rewrites every doc/metadata file with the correct counts. Supports --check (CI mode, exit 1 on drift) and --apply (write mode). KISS: one helper, regex-driven, no codegen/build system. 2. scripts/codelens.py — added --command-count flag that prints the runtime count and exits; --help description now includes the count so introspection works without parsing subcommand lists. 3. tests/test_integration.py — the loose `>= 41` assertion is now strict `== EXPECTED_COMMAND_COUNT` (== 64). Updated with a clear docstring explaining the update procedure when the count intentionally changes. 4. tests/test_command_count.py (new) — four enforcement tests: - test_command_count_helper_matches_runtime_registry - test_mcp_tool_count_math_is_consistent (total = cmd - {watch,serve}; static + dynamic = total) - test_all_docs_in_sync_with_command_registry (runs sync --check; fails on any drift) - test_sync_helper_idempotent_after_apply (running --apply twice is a no-op the second time) 5. CONTRIBUTING.md — added 'Syncing Command Counts' section so contributors know the procedure when adding/removing commands. Files synced by sync_command_count.py --apply (8 files, 19 substitutions): - README.md (4 locations: feature blurb, --help comment, file tree x2) - SKILL.md (front-matter description + MCP tool count) - SKILL-QUICK.md (All N Commands, Total line, MCP Server section x4) - pyproject.toml (description field) - skill.json (description field) - scripts/mcp_server.py (module docstring 'all N+ commands') - scripts/graph_model.py (docstring 'All N existing CLI commands') - tests/test_integration.py (module docstring 'all N commands') Actual counts (runtime): - CLI commands: 64 (len(COMMAND_REGISTRY)) - MCP tools: 62 total = 51 static (len(_TOOL_DEFINITIONS)) + 11 dynamic (excluded from MCP: watch, serve — long-running) Test results: - tests/test_command_count.py: 4/4 pass - tests/test_integration.py::TestModuleStructure: 4/4 pass (incl. strict assertion) - tests/test_integration.py (full file): 95/95 pass - tests/ (full suite minus test_integration.py): 843 passed, 12 skipped, 1 pre-existing failure (test_architecture::test_auto_scans_on_fresh_workspace — fixture bug unrelated to issue #38; verified failing on pristine main) Closes #38.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
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 #38
Problem
The CodeLens command count was hardcoded in 8 different places across the repo and had drifted to 5 different values (41, 45, 56, 57, 60). The actual runtime count is 64 commands. The existing regression test (
tests/test_integration.pyL281) used a loose>= 41assertion that would not catch silent command loss — every command could disappear and the test would still pass.The MCP tool count was also inconsistent: README said 55, SKILL.md said 54, SKILL-QUICK.md said 58 (with broken math: "51 static + 7 dynamic = 58" doesn't even add up).
Actual Counts Found (runtime)
len(COMMAND_REGISTRY)(auto-registered fromscripts/commands/*.pyminus__init__.py)len(COMMAND_REGISTRY) - 2(excludeswatch,serve)len(_TOOL_DEFINITIONS)inmcp_server.pytotal - static(auto-discovered fromCOMMAND_REGISTRY)Single-Source-of-Truth Mechanism
KISS design: one helper + tests that enforce it. No codegen, no build system.
1.
scripts/sync_command_count.py(new)Reads
COMMAND_REGISTRYand_TOOL_DEFINITIONSat runtime and rewrites every doc/metadata file with the correct counts. Regex-driven, declarative rule list.When adding a new rule (e.g. for a new doc file that mentions counts), add one entry to
_build_rules()in this file. The docs themselves never hardcode the number.2.
scripts/codelens.py—--command-countflag (new)Prints
len(COMMAND_REGISTRY)and exits. Used by tests/CI to introspect without parsing--help. The--helpdescription now also includes the count.3.
tests/test_integration.py— strict assertionThe loose
>= 41is now strict== EXPECTED_COMMAND_COUNT(= 64). Detailed docstring explains the update procedure when count intentionally changes. The sentinelEXPECTED_COMMAND_COUNT = 64is the ONE place where the count is intentionally hardcoded — it is the regression anchor; the sync helper intentionally does NOT touch it.4.
tests/test_command_count.py(new)Four enforcement tests:
test_command_count_helper_matches_runtime_registry— sync helper reports correct counttest_mcp_tool_count_math_is_consistent—total = cmd - {watch,serve};static + dynamic = totaltest_all_docs_in_sync_with_command_registry— runssync --check; fails on any drifttest_sync_helper_idempotent_after_apply— running--applytwice is a no-op the second time5.
CONTRIBUTING.md— updatedAdded a "Syncing Command Counts (issue #38)" section so contributors know the procedure when adding/removing commands.
Files Changed
scripts/sync_command_count.pytests/test_command_count.pyscripts/codelens.py--command-countflag + count in--helpdescriptiontests/test_integration.py==assertion (was>= 41); updated docstringCONTRIBUTING.mdREADME.md57→64(CLI),55→62(MCP),50→51(static),5→11(dynamic),56→64(file tree),57→64(commands dir)SKILL.md56→64(commands),54→62(MCP)SKILL-QUICK.md56→64(heading),60→64(Total line, also collapsed stale per-issue breakdown),58→62(MCP heading),51→51(static, unchanged),7→11(dynamic), dropped stale issue-number annotationspyproject.toml45→64(description)skill.json45→64(description)scripts/mcp_server.py45+→64(docstring)scripts/graph_model.py56→64(docstring)Total: 12 files changed, 588 insertions, 22 deletions.
How It Prevents Future Drift
len(COMMAND_REGISTRY)went from 64 → 65)64 → 63)test_all_docs_in_sync_with_command_registryfails (sync --check exits 1)The one-place-to-update is
EXPECTED_COMMAND_COUNTintests/test_integration.py; everything else is automatic.Test Results
tests/test_command_count.py(new enforcement tests)tests/test_integration.py(strict assertion + all smoke tests)(95 dots, 0 failures, 0 skips. Pytest was killed by
timeout 540before writing the final summary line, but the dot output confirms all 95 tests passed.)Full suite minus integration tests
The 1 failure is pre-existing and unrelated to this PR:
tests/test_architecture.py::TestArchitectureBasic::test_auto_scans_on_fresh_workspace— fails because
benchmarks/fixtures/clean_app/.codelens/is committed to git and gets copied by thefresh_clean_appfixture (which is supposed to yield a workspace WITHOUT a.codelens/dir). Verified failing on pristinemain(commit 241c762) before any of my changes.python3 scripts/codelens.py --help(Definition of Done #1)python3 scripts/codelens.py --command-countpython3 scripts/sync_command_count.py --checkDefinition of Done
python3 scripts/codelens.py --helpshows the same correct count (64) as all doc/metadata filesPYTHONPATH=scripts python3 -m pytest tests/test_integration.py -vPASS, with strict==assertionPYTHONPATH=scripts python3 -m pytest tests/ -v— 843 pass + 12 skip + 1 pre-existing unrelated failure (no regressions introduced)Closes #38.