Repository navigation
Commit 7e0066a
docs(spec): re-anchor the dead tracker citations in packages/spec/src's test surface to the commits that decided them (#21700)
Part of #20234
Clause-②: no
## What this stage does
The citation gate's census defers `packages/**/*.test.ts`, so the dead
tracker numbers in `packages/spec/src`'s test files were never in its
count. This stage measured that surface and re-anchored every dead site
in its comment and docblock text, in ruling C+D form C (triage
`5856637615`): each line now cites the commit on `main` that decided
what it describes, and says the decision in words. Wherever an earlier
stage of this card, or a sibling lane, already landed an anchor for the
same number, this stage reuses it.
It also takes the two source comments that tests read literally, and
moves each reader onto the new text:
- `src/data/api-derivation.ts:163`: the `[#6259]` marker on
`DATA_ACTION_TO_API_OPERATION` becomes `[commit 6968885]` and the
sentence says what that commit did (it removed the producer-less `batch:
'bulk'` row and stopped the description calling `batch` a runtime
action). Its reader, `src/data/api-derivation.test.ts:236`, splits on
the new marker.
- `src/identity/identity.zod.ts:230`: `(#8715,` becomes `(commit
2c86fe3,`; the maintainer-ruled DELETE and its date stay. Its reader,
`src/identity/api-key-retirement.test.ts:118`, asserts the new opening
phrase.
- The runtime test that stage 6's record also named
(`packages/runtime/src/api-exposure.test.ts:152`) reads
`packages/runtime/src/api-exposure.ts`, not the spec file, so it is not
a reader of this text and is untouched.
Comment and docblock text only, plus those two readers. No test title,
schema, type, export or behaviour change.
## Census (base `7d0781482d`, head `0e92e882f4`)
Instrument: the gate's own `extractCitations` (comment-prose projection)
and `namesThisRepository` over all 596 `packages/spec/src/**/*.test.ts`
files (no `.test.tsx`, `.spec.ts` or `__tests__/` files exist there),
with string literals read through the shared `scanSource` literal
projection. Every distinct in-repo number was probed with REST
`issues/N`, redirects not followed, with lit controls #16862 #16847
#17698 and dead controls #16714 #16715 #16697 at the start, every 100
numbers and the end.
| | base | head |
|---|---|---|
| distinct in-repo numbers probed | 1,397: 1,310 answer 200, 87 answer
404, 0 other | 1,377: 1,309 answer 200, 68 answer 404, 0 other |
| controls | 45/45 lit = 200, 45/45 dead = 404 | 45/45 and 45/45 |
| dead sites in comments and docblocks | **87 sites, 85 lines, 34 files,
40 numbers** | **0** |
| dead sites in string literals | 150 sites, 147 lines, 56 files, 69
numbers | 147 sites, 144 lines, 55 files, 68 numbers |
87 is under the stage's 120-site bound, so this stage takes all of it.
By area: package root 36, `shared/` 10, `system/` 9, `data/` 8, `api/`
5, `automation/` 5, `integration/` 5, `conversions/` 4, `security/` 3,
`identity/` 2. The excluded files (`migrations/**`;
`automation/flow-slot-refusal-codes.test.ts`;
`automation/flow-write-node-stored-metadata-target.test.ts`) carry 0
dead sites, so the exclusions removed nothing.
The three literal sites that left are exactly the two readers' literals.
Every test title is untouched. No in-repo comment citation was added at
head. The one live number that left the in-repo count is #6110, which
now carries its `objectui#` qualifier (below). A raw `#N` scan of the
comment projection agrees with the gate's extractor: its only extra hits
are three `objectui #11166` sites that are objectui's.
The gate's own census (`check-issue-citations.mjs --census --json`,
board enumerated, 196 pages, frontier #21684) reads **0** findings in
`packages/spec/src` at head. The gate's extractor read 2 at base
(`api-derivation.ts:163` #6259, `identity.zod.ts:230` #8715).
### Dead numbers left in string literals (not touched; #20749's class
(e))
68 numbers at 147 sites, all test titles. `data/` 40, `api/` 33, `ui/`
21, `kernel/` 18, `contracts/` 10, `shared/` 6, `system/` 6,
`integration/` 5, `(root)` 3, `identity/` 3, `conversions/` 2,
`automation/` 1. One of them is not a tracker number at all: `#0000` in
`shared/retired-key*.test.ts` is a fixture placeholder.
## Anchors
| number | sites | anchor | where |
|---|---|---|---|
| #6037 | 4 | `18189983d` | type-alias-convention.pin.test.ts |
| #6072 | 1 | `7f713b662` (the squash commit of PR #6072, ADR-0122 phase
1) | type-alias-convention.pin.test.ts |
| #6083 | 5 | `53068c130` (ADR-0122 phase 2) | connector-author-shape,
environment-artifact, type-alias-convention |
| #6085 | 1 | `026101660` (added this very pin file) |
shared/expression-dialect-docs.pin.test.ts |
| #6239 | 1 | `f549a0d4a` (the sweep commit, cited on the sweep's header
line) | type-alias-convention.pin.test.ts |
| #6259 | 1 | `6968885ef` | data/api-derivation.test.ts |
| #6345 | 5 | `e2798fab7` (its diff wrote all five lines) |
conversions.test.ts, stored.test.ts, driver/turso.test.ts |
| #6362 | 3 | `b5404f496` | automation/webhook.test.ts,
integration/connector.test.ts |
| #6527 | 1 | `259459d8b` (the squash commit of PR #6527) |
type-alias-convention.pin.test.ts |
| #6604 | 2 | `d127ff002` | type-alias-convention.pin.test.ts |
| #6605 | 3 | `c6b05c76a` (wrote the prose-count check) |
type-alias-convention.pin.test.ts |
| #8714 | 3 | `42b05af89` | security/explain.test.ts |
| #8715 | 2 | `2c86fe3ea` | identity/api-key-retirement.test.ts |
| #9040 | 2 | `24206416a` |
data/driver/driver-credential-refusal.test.ts |
| #9041 | 1 | `d491625c1` |
data/driver/driver-credential-refusal.test.ts |
| #9741 | 2 | `2a29caa53` | api/protocol.test.ts |
| #10194 | 2 | `2306a765c` | analytics-strictness-batchd,
metadata-url-spelling |
| #10485 | 9 | `35ad101bc` | sync-retirement, metadata-collection,
metadata-url-spelling, stack-top-level-strict, type-alias-convention |
| #10926 | 2 | `d173125fb` | system/i18n-resolver.test.ts,
system/translation.test.ts |
| #11006 | 4 | `cccbe51bf` | api/protocol.test.ts,
type-alias-convention.pin.test.ts |
| #11166 | 1 | `735f5c709` (the runtime and service-datasource lanes'
anchor) | shared/external-errors.test.ts |
| #11333 | 1 | `e58ea8b38` (stage 6's anchor for the same phrase) |
system/environment-artifact.test.ts |
| #12194 | 1 | `311433f6b` | type-alias-convention.pin.test.ts |
| #12493 | 1 | `aa5994e17` | system/operation-message.test.ts |
| #12961 | 2 | `901355c3b` | system/i18n-resolver.test.ts |
| #13135 | 3 | `9e0ba21a1` | type-alias-convention.pin.test.ts |
| #13156 | 1 | `fd289be45` (the sibling files' spelling, "commit
fd289be's strip") | compose-stacks-key-loss.test.ts |
| #13218 | 2 | `c45d8e6b4` | system/i18n-resolver.test.ts |
| #14162 | 1 | `c5a9a437d` (the squash commit of PR #14240, whose body
names #14162 as the card it lands; it is the load path that judges each
`packages[]` entry with `ArtifactPackageEntrySchema`) |
stack-artifact-packages.test.ts |
| #14419 | 1 | `c5a7448d5` (its message names #14419 as the card it
lands) | automation/control-flow.test.ts |
| #14662 | 1 | `35dffeace` | compose-stacks-action-key-collision.test.ts
|
| #14676 | 4 | `13c48c2a5` | integration/connector.test.ts,
type-alias-convention.pin.test.ts |
| #14686 | 3 | `279431e7a` | compose-stacks-action-echo.test.ts |
| #14691 | 2 | `b3a63d32c` | rest-api-config-dead-keys-retirement,
type-alias-convention |
| #14722 | 2 | `23c72be3c` (stage 1's "refuted in commit 23c72be") |
shared/union-author-message-pins.test.ts |
| #16659 | 3 | `ecdfc9411` | schedule-organization.test.ts,
type-alias-convention.pin.test.ts |
| #16864 | 1 | `29dd1a6dd` (it wrote this very pin line) |
conversions/conversions.test.ts |
| #17124 | 1 | `86c505286` (the service-analytics and core lanes'
anchor) | data/analytics-date-range-two-bound-window.test.ts |
Every anchor is unique at nine hex digits, single-parent, and an
ancestor of `main`. That was read from a full, not shallow, treeless
clone of `main` at the base. For 40 of the 49 (number, anchor, file)
pairs, the anchor's own diff wrote a line naming the number into that
file. Where it did not, the anchor's message or its PR body names the
number.
Two census-dead sites are not this repository's numbers. They are
respelled so the gate reads their qualifier, following stage 5's
precedent, and are not re-anchored. Both numbers answer 200 on objectui.
- `api/export-job-family-retirement.test.ts:24-25`: `objectui` / `PR
#10264` was split across a line break, so the census read #10264 as
bare. The line break now falls before `objectui PR #10264`.
- `shared/editability-boundary.test.ts:391-392`: `(objectui#6010 / #6110
/ #6111)` becomes `(objectui#6010 / objectui#6110 / objectui#6111)`, the
spelling `ui/view.zod.ts` and `data/field.zod.ts` already use for the
same pair.
## Proof that only text moved
- **Token streams.** A TypeScript 6.0.3 parser leaf-token comparison
(JSDoc nodes skipped) and a comment-blanked comparison (the shared
`maskComments`, whitespace collapsed) run over all 36 files, base vs
head. 34 files are IDENTICAL on both instruments. The other two differ
only in the declared reader literals: `api-derivation.test.ts` in 2
string tokens (`'[#6259]'` and its assertion message), and
`api-key-retirement.test.ts` in 1 (`'are NOT declared here (#8715'`).
`VERDICT text-only (36 files)`, exit 0.
- **Controls, 8 of 8 as expected.** These ran on scratch copies. An
identifier change, a test-title string, a template literal and a regex
literal each read DIFFERS (exit 1). A line comment, a JSDoc edit and a
block comment each read IDENTICAL (exit 0). An undeclared literal
changed beside the declared ones reads DIFFERS (exit 1).
- **Lines.** 206 changed lines (103 out, 103 in; every file keeps its
line count). 200 are comment lines, and 6 are the three reader lines out
and in.
- **Test counts unchanged.** The 34 touched test files ran at base in a
separate base worktree, and at head: 346 suites and 1,689 tests passed
on both sides. The (fullName, status) list matched for every file.
## Reverse verification of the two readers (each leg through
`scripts/ablation-replace.mjs`, restore proven against `HEAD`)
| leg | mutation | result |
|---|---|---|
| A1 | `api-derivation.ts`: `[commit 6968885]` back to `[#6259]` |
red: "the `[commit 6968885]` removal note vanished from the TSDoc", 1
failed, 31 passed |
| A2 | `api-derivation.test.ts`: the reader back to `split('[#6259]')` |
red, same assertion |
| B1 | `identity.zod.ts`: back to `are NOT declared here (#8715` | red:
`toContain('are NOT declared here (commit 2c86fe3')`, 1 failed, 2
passed |
| B2 | `api-key-retirement.test.ts`: the reader back to `(#8715` | red,
same assertion |
Each leg's mutation landed (anchor 1 → 0, blob changed), and each
restore read blob == HEAD with an empty `git diff HEAD`. Both files are
green at `HEAD` (32/32, 3/3), and the tree is clean afterwards.
## Generated artifacts and the changeset
- After `pnpm --filter @objectstack/spec build`, the rewritten
`DATA_ACTION_TO_API_OPERATION` docblock is in `dist/data/index.d.ts` and
`index.d.mts`. The positive control, the same docblock's unchanged first
sentence, is in the same two files, and the old `[#6259]` marker is in 0
`dist` files.
- The `identity.zod.ts` block comment is in no `dist` file, and neither
is the control sentence from the same block. But `files[]` ships
`src/**/*.zod.ts` verbatim, so the new text publishes.
- So this PR carries a `@objectstack/spec` patch changeset
(`.changeset/spec-test-surface-dead-citation-anchors.md`, with the
`Clause-②: no` line), and `skip-changeset` does not apply. Test files do
not ship.
- `check:generated`: all 15 generated artifacts are up to date, with
nothing regenerated. `check:docs` is green, so no reference page renders
either comment.
## Verification
- `pnpm --filter @objectstack/spec build`, then `check:generated`: exit
0.
- `pnpm --filter @objectstack/spec exec vitest run --project local
--maxWorkers=2`: 610 files passed, 18,113 tests passed, 1 todo.
- The two touched `repo`-project files (`export-job-family-retirement`,
`rest-api-config-dead-keys-retirement`) are green in the 34-file run.
- `pnpm --filter @objectstack/spec typecheck`: exit 0
(`check:test-typecheck` OK: 52 files, 246 errors, 135 pinned signatures
held).
- `dispatch-gates --commands` at `0e92e882f4` derives 85 families.
`--ran` reports 85 accounted, 84 run (all exit 0), 1 NOT MEASURED and 0
unrun.
- The NOT MEASURED one is `check:dual-build-cjs-loads`, which exits 3
(PREREQUISITE NOT MET) without a full monorepo build. It is a declared
narrowing: the diff is comment-only in `packages/spec`, and spec's 19
require entries from the gate's own `--list` all load at head (a
missing-entry control throws). CI runs the full gate.
- Lint, a proven narrowing: `eslint --no-inline-config --format json`
over the 36 touched files gives 36 files, 0 errors and 0 warnings.
`isPathIgnored` is false for all 36, read from eslint's own config.
`eslint.config.mjs` enables no type-aware linting (no
`parserOptions.project`), so a comment edit cannot move any untouched
file's verdict. The repo-wide `pnpm lint` is CI's.
- These readings are at head `0e92e882f4`.
`origin/main` was re-fetched before opening this PR (`83e2feeb46`, 5
commits past the base). None of those commits touches `packages/spec` or
any file here, and `git merge-tree` onto it exits 0, so no merge was
taken.
## Acceptance notes
- **Rung choices, one line each.** #16864 cites `29dd1a6dd`, the commit
that wrote this exact pin line; stage 8 took ADR-0087's 2026-09-13
addendum for a different sentence about the three data-at-rest seams.
#6239's row in the `-7` receipt table now reads `views`, and the sweep
commit `f549a0d4a` is cited on the sweep's header line beside the live
`#6486`.
- **What remains of this card's surface.** In `packages/spec/src` there
are no dead comment or docblock citations left: the gate census reads 0
and the test-surface census reads 0. What remains are the 68 dead
numbers in 147 test-title literals listed above. This stage's dispatch
assigns those to #20749's class (e), so this PR says `Part of` and
leaves the card open for that call.
- **Outside the card's census surface, as earlier stages recorded.**
`docs/audits/2026-07-unknown-key-strictness-ledger.md:676` (#6276) has
no carrier.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 16d241a commit 7e0066a
37 files changed
Lines changed: 119 additions & 103 deletions
File tree
- .changeset
- packages/spec/src
- api
- automation
- conversions
- data
- driver
- identity
- integration
- security
- system
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
25 | | - | |
| 24 | + | |
| 25 | + | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1805 | 1805 | | |
1806 | 1806 | | |
1807 | 1807 | | |
1808 | | - | |
| 1808 | + | |
1809 | 1809 | | |
1810 | 1810 | | |
1811 | 1811 | | |
| |||
1935 | 1935 | | |
1936 | 1936 | | |
1937 | 1937 | | |
1938 | | - | |
1939 | | - | |
1940 | | - | |
| 1938 | + | |
| 1939 | + | |
| 1940 | + | |
1941 | 1941 | | |
1942 | 1942 | | |
1943 | 1943 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
249 | 249 | | |
250 | 250 | | |
251 | 251 | | |
252 | | - | |
253 | | - | |
| 252 | + | |
| 253 | + | |
254 | 254 | | |
255 | 255 | | |
256 | 256 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
412 | 412 | | |
413 | 413 | | |
414 | 414 | | |
415 | | - | |
| 415 | + | |
416 | 416 | | |
417 | 417 | | |
418 | 418 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
217 | 217 | | |
218 | 218 | | |
219 | 219 | | |
220 | | - | |
| 220 | + | |
221 | 221 | | |
222 | 222 | | |
223 | 223 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
276 | 276 | | |
277 | 277 | | |
278 | 278 | | |
279 | | - | |
| 279 | + | |
280 | 280 | | |
281 | | - | |
282 | | - | |
| 281 | + | |
| 282 | + | |
283 | 283 | | |
284 | 284 | | |
285 | 285 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| |||
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
200 | | - | |
| 200 | + | |
201 | 201 | | |
202 | 202 | | |
203 | 203 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
0 commit comments