docs(service-settings): re-anchor the dead tracker citations to the commits that decided them - #20836
Conversation
…ommits that decided them Eleven comment and docblock sites under packages/services/service-settings/src cited a tracker number that answers 404. Each now cites the commit in this repository that decided what the line describes (ruling C's commit rung; no ADR records any of the four): - #13279 -> 6a180e4, the permission-store read that fails loud, and the settings plugin's re-raise of the branded outage (4 lines); - #10159 -> 1ec36b7, the refusal of a settings write issued before the engine is bound, which left reads open on purpose (3 lines); - #17062 -> 50b6f17, the package-local route-ledger conformance guard (2 lines); - #11318 -> 99ccbb9, the Settings -> AI live-call hint that carries the cloud-only boundary and deliberately leaves the embedder hint alone (2 lines). Two headers keep the antecedent the docblocks below them speak of: the conformance test's opens "the issue behind commit 50b6f17" for its later "per the issue", and the AI hint test's opens "The card behind commit 99ccbb9:" for its later "this card". Every file keeps its line count; no code token moves; no citation number is added. Two test strings naming a dead number (a describe title and an assertion message) are left. Claude-Session: https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H Co-authored-by: Claude <noreply@anthropic.com>
…ce comments The rewritten docblock on SettingsService's pre-bind read reporter ships in dist (both JS entries and both declaration files), so the package's published bytes change and take a patch changeset. Comments only. Claude-Session: https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 8 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 65554518b7d6fabd1fe3b3ae0522509c21e910e7 && git checkout 65554518b7d6fabd1fe3b3ae0522509c21e910e7
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 15b586dcffa88471afeaba4dbf560223692ad944 ac05607d619c76e107db022098f8abee535615d3 && git checkout -B drift-repro 15b586dcffa88471afeaba4dbf560223692ad944 && git merge --no-ff ac05607d619c76e107db022098f8abee535615d3
node scripts/docs-audit/affected-docs.mjs --json 15b586dcffa88471afeaba4dbf560223692ad944
|
Contract reviewServed-tier: ① Derived judgmentsRead against
② Semver level
③ Boundary flagsThe dev report (
Nothing is escalated. One reading for the seat, not a flag on this PR: Implemented-by: VERDICT: PASS |
Part of #20596
Clause-②: no
What changed
This is the fifteenth stage of the
domain:serviceslane of the dead-citation sweep. It coverspackages/services/service-settings/src/**and nothing else. By the seat's claim (5908460751), it is the largest package left in the lane. Later stages cover the other packages, so this PR saysPart ofand the card stays open.Every comment or docblock site in scope that cited a tracker number answering 404 has been rewritten in ruling C+D's form C (comment 5749154545 on #19123), by the method of stages 1 to 14 (the latest is PR #20816, landed as
73155fedc). That is 11 sites on 11 lines in 9 files, covering 4 numbers:#11318, stands only in test files here; it was read on its own and answers 404.Each rewritten line now cites the commit in this repository that decided what the line describes, and says in its own words what was decided: 4 distinct commit shas. No ADR records any of the four decisions (see the per-number table), so ruling C's commit rung applies. No number was dropped.
Only comments changed. Every touched source file keeps its line count (11 lines out, 11 in, over 9 files), so no line citation into these files moves. All 11 changed lines carried a dead citation. No code token moves (see the guard below).
No citation number is added. The only tracker number on an added line is the live
#10251, once, insettings-prebind-read-warning.test.ts:17. It already stood on that line, and it now sits beside the sha as the convenience link ruling C allows: 「(commit 1ec36b7, PR #10251)」.1ec36b730is that pull request's squash commit.2 dead sites are left on purpose: a test title and a test assertion message (see the list below).
One more file: a
patchchangeset for@objectstack/service-settings, because the rewritten prose ships (see Changeset below).Census:
service-settings, before and afterInstrument (A1). The gate's own
node scripts/check-issue-citations.mjs --census --json, read-only and unchanged. The count below is itsallocated-but-absentfindings underpackages/services/service-settings/. Each run counts as a reading only because its board frontier equals the newest issue or pull-request number, read by a separate request just before and just after the run.allocated-but-absent73155fedc, run 2026-09-30T09:39:38Z to 09:43:17Zac05607d6, run 10:02:17Z to 10:06:00ZThe whole-repo drop is 4, exactly this diff's census sites. The
resolvestally is 33,134 in both runs, andresolves-as-pull-request(1,985) andcross-repo-unjudged(1,018) did not move either. Neither run was truncated or discarded: both enumerations read 187 pages at the newest frontier. The seat's census counted 4 here at6bff748b, and the base agrees:6bff748bis an ancestor of the base, and no commit between them touches this package'ssrc.Supplementary instrument, the whole scope. The census does not read test files or strings, and this stage's scope includes test comments. So a second reading runs the gate's own exported
extractCitations(whole-file and comment-prose projections) andnamesThisRepositoryover every.tsfile underservice-settings/src(64 files). It takes its verdicts from the before census's own board reading rather than from a second enumeration: a number is dead when that census reported itallocated-but-absent, and alive when the gate's own census-scope extraction judged it and the census did not report it. 10 numbers are covered by neither, because they stand only in test files, or as the second number of an#A/#Bpair. Each was read on its own through the read-only tools. 1 answers 404 (#11318, on the issue and the pull-request endpoint alike); 6 answer as issues; 3 answer as pull requests (#7554,#10251,#5133). The probe's control: the known issue#11352answers 404 on the pull-request endpoint.73155fedcac05607d6Its src-comment column equals the census's 4, which is the control on the second instrument. The 519 live citations and 2 cross-repo citations are the same in both readings, and the drop of 11 citations is exactly the rewritten sites. A third, raw reading (every
#followed by 2 to 6 digits, whatever surrounds it) finds 547 occurrences before and 536 after, the same drop of 11. The 13 tokens beyond the gate's grammar are the same before and after, and none is dead (see Acceptance notes).Per-number table
Sites and files count every dead occurrence in scope at the base (comments and strings, tests included).
rewritten / leftcounts the sites rewritten and the sites left. Each anchor was read in its message and diff, not only its subject.#132796a180e42d(PR #13475):resolveAuthzContextraisesAuthzStoreUnavailableError(SERVICE_UNAVAILABLE, 503) when a permission-store read throws, instead of answering an outage as a caller with zero capabilities, and each production transport's fail-closedcatchre-raises that brand. The settings plugin'sverifiedContextFromRequestis one of them. Its message names#132794 times and its diff 54 times;git blameputssettings-service-plugin.ts:307in it, and the other three lines were written byac9376a74(PR #16580), a descendant, which describes that re-raise. Stage 6's anchor, reused by the storage, datasource and analytics stages#101591ec36b730(PR #10251): a settings write issued before the engine is bound is refused withSETTINGS_ENGINE_NOT_BOUND(503). Its message states that every read in any state is unchanged, which is the "left reads open" all three lines describe. The message does not name#10159, but its own diff does, once, in its changeset ("refused loudly instead of resolving successfully while nothing reachessys_setting(#10159)"), andsettings-prebind-read-warning.test.ts:17already paired the two numbers.git blameputs the three lines ina24b7fa4d(PR #11044), the later read-half fix, a descendant. New to the sweep#1706250b6f17d4(PR #17071): adds the package-local route-ledger conformance guard beside the dogfood live-mount parity gate, and updates the ledger header that had said such a guard was deliberately omitted. Its message does not name#17062; its diff does, on 3 added lines, which are the three sites here (git blameputs all three in it). New to the sweep#1131899ccbb9c8(PR #11467): the Settings, AI "Test connection" fallback keeps its mount instruction on all three real-provider branches and gains the cloud-only boundary read fromPLATFORM_CAPABILITY_PROVIDERS.ai. Its own changeset states that "the embedder hint at the fourth site is deliberately left alone ... and pinned by a contrast test", which is the fence:339describes. Its message's trailer names#11318as the issue it answers, its diff names the number 3 times, andgit blameputs all three lines in it. New to the sweepEvery cited sha matches exactly one commit (
git rev-parse --disambiguate, count 1 for each of the 4), and all 4 are ancestors of the base (merge-base --is-ancestor, exit 0 for each; reverse leg, base against each anchor, exit 1 for each; control legs exit 0: stage 1's landing422db788a, and the repository's root commit, which lies deeper than every anchor; the history is complete,--is-shallow-repositoryfalse, 15,193 commits). Each of the 4 numbers answers 404 on the issues endpoint, which serves pull requests too, read one by one.No ADR,
scripts/adr-anchors/file or otherdocs/page records the decision of any of the 4:docs/adrnames none of the numbers, and none of their mechanisms (AuthzStoreUnavailableError,SETTINGS_ENGINE_NOT_BOUND,engineBindPending, the settings route ledger, the AI hint's edition boundary).Wordings to check
settings-service-plugin.ts:307); 「([finding] a permission-store read failure resolves as an AUTHENTICATED caller holding ZERO capabilities — the package door answers 403 FORBIDDEN, byte-identical to a genuine capability denial #13279)」 became 「(commit 6a180e4)」 on 2 lines; 「[finding] a permission-store read failure resolves as an AUTHENTICATED caller holding ZERO capabilities — the package door answers 403 FORBIDDEN, byte-identical to a genuine capability denial #13279's permission-store re-raise」 became 「commit 6a180e4's permission-store re-raise」. These are the forms the storage and datasource stages used for the same sha.#10159. 「is why SettingsService accepts a write before its engine is bound and answers "resolved" while nothing reaches sys_setting — everykernel:readyhook registered frominit()is inside that window #10159's fix deliberately left reads open」 became 「is why commit 1ec36b7's write refusal deliberately left reads open」; 「(SettingsService accepts a write before its engine is bound and answers "resolved" while nothing reaches sys_setting — everykernel:readyhook registered frominit()is inside that window #10159's fix left reads open on purpose)」 became 「(commit 1ec36b7 left reads open on purpose)」; 「(SettingsService accepts a write before its engine is bound and answers "resolved" while nothing reaches sys_setting — everykernel:readyhook registered frominit()is inside that window #10159 / PR fix(service-settings): refuse a settings write issued before the engine is bound #10251)」 became 「(commit 1ec36b7, PR fix(service-settings): refuse a settings write issued before the engine is bound #10251)」, with the pull-request number kept as the convenience link beside its own squash commit.#17062. 「Two layers, since [finding] service-settings' route ledger has no conformance guard — the pattern every sibling ledger follows is silently missing here #17062.」 became 「Two layers, since commit 50b6f17.」 The docblock goes on to describe the conformance test that commit added as the second layer.settings-route-ledger.conformance.test.ts:4: 「Settings route-ledger conformance ([finding] service-settings' route ledger has no conformance guard — the pattern every sibling ledger follows is silently missing here #17062)」 became 「Settings route-ledger conformance (the issue behind commit 50b6f17)」, because:25of the same docblock says 「(per the issue)」.manifests/ai.manifest.test.ts:277: 「The AI settings manifest tells an operator at runtime to mount@objectstack/service-ai, which the capability roster declares cloud-only (no open-edition version to install) #11318 —」 became 「The card behind commit 99ccbb9:」, because:288「the very claim this card is about」 and:329「The un-followable form this card retired」 speak of that card.ai.manifest.test.ts:339. 「deliberately not edited — The AI settings manifest tells an operator at runtime to mount@objectstack/service-ai, which the capability roster declares cloud-only (no open-edition version to install) #11318 fences this site out by name」 became 「... — commit 99ccbb9 fences this site out by name」. The commit's own changeset names that site (quoted in the table).The 2 sites left
manifests/ai.manifest.test.ts:292, adescribetitle (#11318);settings-route-ledger.conformance.test.ts:88, the assertion message a failing run prints (#17062). It is a string, not a comment, and form C does not touch strings.src, listed and left, not edited in this stage:README.mdnames only the live#8026;vitest.config.tsnames only live numbers (#8020,#8030,#8063,#8104,#10374);tsconfig.jsonandpackage.jsonname none;CHANGELOG.mdnames#13279and#10159on 2 lines, the entries of6a180e4and1ec36b7, which are this PR's anchors.Mechanical guard: no code token moves
The guard compares, base
73155fedcagainst head, over all 9 touched.tsfiles:forEachChildwalk, so comments are trivia and JSDoc nodes are never visited). String and template literals are therefore read in full.getChildrenwalk, so punctuation and keywords are included; JSDoc nodes skipped).Results:
ac05607d6: 9,999 base leaf tokens, 0 files with a token change on either reading (exit 0). The first commitff7ef46f4gave the same, and no.tspath changed after it.settings-service.ts(「deliberately left reads open.」 to 「deliberately kept reads open.」): 0 files changed, as expected (exit 0).settings-service-plugin.ts(isAuthzStoreUnavailableError(err)toisAuthzStoreUnavailableErrorX(err)): DIFFER on the identifier (exit 1).ai.manifest.test.ts:292(#11318to#11319): DIFFER on the string literal (exit 1).Every mutation went through
scripts/ablation-replace.mjs(wrap mode) under a shell trap that restores by absolute path, and each landed (anchor 1 to 0, blob changed). Each restore was proven byte-identical to the HEAD blob (1248149a428d,a2fac9ad1f0b,79c2b40a48a6), withgit diff HEADempty and a clean tree afterwards.Changeset
This change ships bytes, so a
patchchangeset for@objectstack/service-settings(.changeset/20596-service-settings-provenance-anchors.md) is included. Its body is stages 12 and 13's commit-anchor text, word for word, with the package name changed.Measured on the built package (A3), after a full workspace build in which this package was a cache miss (71 of 71 tasks, 0 cached, at
ff7ef46f4, which holds every source-line change):files[]isdist,README.mdandCHANGELOG.md, and the package is not private.settings-service.ts:685docblock, on the pre-bind read reporter, is in all four entries:dist/index.js,dist/index.cjs,dist/index.d.tsanddist/index.d.cts(once each).settings-route-ledger.ts:17,settings-routes.ts:72,settings-service-plugin.ts:307) are stripped by the bundle, and the other seven sit in test files.settings-service.ts:685once in each of the four entries, and the neighbours of the three stripped rewrites 0 everywhere.dist, and none of the four old numbers is left there.The later commit adds only the changeset.
Gates (final head
ac05607d6)pnpm check:issue-citationsexits 0 (self-test, 114 cases, 8 batteries).node scripts/check-issue-citations.mjsexits 0: 「no issue citations added against 73155fe (4 file(s) read)」.pnpm check:doc-authoringexits 0 (the sibling-package prose-id baseline holds, no growth).node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackatac05607d6derived 63 commands, the same 63 as at dispatch.--ran, fed each command with its exit code, reports 63 run, 0 NOT MEASURED (a derived zero), 0 unrun, and exits 0.turbo run buildabove ran first under the shared verify lock, so no gate hit an unbuilt workspace.node scripts/check-changeset-fixed.mjs,pnpm check:authz-resolver,pnpm check:error-code-casingandpnpm check:filter-alias-parity, each exit 0.ac05607d6:pnpm --filter @objectstack/service-settings test: 33 files pass and 584 tests pass, which is every tracked test file undersrc/, the 5 touched ones included.pnpm --filter @objectstack/service-settings typecheck(tsc --noEmit) exits 0, andtsc --listFilesputs all 9 touched files in the program..tsfiles, gives 9 files, 0 errors and 0 warnings (its--format jsonoutput). All 9 are in eslint's own population (none reported ignored;dist/index.js, the control, reads ignored).eslint.config.mjsnever enables type-aware linting (noparserOptions.project, as its own lines 327-328 state), so a comment edit here cannot move the verdict on any untouched file. The repo-widepnpm lintis CI's run.pnpm check:nul-bytesexits 0, and a raw scan of the 10 changed files for control bytes finds none.Acceptance notes
CITATION_RErefuses a hyphen after the digits, so a dead#N-wordcitation (#13398-class) is invisible to the diff gate and to the census #20636, including theclause #Nposition). At the base,#N-wordis on 0 lines.#A/#Bis on 11 lines (12 second numbers), and every second number is live:#6580,#5094,#11230,#5480,#5932,#6199and#5204by the census's own judgement, and#5133read on its own as a pull request.option #N,clause #Nand URL-spelled links are on 0 lines. So the claim's 0 / 11 / 0 / 0 hold, and nothing dead hides behind them. The one other raw token beyond the grammar is the colour literal'#6366f1'inmanifests/branding.manifest.ts:32.srcspeak of 「the card」 or 「this card」. They carry no number, and neither instrument sees them. The ones whose antecedent this diff would have removed are handled above; the rest are unchanged, as in stages 8 to 14.#10159→1ec36b730;#17062→50b6f17d4;#11318→99ccbb9c8; and the reused#13279→6a180e42d.mainat73155fedc.mainhas since moved two commits (4b45afaed,15b586dcf). Neither touchespackages/services/service-settings,scripts/check-issue-citations.mjs,.changeset/config.jsonor a path in this diff.15b586dcfmovespackages/spec/liveness/**, a gate input this comment-only diff cannot interact with. No merge was taken; the merge queue rebuilds on the merged generation.Generated by Claude Code