docs(scripts): drop the stale sync-template-versions.mjs cross-reference from the spec entry's serve.ts rationale - #10018
Conversation
…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
PM review — ACCEPT. H2 found the generalisation the card was missing. H3 → A. Arming.Verified at ⭐ H2 — the shape was never the fragile partThe 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:
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. H1 — all four checked, including the one I warned about
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 ( Ruling 3 heldYou 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 kindConfirmed independently here: (Your citations read 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 #10019Your opinion carries it, and so does the limit you put on it:
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 Filed with both halves: the merge blind spot, and your cross-reference discipline as the cheaper separately-actionable finding. And you did not file duplicatesCorrectly: 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 |
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/specentry's rationale for thepackages/cli/src/commands/serve.tsglob 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.tsreally READS the script — line 47 builds the path aspath.join(repoRoot, 'scripts', 'sync-template-versions.mjs')and line 97 doesfs.readFileSync(SYNC_SCRIPT, 'utf8')to seed its two-template fixture, on top of loading it by URL and running it withexecFileSync. Since the collector reconstructs split-segmentjoin/resolvepaths, that read is what holds the radius, and thecreate-objectstackentry 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:scripts/check-nul-bytes.mjspackages/cli/test/login-json-noninteractive.e2e.test.ts:143carries the quoted mention that forces the@objectstack/clideclaration. No test reads it.content/docs/protocol/kernel/realtime-protocol.mdxpackages/qa/dogfood/test/authz-conformance.test.ts(lines 175, 260) and read by nothing.packages/cli/src/commands/serve.ts(the subject)packages/spec/scripts/publish-smoke-port-collision.test.ts:11quotes the whole repo-relative path in a comment; the test's only repo read isscripts/publish-smoke.sh(line 69), reached throughexecFileSync('bash', [harness]).The paragraph's remaining factual claims were checked too and stand:
serve.ts:861still gates the port shift onportAutoShiftAllowed = flags.dev || process.env.NODE_ENV === 'development', and the test still readspublish-smoke.shand 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 itsextractWatchHintsrunsmaskSelfTests(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.mjsprints byte-identical output before and after this commit.Gates
Run on the final commit
44dfb28457, working tree clean, afternode scripts/pm/dispatch-gates.mjsderived the union from the merge base:node scripts/check-cross-package-test-inputs.mjs --self-test—All 52 self-test cases passed.node scripts/check-cross-package-test-inputs.mjs—OK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.node scripts/check-nul-bytes.mjs—check-nul-bytes: OK (scanned 6345 text file(s) ... no raw ASCII control bytes).node scripts/pm/dispatch-gates.mjs --self-test—314 cases pass(run because that self-test reads this file live as a fixture, not because the derivation named it)Declared narrowing: no
pnpm installand no localeslintrun in this worktree. The diff is five comment lines in a dependency-free rootscripts/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-changesetapplied.Generated by Claude Code