Uh oh!
There was an error while loading. Please reload this page.
fix(docs-audit): give declinedIn the type-declaration discriminator - #11495
fix(docs-audit): give declinedIn the type-declaration discriminator#11495os-steve wants to merge 1 commit into
declinedIn the type-declaration discriminator#11495Conversation
…#10901) `declinedIn` was the last `route:`/`client:` scan in `affected-docs.mjs` still deciding "is this in code position?" for itself. #10793 taught the row recognizer and the first term of its denominator to read through both of #10500's exact discriminators; its complement did not move, so a literal-union `route:` TYPE member written in either of the two quotes the recognizer declines was billed as a value the parse FAILED to read — a named entry, a PARTIAL-read verdict and exit 1, on a ledger that is completely accurate. The region list now arrives as a required parameter from the one caller that already computes it, with no default: a call site that forgot the discriminator would silently reintroduce exactly the second opinion this closes. `offset` makes the returned index absolute, so the in-window slice's coordinate translation happens once inside the function instead of at one of the two call sites. Both call sites were reachable and both are covered: a leading entry interface arrives through the file-wide `route:` sweep, a trailing one lands inside a row window and reached the in-window `client:` sweep (measured before the fix: `clientsDeclared` 2 on a file declaring one client, exit 1). ⛔ The other discriminator is deliberately NOT applied. This still reads raw bytes, so a declined spelling quoted in a COMMENT is still billed as an unread row — that is #10794, closed `not planned`, and not this change's to reverse. The boundary is pinned in `--self-test` so the card that closes#10794 moves the pin rather than finding none. Self-test: 339 -> 366 cases. 15 of the new cases fail against the previous `declinedIn` and pass after. Live delta is zero and predicted so in advance: 0 quoted `route:`/`client:` leads inside any type declaration across all seven ledgers, and `--bridge-coverage` is byte-identical before and after (268 of 268 route / 222 of 222 client / 177 unreachable, exit 0). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. |
Superseded by #11500 — not a change of substance. The diff is byte-identical: same blob ( Why this one could not simply be edited: this PR's body was fixed in place, but commit Removing it from a pushed commit needs an amend plus a force-push, and Closing in favour of #11500 so that only one open PR claims #10901 at a time. ⛔ Do not reopen and merge this PR. Deleting this branch was authorized, but ref deletion is blocked for this seat ( Generated by Claude Code Generated by Claude Code |
Fixes#10901
declinedInwas the lastroute:/client:scan inscripts/docs-audit/affected-docs.mjsstill deciding "is this in code position?" for itself. #10793 taught the row recognizer — and the first term of its denominator — to read through both of #10500's exact discriminators. Its complement did not move, so a literal-unionroute:TYPE member written in either of the two quotes the recognizer declines was billed as a value the parse failed to read: a named entry, a PARTIAL-read verdict, and exit 1, on a ledger that is completely accurate. That is the false red the type-declaration exclusion exists to prevent.Route taken: (2), the narrow one — chosen on measurement, not on adjective
Triage ruled (2) and left (3) available "if it turns out equally cheap". It is not. I built (3) as a working probe (fold
declinedInintodeclarationsInas its missing third filter, with the one declaration list computed once per file so the in-window call cannot mis-lex a slice) and ran the differential againstorigin/mainon five shapes. (3) passes the existing 339 self-test cases, so the measurement had to be behavioural rather than a pass/fail:origin/mainroute:type member, double-quoteddeclined 1, exit 1declined 0declined 0declined 1, exit 1declined 0declined 0declined 1, exit 1declined 0declined 1, exit 1declined 2,routesDeclared 3declined 1, value unnameddeclined 2,routesDeclared 3client:uniondeclined 1, exit 1declined 0declined 0(3) changes four populations, two of them uninvited:
declinedInstill reads raw text, so aroute:quoted in a comment in ANY other spelling is billed as an unread row — a PARTIAL-read verdict on an accurate ledger #10794, closednot planned("the loud direction… polish without a puller"). Folding intodeclarationsInappliescodeOnlyas a rider and silently reverses that closure. Not this card's to reverse.declarationsInmatches[ \t]*after the colon wheredeclinedInmatches\s*, so under (3) the declaration stops being named (route:with an empty value) while still being counted. "Produces nothing a reader can act on" is the silence this file exists to break.So (2) it is: it changes exactly the population this card is about, in both quote spellings, at both call sites. D is pre-existing and byte-identical on
origin/mainand on this branch — filed unassigned as #11494.What changed
The region list arrives as a required parameter from the one caller that already computes it, with no default — a call site that forgot the discriminator would silently reintroduce exactly the second opinion this closes.
offsetmakes the returnedindexabsolute, so the in-window slice's coordinate translation happens once inside the function instead of at one of the two call sites.Both call sites were reachable and both are covered:
route:sweep;client:sweep. Measured before the fix on that shape:clientsDeclared2 on a file declaring one client, one named declined entry, exit 1.⛔ The other discriminator is deliberately not applied. This still reads raw bytes, so a declined spelling quoted in a comment is still billed as an unread row (#10794). Applying
codeOnlyhere is also not free of its own accord: it blanks string contents, and this scan's whole job is to quote the unread spelling back at the reader, so a masked window would nameroute: ""for every entry. The boundary is pinned in--self-testso whichever card eventually takes on #10794moves that pin rather than finding none.Evidence
All figures below are from this branch at
dc5d11b6.The non-vacuity proof is synthetic, and it has to be. The live delta is zero, so a green live run proves nothing about this change — stated as a prediction before running, then checked.
Fail-before / pass-after, identical case text, run against
origin/main'sdeclinedInand against this one:Both quote spellings are pinned apart, not assumed. They come out of one regex alternation and one code path and were measured behaving identically — which is the reason to pin them separately rather than to trust one for both.
Live safety check — predicted NO CHANGE, and it held.
--bridge-coveragebefore and after is byte-identical (md5 201a2b4850f62b5f9f0133547d0e907fboth runs), exit 0 both:The claimed live-zero was verified here rather than inherited, with a positive control. Across all seven ledgers: 0 quoted
route:/client:leads inside any type declaration, out of 490 quoted code leads. The same scan finds the lead in the fixture (1 per spelling), so the zero is a measurement and not a broken scan.The exclusion is still load-bearing — measured, not assumed. Ablating
typeDeclRegionsto return[](mutation proven on disk by anchored grep; restored by anEXIT INT TERMtrap;affected-docs.mjsis executed directly by node, so the edited bytes are the bytes that run):That is today's tree's form of the note the file records (
259 of 266): seven ledgers, oneroute: string;member each,268 + 7 = 275.--bridge-coverage's consumer is unaffected..github/workflows/docs-drift-check.ymlreads onlybridge.measured,bridge.reachable,bridge.clientRowsandbridge.unreachablefrom the--jsonarm. This change does not touchrows, so none of those four can move; the header's shape is unchanged.Gates
Derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(change set taken from the script's own merge-base derivation, re-derived after the final commit — the set was unchanged), and run atdc5d11b6. All green, each quoted from the gate's own verdict line:pnpm check:docs-audit-scope—✓ affected-docs self-test: 366 cases pass./✓ check-audit-scope self-test: 24 cases pass.pnpm check:entry-guard—✓ check:entry-guard: 139 scripts/ file(s) — every entry guard goes through invoked-as.mjspnpm check:parse-guard—✓ check:parse-guard: 138 scripts/ file(s) — every TypeScript parse goes through ts-parse.mjs.pnpm check:cross-package-test-inputs/node scripts/check-cross-package-test-inputs.mjs—OK: 14 package(s) read outside themselves, all declaredpnpm check:pnpm-filter-targets—✓ check:pnpm-filter-targets: 120/148 --filter occurrence(s) … resolvepnpm check:pm-governed-merges—✓ check-governed-merges --self-test: 129 assertionsnode scripts/check-ci-filter-parity.mjs—OK: all 89 declared cross-package glob(s) … are coverednode scripts/docs-audit/check-affected-docs.mjs—✓ affected-docs self-test: 366 cases pass.pnpm check:nul-bytes—check-nul-bytes: OK (scanned 6448 text file(s) … no raw ASCII control bytes).No narrowing to declare:
pnpm lint(eslint . --no-inline-config, repo-wide) was run in full under the shared verify lock — exit 0 in 68s.No changeset: this touches one CI/tooling script under
scripts/and publishes nothing, so the PR carriesskip-changeset.Generated by Claude Code
Generated by Claude Code