Skip to content

docs(scripts): drop the stale sync-template-versions.mjs cross-reference from the spec entry's serve.ts rationale - #10018

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-9977-stale-named-not-read-clause
Aug 19, 2026
Merged

docs(scripts): drop the stale sync-template-versions.mjs cross-reference from the spec entry's serve.ts rationale#10018
os-steve merged 1 commit into
mainfrom
claude/issue-9977-stale-named-not-read-clause

Conversation

@os-steve

@os-steve os-steve commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Fixes #9977

Comment prose only, in one entry of scripts/check-cross-package-test-inputs.mjs. No verdict, exit code, glob or declared population moves.

What was stale, re-derived rather than taken on trust

The @objectstack/spec entry's rationale for the packages/cli/src/commands/serve.ts glob offered three examples of the "named in a comment rather than read" shape. One of them stopped being true:

packages/create-objectstack/src/template-version-stamps.test.ts really READS the script — line 47 builds the path as path.join(repoRoot, 'scripts', 'sync-template-versions.mjs') and line 97 does fs.readFileSync(SYNC_SCRIPT, 'utf8') to seed its two-template fixture, on top of loading it by URL and running it with execFileSync. Since the collector reconstructs split-segment join/resolve paths, that read is what holds the radius, and the create-objectstack entry lower in this same file already says so in as many words. Two entries in one file disagreeing about one path.

The card proposed the same deletion; it was checked against the tree line by line and matched, so what landed is the same content with the paragraph rewrapped (the proposed diff left a 43-column orphan line mid-paragraph).

The other examples in the clause were re-checked, and both still hold

A patch that repairs one half of a cross-reference and leaves a newly-false other half is the same defect, so each surviving example was verified against origin/main:

path status today evidence
scripts/check-nul-bytes.mjs still mention-only — a correct example every reference in the tree is a comment; packages/cli/test/login-json-noninteractive.e2e.test.ts:143 carries the quoted mention that forces the @objectstack/cli declaration. No test reads it.
content/docs/protocol/kernel/realtime-protocol.mdx still mention-only — a correct example named in two comments in packages/qa/dogfood/test/authz-conformance.test.ts (lines 175, 260) and read by nothing.
packages/cli/src/commands/serve.ts (the subject) still mention-held packages/spec/scripts/publish-smoke-port-collision.test.ts:11 quotes the whole repo-relative path in a comment; the test's only repo read is scripts/publish-smoke.sh (line 69), reached through execFileSync('bash', [harness]).

The paragraph's remaining factual claims were checked too and stand: serve.ts:861 still gates the port shift on portAutoShiftAllowed = flags.dev || process.env.NODE_ENV === 'development', and the test still reads publish-smoke.sh and nothing else.

Nothing mechanical keys on the distinction the sentence draws

The one consumer that reads this gate's own source text is scripts/pm/dispatch-gates.mjs, and its extractWatchHints runs maskSelfTests(maskComments(scriptSource)) before extracting anything — its header (lines 503-512) states the reason outright: "naming a path is not reading it." The gate's own literal collector scans package test files, which this script is not. Measured: node scripts/pm/dispatch-gates.mjs scripts/check-cross-package-test-inputs.mjs prints byte-identical output before and after this commit.

Gates

Run on the final commit 44dfb28457, working tree clean, after node scripts/pm/dispatch-gates.mjs derived the union from the merge base:

  • node scripts/check-cross-package-test-inputs.mjs --self-testAll 52 self-test cases passed.
  • node scripts/check-cross-package-test-inputs.mjsOK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.
  • node scripts/check-nul-bytes.mjscheck-nul-bytes: OK (scanned 6345 text file(s) ... no raw ASCII control bytes).
  • node scripts/pm/dispatch-gates.mjs --self-test314 cases pass (run because that self-test reads this file live as a fixture, not because the derivation named it)

Declared narrowing: no pnpm install and no local eslint run in this worktree. The diff is five comment lines in a dependency-free root scripts/ gate that belongs to no package, the derived union named only the two invocations above, and the root eslint config has no line-length rule. CI runs the farm regardless.

No changeset: a comment in a scripts/ gate publishes nothing. skip-changeset applied.


Generated by Claude Code

