Repository navigation
Commit 9c93ce6
test(spec): the six reader-bound needles move with their readers, naming each cited decision in words instead of a tracker number (stage 31) (#22511)
Part of #20749
Clause-②: no
Stage 31 of this card, the needles stage: answer A in the seat's ACCEPT
`6074213330`, under the claim `6084058576`. Six test strings carried a
tracker id that a reader matches. Each one moves with its reader in this
PR, and the match stays exactly as strong: the new words sit in the same
reader places the old id did. Three class (e) strings that regrew since
stage 30 drop a number: two titles that already explain it, and one
ledger `why:` value that keeps its ruling record id (the claim amendment
in ACCEPT `6085085283`). Text only: no schema shape, key, `.describe()`
string or behaviour moves.
## Census, re-taken at the base
Stage 28's `census28.cjs`, byte-identical (md5 `31d8488b…`), calibrated
first against nine published readings, all reproduced exactly: 128/130,
191/200 and 73/76 (stages 27 to 28), 73/76 and 16/17 (stage 29's base
and head), 17/18 and 10/10 (stage 30's base and head), 17/18 at
`e75dceddd` and 10/10 at stage 30's landing `961d365f1`.
At the base `e148ca984`: **13 messages / 13 ids in 10 files** (titles
2/2, other 11/11).
- the 6 reader-bound strings (moved here);
- the 4 CSS hex colours that stage 21's ACCEPT kept
(`ui/dashboard-chart-structure-refusal.test.ts:94` x2,
`ui/dashboard.test.ts:124` x2);
- 3 regrown since stage 30's landing:
- 2 titles from PR 22315 (`automation/end-node-outcome.test.ts:67`,
`automation/io-node-config.test.ts:472`), rewritten here;
- 1 ledger `why:` value from PR 22425
(`system/metadata-form-zod-reconciliation.test.ts:497`). The claim
amendment in ACCEPT `6085085283` admitted it, and the patch round
rewrote it: `#22211 A` becomes `letter A`, and the ruling record id it
cites stays.
At the head `a766d439f`: **4 / 4 in 2 files**, the 4 hex colours only,
which is the card's end state. Titles 0/0. (`fbec38c32`, before the
patch round, read 5 / 5 in 3 files.)
No file is deferred. At 15:45Z there were 11 open PRs (418 file rows,
each list complete against the PR's `changed_files`). None touches any
of the 14 files in this diff, or the 3 files that still carry an id. The
lit control, `ui/component.zod.ts`, is found in 2 of them (22421 and
22496).
## The six pairs
Each needle and every reader place it matched move together, one span
per line. "Places" are the reader lines where the needle matched inside
the exact text the test reads.
| pair | test string | reader | needle, base → head | reader places,
base → head |
|:--|:--|:--|:--|:--|
| P1 | `ai/build-progress.test.ts:236` | `ai/build-progress.zod.ts`, the
whole file (`SOURCE`) | `cloud#2172` → `the cloud build-progress card` |
8, 27, 77, 84, 108, 123, 177 → the same seven |
| P2 | `ai/build-progress.test.ts:237` | the same file | `objectui#7388
block 2` → `block 2 of the objectui build-panel card` | 85 → 85 |
| P3 | `contracts/approval-service.test.ts:274` | the
`continueRestoredRun` docblock in `contracts/approval-service.ts` |
`#16495` → `the automation-service contract` | 999 → 999 |
| P4 | `ui/notification.test.ts:123`, plus its own anti-vacuity regex at
`:134` | the tombstone note label in `ui/notification.zod.ts` | `//
[#4610]` → `// [dual-source removal]` (and the regex `^\[#4610\]` →
`^\[dual-source removal\]`) | 94 → 94 |
| P5 | `ui/strictness-batch14.test.ts:395` | `ui/notification.zod.ts`
and `ui/sharing.zod.ts`, each whole | `#5015` → `no-door retirement` |
48, 103 and 24, 114 → the same |
| P6 | `ui/component-props-unknown-members.pin.test.ts:322` (the opaque
line's `ruling`) | the assertion at `:417` | `#21704` → `the five
members the last typing stage stopped on` (the regex follows) | the one
`ruling` value → the same |
What each number meant, now said in words:
- **P1, P2.** The cloud card is the one that ruled the build-progress
phase vocabulary in and owns where the emitter sits; the docblock says
both. Block 2 of the objectui card is the piece that admits `verify` in
`extractBuildProgress`, the consumer's strict parse.
- **P3.** The sibling this verb copies is `IAutomationService.cancelRun`
/ `restoreConsumedSuspension`, as the automation-service contract
declared them.
- **P4.** The `./ui` `Notification` / `NotificationConfig` wrappers were
removed as dual-source, and the note's label now says so.
- **P5.** `NotificationActionSchema` and `EmbedConfigSchema` were
retired because they had no authoring door (ADR-0049 enforce-or-remove).
Both modules record that retirement in the same four places as before.
- **P6.** The decision card is the one on the five `ComponentPropsMap`
members the last typing stage stopped on. The record id `5979239990`
stays.
**Readers beyond the claim's "about" lines.** The claim lists
`build-progress.zod.ts` about `:8`, `:27`, `:85` and `sharing.zod.ts`
about `:24`. The old needles also matched `build-progress.zod.ts` 77,
84, 108, 123 and 177, and `sharing.zod.ts` 114. Leaving any of those
would have made the new needle match fewer places than the old one,
which is a stronger test, not the same one. So they move too, inside the
two files the claim admits. Nothing outside the claim's files moves
except the two generated pages, both written by `gen:docs` only:
`ai/build-progress.mdx`, as the claim names, and `ui/sharing.mdx`, which
renders the `sharing.zod.ts` module docblock.
**Shipped text that moved.** This is listed for the review.
- `build-progress.zod.ts`: the module docblock (lines 8, 27, 77, 84,
85), the `BUILD_PROGRESS_PHASES` docblock (108, 123) and the `hop` field
docblock (177).
- `approval-service.ts`: the `continueRestoredRun` docblock (999), which
`dist/contracts/index.d.ts` carries.
- `notification.zod.ts`: comment lines 48, 94 and 103.
- `sharing.zod.ts`: module docblock line 24 and comment line 114.
- The `ai/build-progress` reference page's `description:` front matter
now ends with "(the cloud build-progress card, ruling A)".
`page-description.ts` strips only a parenthetical that holds a tracker
or ADR id, so the words now stay in the description.
No `.describe()` string moves.
**Ids that stay on those lines on purpose.** These are comment citations
that no test matches, so they are not needles: `#15389` and decision
batch `#106` beside P3, and the other ids in the same docblocks.
## Class (e) regrowth
`(#22110)` is dropped from the two titles. Each already states that
card's decision: a flow text slot reads `{{ }}` holes and refuses a
single-brace token. Read with the card's 17 comments and its landing
record. There is no reader: a `git grep -F` of each old title and of
each distinctive head finds only the literal itself. The lit control
`composeStacks` is found in `stack.zod.ts`; the dark control exits 1.
## Text only, proven
- **Byte level, all 13 edited files.** `subst31.cjs` applies the plan to
the base text and compares the result with the head. The plan was
written at 15:48:21Z, before any edit: 31 spans, each required to occur
exactly once on its base line. The result is 13/13 SAME, line counts
unchanged, including both generated pages and the `description:` line
exactly as predicted. Every old span carries an id, and no new span
carries `#` plus digits.
- **Controls, 9/9 as predicted.** One character in an unplanned comment,
an id appended inside a new span, a reverted span, an inserted line,
trailing whitespace, a generated page edited off-plan, a plan with an
absent span and a plan with an id in a new span all go red. The
unmodified copy reads SAME.
- **Stage 28's `textonly28.cjs`, byte-identical**, on the 7 test files:
5 SAME (2 title, 5 declared changes). `notification.test.ts` and the
component-props pin stop at their regex reader lines (134, 417), because
that instrument masks string tokens, not regex literals. With only those
two lines put back to base, both read SAME (1 declared change each).
- **Per-file test counts and status sequences**, base vs head, 7 files,
`--project local --project repo`, JSON reporter: 193 / 193, identical in
7/7. Two fullNames change (the two titles) and 0 differ from the plan.
There are 0 duplicate fullNames on either side. Names carrying `#` plus
digits: 2 at base, 0 at head.
## Same strength, proven
**Places.** `sites31.cjs` finds every place each needle matches, inside
the exact text its test reads. The old needles' places at base equal the
new needles' places at head, pair by pair (the table above). Each new
needle has 0 places at base, and each old needle has 0 at head.
**Mutations.** Each leg goes through `scripts/ablation-replace.mjs`,
which requires the anchor count, restores to `HEAD` and proves blob ==
HEAD after every leg. The test reads the source with `readFileSync` from
`src`, so no build sits between the mutation and the test. The
predictions were written at 15:55:52Z, before the first run. The same
matrix ran at the head and, with the worktree detached at the base, at
the base:
| drift | base | head |
|:--|:--|:--|
| P1, every place | red | red |
| P1, one place (84) of seven | green | green |
| P2 | red | red |
| P3 | red | red |
| P4, the label (the anti-vacuity test and 4 more go red) | red | red |
| P5, both places in `notification.zod.ts` | red | red |
| P5, both places in `sharing.zod.ts` | red | red |
| P5, one place (48) of two | green | green |
| P6, the assertion text | red | red |
| P6, the `ruling` value | red | red |
- **Result:** 10/10 at the head and 10/10 at the base, as predicted.
Every red fails on the needle assertion itself.
- **The null legs:** the first P2 leg at the head never ran.
`ablation-replace` refused it, because its replacement was a substring
of the anchor. The base P2 leg as first written had the same defect and
was not run. Both were re-anchored with a replacement that is not a
substring, and that amendment was written down before the re-run, with
the prediction unchanged.
- **Restore:** after the matrix the worktree is back on the branch at
`fbec38c32`, and `git status` is clean.
## Verification at `fbec38c32`
All heavy runs went through `scripts/pm/os-verify-lock.sh`, slot
`dev-20749-s31`. Each exit was written to a file or read from the lock's
VERDICT line.
- **Workspace build:** `pnpm turbo run build --concurrency=2` over
`./packages/*` and `./packages/*/*` gives 71/71 tasks, exit 0. It is the
prerequisite for the gates that read `dist`.
- **Spec typecheck:** exit 0, and `check:test-typecheck` holds 52 files
/ 246 errors / 135 pinned signatures, unchanged. `tsc --listFilesOnly -p
tsconfig.test.json` holds all 7 edited test files (617 test files in the
program).
- **Spec unit tier, `--project local`, in full:** 630 files passed,
18798 tests passed and 1 todo, exit 0.
- **Spec repo tier, `--project repo`, in full:** 54 files passed, 915
tests passed, exit 0.
- **`check:generated`:** all 15 generated artifacts are up to date.
Before `gen:docs` ran, it named only `content/docs/references/**` as
stale.
- **Derived gates:** `dispatch-gates --commands` derives 109 commands
from the merge base `e148ca984` (14 paths). All 109 exit 0, and `--ran`
reconciles 109 derived, 109 run, 0 NOT-MEASURED, a derived zero.
- **Roster families:** the 6 whose roster sits in a directory this diff
touches also exit 0 (`check-changeset-fixed`, `check:meta-url-spelling`,
`check:spec-changes`, `check:authz-resolver`, `check:error-code-casing`,
`check:filter-alias-parity`).
- **ESLint, a proven narrowing:** `--no-inline-config` over the 11
changed `.ts` files gives 0 errors and 0 warnings. ESLint's own config
reports 11 configured, 0 ignored and 0 with type-aware parser options,
so the diff cannot move a verdict on an untouched file. The 3 Markdown
files are outside ESLint's config.
- **Control bytes:** the scan over the 14 changed files finds 0.
`check:nul-bytes` (in the derived set) exits 0.
## Patch round at `a766d439f` (open question answered A, ACCEPT
`6085085283`)
One span on one line,
`system/metadata-form-zod-reconciliation.test.ts:497`: `(ruling record
6070963704, #22211 A):` becomes `(ruling record 6070963704, letter A):`.
The commit is `a766d439f`, on top of `fbec38c32`, with no merge of
`main` (the PR reported no conflict, and `git merge-tree` onto
`origin/main` `446c8b2a6` is clean).
- **Text only, byte level:** the one-span plan, written at 16:36:23Z
before the edit, applied to `fbec38c32`, equals the head: SAME, 1616
lines on both sides. A control that re-adds an id inside the span reads
DIFFERENT. Stage 28's `textonly28.cjs` with line 497 declared reads SAME
(552 string tokens, 1 changed, declared); without the declaration it
refuses the line, as it should.
- **No reader:** a `git grep -F` of the old text, and of the value's
opening words, finds only the literal itself. No assertion reads the
text, only its length (more than 20).
- **That file's tests:** 76 / 76 passed at base and head, under
`--project local --project repo`. The status sequence is identical and
no fullName changed.
- **Census:** `census28.cjs` at the head reads **4 / 4 in 2 files**, the
4 named hex colours. The same instrument reads 5 / 5 at `fbec38c32` and
13 / 13 at the base `e148ca984`.
- **Full runs at `a766d439f`:**
- workspace build: 71/71;
- spec typecheck: exit 0, with `check:test-typecheck` at 52 / 246 / 135
held, and the patched file is in the `tsconfig.test.json` program;
- spec `--project local`: 630 files, 18798 passed, 1 todo;
- spec `--project repo`: 54 files, 915 passed;
- `check:generated`: all 15 up to date.
- **Gates:** `dispatch-gates --commands` derives the same 109 commands,
all exit 0, and `--ran` reads 109 / 109 / 0 NOT-MEASURED. The 6
directory-sharing roster families also exit 0. ESLint over the file: 0 /
0; it is configured, not ignored and not type-aware.
- **CI on `a766d439f`** at 17:05Z: 33 success, 2 skipped, none red. On
`fbec38c32`, the push of `a766d439f` cancelled 14 jobs, and the
aggregate `TypeScript Type Check` job failed at its "Verify every
type-check lane succeeded" step because its lanes were cancelled. That
red is on the superseded head only.
## Changeset
`@objectstack/spec` `patch`: shipped text moved. The package's `files`
ships `src/**/*.zod.ts`, and the `continueRestoredRun` docblock is in
`dist/contracts/index.d.ts`. `npm pack --dry-run`: 2069 files, 0
`*.test.ts`. The three edited `.zod.ts` sources ship, and
`dist/contracts/index.d.ts` carries the new docblock words (the old ones
are in 0 `dist` files). `Clause-②: no`: no accept-set change.
## Acceptance notes
- **Kept, by ruling:** the 4 CSS hex colours (stage 21's ACCEPT).
- **The regrown ledger `why:` value**
(`system/metadata-form-zod-reconciliation.test.ts:497`, added by PR
22425 after stage 30) was admitted by the claim amendment and rewritten
in the patch round. The census now reads only the 4 hex colours.
- **Comment citations** in the four reader files that no test matches
stay as they are (for example `cloud#1838`, `objectui#7388` in other
sentences, `#4535`, `#5781`, `#15389`).
- **An observation, not filed.** The build-progress liveness watch names
the objectui card as one of two carriers. That card was closed on
2026-09-27 with its block 2 handed off and "not tracked here". The
objectui changeset this repo now carries
(`.changeset/console-f0268ad78485.md`) says the chat panel reads cloud's
verification loop. The docblock's carrier sentence may be stale. This
stage keeps what it says and only replaces the id.
- **A wide reading, for the record.** Counting any `#` plus digits, 4
titles carry `PD #12` / `batch #58` (`conversions/conversions.test.ts`,
`system/i18n-resolver.test.ts`). These are two-digit labels below the
census id pattern, the same at base and head, and outside the census
population.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DhTqaEHqPVSVnAkjG3jywn)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 4e9fe9f commit 9c93ce6
15 files changed
Lines changed: 48 additions & 32 deletions
File tree
- .changeset
- content/docs/references
- ai
- ui
- packages/spec/src
- ai
- automation
- contracts
- system
- ui
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
79 | | - | |
| 79 | + | |
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
87 | | - | |
| 86 | + | |
| 87 | + | |
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
233 | 233 | | |
234 | 234 | | |
235 | 235 | | |
236 | | - | |
237 | | - | |
| 236 | + | |
| 237 | + | |
238 | 238 | | |
239 | 239 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| |||
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
77 | | - | |
| 77 | + | |
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
84 | | - | |
85 | | - | |
| 84 | + | |
| 85 | + | |
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
| |||
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
108 | | - | |
| 108 | + | |
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| |||
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
123 | | - | |
| 123 | + | |
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| |||
174 | 174 | | |
175 | 175 | | |
176 | 176 | | |
177 | | - | |
| 177 | + | |
178 | 178 | | |
179 | 179 | | |
180 | 180 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
| 67 | + | |
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
469 | 469 | | |
470 | 470 | | |
471 | 471 | | |
472 | | - | |
| 472 | + | |
473 | 473 | | |
474 | 474 | | |
475 | 475 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
274 | | - | |
| 274 | + | |
275 | 275 | | |
276 | 276 | | |
277 | 277 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
996 | 996 | | |
997 | 997 | | |
998 | 998 | | |
999 | | - | |
| 999 | + | |
1000 | 1000 | | |
1001 | 1001 | | |
1002 | 1002 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
494 | 494 | | |
495 | 495 | | |
496 | 496 | | |
497 | | - | |
| 497 | + | |
498 | 498 | | |
499 | 499 | | |
500 | 500 | | |
| |||
0 commit comments