Skip to content

Spec 014's checks: the holes the review of 20 Oct found - #575

Merged
adamjohnwright merged 5 commits into
mainfrom
fix/014-checks
Oct 20, 2026
Merged

adamjohnwright merged 5 commits into
mainfrom
fix/014-checks

Conversation

@adamjohnwright

Copy link
Copy Markdown
Contributor

Spec 014 (specs/014-content-service-modules). From the review of everything merged since #485, and a review of this PR. These are the checks every move in the split relies on. Each hole below was shown passing before and failing now.

boundaries.spec.ts: the contract's table, row by row

  • Each shared module imports only what its row names, plus leaves. For example, answers may not import body.
  • The server never imports a family. The registry imports only families.
  • Every other module is a leaf and imports only leaves, so one reaching the registry, a family or service.ts fails, a new module included. Nothing in the service imports the two tools that read the list.

endpoint.ts. The Endpoint, Handler, Answer and Request types move from registry.ts to a types-only leaf. Families declare Endpoint[] and cached returns a Handler, and neither may import the registry, since that would be a cycle. T026 creates the registry proper.

check-move: every name used is bound as before

  • This applies to moved code and to code that stays.
  • A receiving module's own javaTrim is flagged. So is a helper left behind that falls through to a global.
  • So is a caller left in service.ts that is pointed at another module's javaTrim in the same change. Shown with 20 callers flagged; the same move done right flags none.

check-baseline-totals: no rise in a module the base counts

  • No module the base branch counts may rise, other than the split's own modules, which later moves add to.
  • So a rise can't hide behind a fall at an unchanged total.

Unlocked falls fail. check:types and check:lint now fail on a per-module fall that hasn't been locked in with --update, so room left by typing can't be spent later unseen. It found 159 loose values #570 typed away without the baseline following; they are locked in here (2928 → 2769).

Smaller fixes:

  • registry.spec.ts: the lookup backstop reads the syntax tree of every module. It sees a lookup however it is written: wrapped, destructured, a family's own list, registry.endpoints, a constant or template path, endpointFor('/…'), or a for-of loop.
  • invalid-inputs.spec.ts: a URL counts for the endpoint routing gives it, not for any template it happens to fit.
  • snapshot-files.spec.ts: the domain snapshot's flag must be exactly 'D'.
  • Docs: contracts/boundaries.md, contracts/checks.md, plan, research and tasks say all of this.

Checks

  • Tools and deploy unit tests: 2,099 passed.
  • check-move on this branch: 4 declarations moved (the types), 0 changed, 0 missing, 0 added, 0 rebound.
  • Lint, implicit any and dead code unchanged; loose 2928 → 2769.

🤖 Generated with Claude Code

adamjohnwright and others added 5 commits October 20, 2026 19:56
- boundaries.spec: the contract's table, row by row. Each shared module
  imports only what its row names (answers may not import body); the
  server never a family; the registry only the families; every other
  module is a leaf and imports only leaves, so one reaching the registry,
  a family or the service fails, a new module included; nothing in the
  service imports the tools that read the list (diff, invalid-inputs).
  The old rules passed all three of the review's cases (shown).
- check-baseline-totals: a module the base already counts may not rise,
  whatever falls elsewhere -- moves create their modules -- so a rise
  cannot hide behind a fall at an unchanged total (shown on a scratch
  baseline).
- check-types and check-lint fail on a per-module fall not locked in, so
  room left by typing cannot be spent later unseen.
- check-move: every name a moved declaration uses must be bound where it
  now is as it was where it came from -- a receiving module's own
  declaration of the name, or a global where the original had a
  declaration or import, is `rebound` (shown on scratch moves; names the
  moved code declares itself are not compared).
- registry.spec: the lookup backstop reads the AST of every module, and
  sees a lookup however written (wrapped, destructured, findLast,
  endpointFor('/...'), a for-of).
- invalid-inputs.spec: a URL counts for the endpoint that answers it (the
  first match, as routing takes it), not any template it fits; a corpus
  skipping /search/diagram/{diagram} now fails (it passed before).
- snapshot-files.spec: the domain snapshot's flag is the one value 'D'.
- contracts/checks.md says what the checks now report.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The Endpoint, Handler, Answer and Request types move from registry.ts
  to endpoint.ts, a types-only leaf: families declare Endpoint[] and
  answers' cached returns a Handler, and neither may import the registry
  (a cycle). The boundary test rejected both; it now allows them, shown.
  T026 creates the registry proper. The contract, plan, research and
  tasks say so.
- check-move compares the bindings of code that stays as well as code
  that moves: a caller left in service.ts pointed at another module's
  javaTrim in the same change is `rebound` (shown: 20 callers flagged;
  the same move done right, none).
- check-baseline-totals: the split's own modules (shared, families,
  registry, server) may rise -- a later move may add a forgotten helper
  to one -- held by the total; every other existing module may not.
- registry.spec's lookup backstop also sees a family's own list
  (dataQueryEndpoints), registry.endpoints, a constant path, a template
  with substitutions, and a partial path.
- contracts/boundaries.md: leaves, and that shared modules and families
  may import them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The per-module loose check now fails on a fall not locked in (the commit
before); service.ts had fallen from 1677 to 1529, and three modules of the
tools with it, without the baseline following.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adamjohnwright
adamjohnwright merged commit 7b1aa47 into main Oct 20, 2026
7 checks passed
@adamjohnwright
adamjohnwright deleted the fix/014-checks branch October 20, 2026 20:46
adamjohnwright added a commit that referenced this pull request Oct 20, 2026
After #575 the loose check held service.ts to its locked-in count, and
this branch's outOfBounds calls had raised it (1529 -> 1539): javaSplit
returned an untyped value. Typed, with fourParts (the first four parts,
or Java's index failure in the order given) at the four sites, the count
falls instead: loose 2769 -> 2709, implicit any 794 -> 789, both locked
in. Answers on beta unchanged (flag and Solr capture sets identical).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant