Uh oh!
There was an error while loading. Please reload this page.
feat(spec): liveness citations can anchor the consuming symbol — path#symbol survives in-range line drift - #13004
Merged
Conversation
…#symbol survives in-range line drift A line citation rots IN RANGE: the consumer moves within its cited file, the file exists, the line is inside it, the file names the key — all three citation checks stay green and the pointer is wrong. Measured on the two action.json entries PR #12214 repointed 2026-08-25: both drifted within a day. A path#symbol anchor moves WITH the consumer; when the consumer is renamed or deleted the gate goes red — a direction a stale line cannot produce. Census before switch-on: zero pre-existing path#symbol tokens, so the check starts green (the orphan-proof zero-census precedent), and the line-window detector alternative was censused at 117-173/298 misses — unshippable noise (the 48-of-227 lesson). Both rotted entries re-anchored. Part of #12516 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LpRNHxWZgSUgVnFT9mQQo4
…veness-in-range-drift
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 126 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-trump
marked this pull request as ready for review
August 28, 2026 14:32
os-trump
enabled auto-merge
August 28, 2026 14:33
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#12516
What this delivers
A liveness citation could rot in range: the cited file exists, the cited line is inside it, the file names the key — and the consumer has moved to a different line of the same file, so
check:livenessstays green while the pointer is wrong. Measured on the card: bothaction.jsonentries repointed with fresh line numbers by PR #12214 on 2026-08-25 had drifted this way by 2026-08-26.This PR adds a symbol anchor to the citation grammar —
packages/path/file.ts#dispatchFlowAction, the proof-ref#convention applied toevidence/producercitations — and re-anchors the two measured-rotted entries. A symbol moves with the consumer, so the anchor survives exactly the movement that rots a line; when the consumer is renamed or deleted the symbol is gone and the gate goes red — a direction a stale line can never produce. A line may still ride along (file.ts#symbol:150, either order): it stays a bounded human convenience; the symbol is the load-bearing half. The ledger README now documents the anchored form as the preferred citation (the option-D honest consequence, adopted alongside the mechanism: line numbers stop being presented as load-bearing).Route decision (per the PM route ruling — decided by measurement)
$-aware) match on content the gate already loads — no TypeScript program, no new dependency, no measurable CI cost (check:livenessheld the shared verify lock 2s on this tree).evidence/producerstring, so PM mechanism-assumption 3's migration question dissolves: adoption is per-citation, and only the two repaired entries adopt here.path#symbol-shaped tokens across every ledgerevidence/producerstring and the empty-state registry — the check starts at a zero population and is red from day one (the orphan-proof zero-census precedent). A malformed anchor (not one identifier) also fails, theverifiedAtbad-date asymmetry one field over: parsed-to-nothing must be loud, not a silently dropped standard.verifiedAt-vs-mtime floor was considered and declined: file mtime is checkout-time in CI (git does not preserve mtimes), and a git-log-based freshness signal needs per-file subprocess calls plus is noisy on hot files by the card's own admission. The anchor mechanism supersedes it for adopters.Regression pair (hard requirement 2) — predicted directions, on-disk proof
The measured rot shape is "the consumer moved while file+line+key checks all stay green". Replayed as a mutate/restore ablation on this tree (no build leg applies: the gate runs from
.mtssource via tsx and reads the cited file as text — nothing resolves throughdist/; the mutation was proven on disk by anchored grep counts instead):perl -pirename ofdispatchFlowActiontodispatchFlowActionMovedinpackages/runtime/src/action-execution.ts; disk proof: old spelling 4 to 0, new spelling 0 to 4.symbol anchors: 5 pointer(s) ... 4 naming a symbol the cited file contains, 1 UNRESOLVED, heading1 anchored citation(s) name a symbol the cited file does not containnamingaction/target.line citations: 302 pointer(s) ... 302 inside the cited file— the line citation is blind to the very movement the anchor catches.git checkout HEAD -- FILE(absolute path, trap-guarded); proof:git diff HEADempty and worktree blob hash20ce1f47b56...byte-identical to the HEAD blob.check-liveness.test.ts,--ledger-rootcopies, real gate spawned) pins the same pair permanently: symbol-gone RED, malformed RED, before-state GREEN (the honest residual, pinned so the red case stays attributable), and the two-number summary line with a non-vacuity floor.Honest residual, stated: a bare
path:NNNcitation that drifts in range remains green (text cannot tell "the consumer" from "plausible code at the address"), and a symbol that survives while its body stops reading the key is out of reach at text level — the file-level key-mention check remains that case's backstop.The two entries now point at the truth (hard requirement 1)
action.target→action-execution.ts#dispatchFlowAction(containsautomation.execute(action.target, ...)and theflowIsUnknownrejection by the same value) +#headlessActionTypeError(readsaction.targetfor the client-dispatched refusal text). Re-verified on this ref;verifiedAt: 2026-08-28.action.requiredPermissions→action-execution.ts#actionPermissionError(the single-sourced read ofactionDef.requiredPermissions) +domains/actions.ts#handleActionsRequest(the ADR-0066 D4 call site, 403) +#resolveRouteActionDeclaration. The card's own measured lines (actions.ts:393-400/473/526) are comment mentions; the code read isactionPermissionError— the anchor cites the code.verifiedAt: 2026-08-28.Path-leg declaration and changeset
packages/spec/scripts/liveness/**(gate + tests) andpackages/spec/liveness/**(two ledger entries + README prose). Nopackages/spec/src/**file is in the diff — the clause-② path leg does not fire.liveness/is in the spec packagefilesarray, but ledger JSON is governance data, not behavior.) Per the dispatch, theskip-changesetdecision is recorded here for the PM; the label has been applied per the repo's standing labeling rule.Gates (all quoted from each gate's own verdict line, exit codes captured before any pipe)
At
93ce7444c(pre-merge) and re-run at385b24ec7(after merging same-day main, which touched siblingkey-mention.test.ts):check:livenessgreen —symbol anchors: 5 pointer(s) written path#symbol, 5 naming a symbol the cited file contains; RED on the regression legs above.vitest runonevidence.test.ts,check-liveness.test.ts,key-mention.test.ts,empty-state.test.ts—Test Files 4 passed, Tests 124 passed(verbose run confirms all 17 new [finding] A liveness citation can rot IN RANGE:action.targetandaction.requiredPermissionspoint at the wrong lines one day after being repointed, and every check stays green #12516 cases executed).check:scripts-typecheckgreen (tsc--listFilesconfirms both edited.mtsand both edited.test.tsfiles are in that program —tsconfig.test.jsonstops atsrc/**, so scripts-typecheck is the program that measures these files, verified not assumed).dispatch-gates.mjs, no args, stderr line confirms derivation from this repo at this commit): cross-package-test-inputs, merge-driver, objectql-double-limit, page-declaration-shape, pm-governed-merges, published-files, slot-lookup, test-source-alias, type-source-resolution, ci-filter-parity, comment-mask-adoption, query-options-erasure, engine-double-contract, where-matcher, bare-root-worklist self-test, pm-dispatch-gates, type-check-coverage, empty-state, strictness-ledger, variant-docs, affected-docs, nul-bytes — all green at385b24ec7.check:type-check-debt— declared narrowing (not run locally; CI runs it in full): the re-measure re-runs tsc per DEBT/TEST_DEBT ledger entry; the only changed TS files live inpackages/spec/scripts/liveness/whose governing program (tsconfig.scripts.json, includescripts/**/*) compiles green, and spec's TEST_DEBT program (tsconfig.test.json, includesrc/**/*) contains 0 of the changed files by--listFilescount — no debt entry's measured population contains any changed file, so the ratchet cannot move from this diff.docs-audit/check-drift-comment.mjsis CI-owned (needs PR context).Scope and follow-up
Per the dispatch: the mechanism + the two entries only — no sweep of other citations. #13003 is the follow-up migration card (anchor adoption for the remaining ~298 line-cited pairs, carrying the census numbers above as its evidence); #13003 remains open and is not addressed here.
Generated by Claude Code