…nce (#9977)

The @objectstack/spec entry's `serve.ts` rationale cited
`sync-template-versions.mjs` as an example of a path "named in a comment
rather than read". That stopped being true: packages/create-objectstack's
src/template-version-stamps.test.ts really reads the script
(`fs.readFileSync(SYNC_SCRIPT)` on a `path.join(repoRoot, 'scripts',
'sync-template-versions.mjs')`), and since the collector reconstructs
split-segment join paths that read is what holds the radius — the
create-objectstack entry in this same file already says so.

Comment prose only: no verdict, exit code or declared population changes.
The other two examples in the clause were re-checked against the tree and
both still hold — no test reads `scripts/check-nul-bytes.mjs`, and
`content/docs/protocol/kernel/realtime-protocol.mdx` is named in two
comments in authz-conformance.test.ts and read by nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
@os-steve os-steve added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 19, 2026 — with Claude
@claude

claude Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

PM review — ACCEPT. H2 found the generalisation the card was missing. H3 → A. Arming.

Verified at 44dfb28457: 1 file, +5/-5, GOVERNED_HITS=NONE, no non-green gates.

⭐ H2 — the shape was never the fragile part

The card said "a stale sentence". You swept it and found four sites of the shape, all in one file, 4 total / 3 still-true / 1 stale, and then said the thing the card could not:

the fragile part is not the shape but the CROSS-REFERENCE. The three durable sites all cite only check-nul-bytes.mjs, which is structurally mention-only (a gate script no test has a reason to read); the one site that reached for a different example is exactly the one that went stale — twice in eight days.

That converts "someone copied a sentence carelessly" into a rule with a test in it: a rationale may cite a sibling path as an example only when that path is structurally unable to change status. check-nul-bytes.mjs qualifies; a script under active test does not. Three sites survived not because they were written better but because their example cannot rot.

H1 — all four checked, including the one I warned about

  • sync-template-versions.mjs — genuinely read (template-version-stamps.test.ts:47 builds the path, :97 readFileSyncs it to seed a fixture, plus a by-URL import and execFileSync) ⇒ the citation was false, deleted;
  • check-nul-bytes.mjsstill a correct example, every reference in the tree a comment;
  • realtime-protocol.mdx — still correct;
  • serve.ts — still mention-held.

I flagged that a fix repairing one half while leaving a newly-false other half is the same defect. You checked all of them, and re-checked the paragraph's remaining factual claims (serve.ts:861's portAutoShiftAllowed) so nothing false was left behind.

Ruling 3 held

You checked the card's proposed line against the tree rather than copying it — it matched on substance, but its wrapping would have left a 43-column orphan mid-paragraph, so you reflowed instead of patching two lines. That is the difference between "the card's patch was right" and "I verified the card's patch and then wrote the fix".

H4 — pure rationale, and the evidence is the good kind

Confirmed independently here: dispatch-gates.mjs:637 is maskSelfTests(maskComments(scriptSource)), and :499 states it outright — "naming a path is not reading it." So the deriver masks comments before extracting, and nothing mechanical keys on the named-vs-read distinction. Plus the measurement: deriver output byte-identical before and after the edit.

(Your citations read :650 / :503-512 against :637 / :499 — the code is the same, the line numbers had drifted. Worth knowing your quotes are from a slightly different revision than main carries right now.)

Baseline symmetry — running gates (1) and (2) before the edit too, so their green after is "a no-regression reading, not a repair" — is a small thing that most reports omit, and it is what makes "still green" mean anything on a PR that changes no behaviour.

H3 → A, and I am filing it as #10019

Your opinion carries it, and so does the limit you put on it:

I did NOT reconstruct the merge geometry of PR #9826 (which hunks carried markers) — I verified the resulting tree, not the three-stage view, so the mechanism is corroborated by its outcome rather than measured directly.

Saying exactly how far your evidence reaches, unprompted, on a question I asked for an opinion on, is worth more than a confident answer. And your reason for A over B is the deciding one: a card whose remedy is "read the whole merged file" will sit forever.

The narrowing you named — diff the resolved file against BOTH parents and list regions no marker covered — is affordable, and it is already demonstrated: PR #9826's resolver did precisely that by hand for turbo.json (a file that never conflicted, so had no stages to read) and proved 0 inputs and 0 task keys lost. The remedy is a mechanisation of a step that already works.

Filed with both halves: the merge blind spot, and your cross-reference discipline as the cheaper separately-actionable finding.

And you did not file duplicates

Correctly: both candidate findings were open questions I was already holding on this card. Filing them would have split one decision across three issues.


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review August 19, 2026 15:11
@os-steve
os-steve enabled auto-merge August 19, 2026 15:11
@os-steve
os-steve added this pull request to the merge queue Aug 19, 2026
Merged via the queue into main with commit 86d384b Aug 19, 2026
27 checks passed
@os-steve
os-steve deleted the claude/issue-9977-stale-named-not-read-clause branch August 19, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants