Skip to content

docs(architecture): make the module-split inventory's header true - #1705

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-1698-inventory-header-tells-the-truth
Sep 6, 2026
Merged

os-steve merged 1 commit into
mainfrom
claude/issue-1698-inventory-header-tells-the-truth

Conversation

@claude

@claude claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Closes #1698

What was wrong

docs/architecture/module-split-inventory.json told its next maintainer to do something nobody could do:

"$schema_note": "Generated for docs/architecture/module-split-plan.md. Regenerate from the artifact; never hand-edit."

There is no generator in this repository. The only permitted action did not exist, and the only available action was forbidden — so doing nothing was the rational move, which is precisely the mechanism by which the file went stale. The generated stamp made it worse: a file that claims to be derived from a commit gets read as fresh.

Route taken: 1 (it is hand-maintained), and why

Route 2 (commit a generator) is not merely out of scope — it is already decided against, on the merits. Two independent pieces of evidence, both measured on this branch's origin/main:

  • Commit 36dc36c0, which added the file, states it outright: "The generator is deliberately not committed — a one-off analysis script is not a gate."
  • module-split-plan.md carries the same reasoning, grounded in AGENTS.md "Do not build platform-level tooling here".

So route 1 is not a fallback here; it is the route the repo already chose and then failed to write down in the file itself.

The measurement that shaped the fix

Auditing the whole roster rather than the one row I was told about changed the diagnosis. files[] is a 171/171 exact match for src/** (*.ts, *.md) at its stamped commit a6be39a3:

roster rows                     : 171
src .ts/.md AT THE STAMP        : 171
roster rows NOT in stamped tree : NONE
stamped files NOT in roster     : NONE

The file was never wrong. It is an accurate snapshot being read as a live index because its header invited that. Every difference against today's tree is 119 commits of movement, not error:

Direction Count What
Roster row with no file today 1 src/flows/case-csat-followup.flow.ts, deleted by #1699
File today with no roster row 34 32 locale sub-bundles under src/translations/{en,es-ES,ja-JP,zh-CN}/ from the #1311 split (the 6 barrels the roster lists still exist), plus src/flows/_guarded-iteration.ts and src/flows/case-escalation-stamp.flow.ts

That is a snapshot behaving like a snapshot. So the counts stay as measured and the drift is recorded rather than silently patched — patching totals by hand to look current would be the same lie in a new place.

The stamp

a6be39a3 is real, reachable and an ancestor of main (git merge-base --is-ancestor exit 0, with a control leg also at 0 on this shallow checkout). It is chore(deps): upgrade the ObjectStack platform to 17.2.0 (#1442), 2026-09-01, and the direct parent of the commit that added the inventory. It is not squashed away.

So the stamp is kept, not deleted — deleting it would break module-split-plan.md, which anchors its own "Measured against" line to it. It is reframed instead: the generated block becomes measured_at, with a meaning field saying in words that it is a measurement stamp, not a generation claim.

Changes

  • module-split-inventory.json — $schema_note rewritten; new $maintenance block (how, who, when, and do_not_hand_patch naming the figures that are frozen readings); new $hand_edits log; generated becomes measured_at. The one dead roster row is removed, and its removal is recorded in $hand_edits precisely enough that the roster's 171/171 identity with the stamped commit stays reconstructible.
  • module-split-plan.md — it carried the other half of the contradiction: a section titled "how to regenerate the inventory" ending "regenerate rather than patch it", sitting directly below the paragraph explaining that the generator is deliberately absent. Fixing only the JSON would have moved the deadlock next door. The "not committed" decision and its AGENTS.md grounding are kept verbatim; the impossible instruction is replaced by the possible one.
  • Changeset — empty frontmatter, the sanctioned "releases nothing" declaration documented in .github/workflows/changeset-check.yml, matching the precedent changeset for these same two files. Docs-only: nothing under src/ changes.

Acceptance

The next person to update this file reads the header and learns: it is hand-maintained, there is no generator and there will not be one, edit it by hand, log the edit, and leave the measured figures alone. Every one of those actions is possible.

Verification

pnpm verify fully green — all eight stages ran:

validate ✓ (1288ms) · typecheck ✓ · lint ✓ · i18n gate ✓ (0 issues)
hygiene ✓ (incl. "no raw control bytes in first-party files")
hygiene:tokens ✓ (authored total ~136,803, ceiling ~140,000)
build ✓ (1411ms) · Test Files 161 passed (161) · Tests 3408 passed | 1 skipped

Run under the shared verify lock: VERDICT command-exit 0 · held the lock 178s.

No new gate and no new test (AGENTS.md, Do not build platform-level tooling here). content/docs/releases/ untouched; CHANGELOG.md and existing .changeset/*.md read only.


Generated by Claude Code

`module-split-inventory.json` told its next maintainer to do something nobody
could do. Its header read "Generated for docs/architecture/module-split-plan.md.
Regenerate from the artifact; never hand-edit", and it carried a commit stamp —
but there is no generator in this repository, and the commit that added the file
(36dc36c) says one was deliberately not committed, because a one-off analysis
script that produced a design artefact is not a gate (AGENTS.md, "Do not build
platform-level tooling here"). The only permitted action did not exist and the
only available action was forbidden, so doing nothing was the rational move —
which is the mechanism by which the file went stale. The `generated` stamp made
it worse: a file that claims to be derived from a commit is read as fresh.

The header now states what is true and what can be done. The file is
hand-maintained; `$maintenance` names who updates it, when, and which figures to
leave alone; `$hand_edits` records each edit. `generated` becomes `measured_at`
— the stamp survives, reframed from a generation claim into a measurement stamp,
because module-split-plan.md anchors its own "Measured against" line to it.

module-split-plan.md carried the other half of the contradiction: a section
titled "how to regenerate the inventory" ending "regenerate rather than patch
it", directly below the paragraph explaining the generator is deliberately
absent. That decision stands and is kept; the impossible instruction is replaced
by the possible one.

One roster row is dropped — src/flows/case-csat-followup.flow.ts, deleted after
the measurement. Auditing the whole roster rather than that one row showed the
file was never wrong: files[] was a 171/171 exact match for src/** at its
stamped commit. Every other difference against today's tree is 119 commits of
movement, not error — 34 authored files added since have no row. The counts
therefore stay as measured and the drift is recorded rather than patched.

Co-authored-by: Claude
@vercel

vercel Bot commented Sep 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Sep 6, 2026 12:14pm UTC

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

module-split-inventory.json says "regenerate, never hand-edit" but no generator is in the repo — it now lists a deleted flow file

2 participants