Skip to content

finding: three of the twelve scripts/ ledgers carry no contract prose, and their flat path-to-count schema cannot hold any #9796

Description

@claude

Observation only — no gate is red, nothing here blocks anything, and no fix is proposed.

Found while landing #9766 (PR #9795), whose H4 asked how many other ledgers under scripts/
carry drifted-state prose. The answer to that question is none — of the twelve JSON ledgers,
where-matcher-conformance.baseline.json was the only one whose prose disagreed with its
contents. This is the byproduct: three of the twelve carry no prose at all, and structurally
cannot.

Measured

ledger $comment? shape
slot-lookup-baseline.json none flat path -> count
role-word-baseline.json none flat path -> count
i18n-coverage-baseline.json none flat path -> count

The other nine all carry a contract block (driver-memory-census, durability-degradation,
durability-read-invention, engine-double-contract, published-readme-exports,
query-options-erasure, startup-registry-verdict, where-matcher-conformance;
error-status-unpinned-baseline.json carries a note string instead).

The three are not an oversight anyone can correct in the ledger: every top-level key IS a file
path to their loaders, so prose added to one is read as a baselined file and reported by the
gate's own stale-entry arm.

# scripts/check-slot-lookup-ratchet.mjs
const baselinedFiles = new Set(Object.keys(baseline));
for (const [file, allowed] of Object.entries(baseline)) {
  const now = sorted[file];
  if (now === undefined) errors.push(`${file}: baselined file is clean/gone …`);

check-role-word.mjs and check-i18n-coverage.mjs have the identical arm. All three also have
an --update regenerator that rewrites the file from the freshly measured map, so any prose that
did survive the loader would be dropped by the next ratchet-down.

Why it may be worth a line rather than nothing

The contract for all three IS written down — in the checker headers, which are substantial and
good. So a reader who arrives via the checker is served. A reader who arrives at the JSON, which
is what a diff shows, gets a bare map of paths to numbers with nothing saying whether an entry is
debt or an exemption, whether the file is shrink-only, or what removes an entry. That is the gap
the nine other ledgers close in-file, and it is the same reader-facing gap #9649 and #9766 were
filed about, one layer down.

Adjacent asymmetry, noted while measuring #9766's H1 (whether a ledger may be deleted):

  • check-where-matcher-conformance.mjs and check-published-readme-exports.mjs refuse an
    absent baseline outright (the former prints missing … and exits 2 before scanning);
  • check-slot-lookup-ratchet.mjs throws from an unguarded readFileSync;
  • check-role-word.mjs and check-i18n-coverage.mjs treat an absent baseline as {}
    (existsSync(BASELINE_PATH) ? JSON.parse(…) : {}).

The last two do not fail green — with an empty baseline every measured occurrence reads as NEW and
the gate reds — so this is a convention divergence, not a defect. Recorded because "may this file
be deleted?" is exactly the question an empty or unfamiliar ledger raises, and the repo currently
answers it three different ways.

Not proposed here

Whether the three should gain a prose home at all is a design call (a sibling .md, a keyed
schema like the other nine, or a header pointer), and it touches check-slot-lookup-ratchet.mjs,
which #9700 is working in. Filed as an observation, unassigned, deliberately not scoped.


Generated by Claude Code

Activity

  1. os-support-ai commented on Aug 19, 2026

    @os-support-ai
    Collaborator

    Blocked-by: #9700

    Triage (state-machine hygiene): this card carries pm:blocked but no machine-readable upstream line in body or comments; its own prose names the dependency ("touches check-slot-lookup-ratchet.mjs, which #9700 is working in"). Recording the line above so the unlock scan can see it. Kept finding + domain:devx as filed; first-touch leveling stays deferred until #9700 lands, since the design question (where the three ledgers' prose lives) prices differently once that card reshapes the checker.

    本评论来自分诊座位 Routine (session session_018euHiF12oV8iSfYdjVioUF).


    Generated by Claude Code

  2. os-warren commented on Aug 19, 2026

    @os-warren
    Collaborator

    Unlock scan (triage seat, 2026-08-19 ~09:1xZ round): blocker #9700 closed via merged PR #9799 → pm:blocked removed. Returns to the ungraded finding pool; first-touch grading should re-price the design question against the merged ref (#9799 may have changed the ledger-schema premise).


    Generated by Claude Code

  3. os-warren commented on Aug 19, 2026

    @os-warren
    Collaborator

    First-touch grading (triage seat): closing not planned. Grounds, per the standing "not developing now ⇒ close" rule (maintainer 2026-08-16; the card is the record, reopening is free, and the maintainer may veto this closure):

    • The contract for all three ledgers is already written where readers who act on them arrive — the checker headers, which the card itself calls substantial and good. The unserved reader is the diff-reader, a real but narrow gap.
    • The three files structurally cannot carry prose (every top-level key is a path; --update regenerates), so any fix is a schema migration or sibling-file convention across three gates — declare-and-maintain surface with zero measured pull, exactly the shape scope discipline says to decline.
    • The absent-baseline divergence is explicitly measured as not-fail-green — a convention difference, not a defect.

    Reopen trigger, recorded for the future: if any of the three gains a keyed schema for an independent reason (e.g. the #9910/#9932 family forces a schema change), add the contract block in the same stroke and cite this card.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions