Skip to content

Commit f7b8a59

Browse files
test(spec): the last system/ file group's test titles state each cited decision in words instead of a tracker number (stage 27) (#21997)
Part of #20749 Clause-②: no Stage 27 of this card: the next area of class (e), the test strings shipped under `packages/spec/src`, as ruled in `5902360492` on #20513. This stage takes the second and last name-ordered `system/` group: the 16 id-bearing test files under `packages/spec/src/system/` from `metadata-form-zod-reconciliation.test.ts` to `worker.test.ts`. Those files carried 63 messages and 70 tracker ids. All 70 now either state what their record decided, in words (form D), or are dropped where the string already says it. No needle sits in this group. Text only: no assertion, identifier, test count or code comment changes, and no file is renamed. This finishes `system/` for this class. ## Census at the base (`aa09db58c9`) Instruments: `census10.cjs` (md5 `9d08602ab972b4b8643c90d64d40fa41`), `census.cjs` (md5 `6e42a45a926d375013c32d62f16a296e`), `census-wide.cjs` (md5 `c98410a19529c439adb0afbfb00026a2`) and `dirtable.cjs` (md5 `dda605c54745b4a60cc14c9a686e4eff`), byte-identical to the copies stages 10 to 26 used. A literal counts as a test title when its folded message is argument 0 of a `describe` / `it` / `test` call, `.each` / `.skip` / `.only` chains included. Everything else is an "other" string. The worktree was cut from `origin/main` at `aa09db58c9`, the claim's base and stage 26's landing. Both instruments read **191 messages / 200 ids in 53 files**, the seat's reading and stage 26's head reading. | directory | files | messages / ids | titles | other | |:--|--:|--:|--:|--:| | (files directly in `src/`) | 30 | 118 / 120 | 117 / 119 | 1 / 1 | | `system/` (this PR: all 16) | 16 | 63 / 70 | 45 / 49 | 18 / 21 | | `ui/` | 5 | 7 / 7 | 0 | 7 / 7 | | `ai/` | 1 | 2 / 2 | 0 | 2 / 2 | | `contracts/` | 1 | 1 / 1 | 0 | 1 / 1 | | **total** | **53** | **191 / 200** | **162 / 168** | **29 / 32** | The group reads **63 messages / 70 ids in 16 files**, the seat's figures file for file: | file (under `system/`) | messages / ids | titles | other | |:--|--:|--:|--:| | `metadata-form-zod-reconciliation.test.ts` | 21 / 24 | 4 / 4 | 17 / 20 | | `metadata-persistence.test.ts` | 1 / 1 | 1 / 1 | 0 | | `metrics.test.ts` | 4 / 5 | 4 / 5 | 0 | | `notification-event-migration-retirement.test.ts` | 3 / 3 | 2 / 2 | 1 / 1 | | `notification.test.ts` | 1 / 1 | 1 / 1 | 0 | | `object-storage.test.ts` | 1 / 1 | 1 / 1 | 0 | | `operation-message.test.ts` | 3 / 3 | 3 / 3 | 0 | | `registry-config.test.ts` | 1 / 1 | 1 / 1 | 0 | | `settings-manifest.test.ts` | 5 / 5 | 5 / 5 | 0 | | `stack-server.test.ts` | 2 / 2 | 2 / 2 | 0 | | `tenant-provisioning-family-retired.test.ts` | 1 / 2 | 1 / 2 | 0 | | `tenant.test.ts` | 3 / 5 | 3 / 5 | 0 | | `tracing.test.ts` | 3 / 3 | 3 / 3 | 0 | | `translation.test.ts` | 12 / 12 | 12 / 12 | 0 | | `validation-message.test.ts` | 1 / 1 | 1 / 1 | 0 | | `worker.test.ts` | 1 / 1 | 1 / 1 | 0 | | **16 files** | **63 / 70** | **45 / 49** | **18 / 21** | Five more test files sit in the same name range and carry no id (`migration`, `search-engine`, `security-context`, `supplier-security`, `translation-typegen`). The 18 "other" strings are declared to the text-only tool: the 17 ledger reasons in `metadata-form-zod-reconciliation.test.ts` (`LEDGER` rows `:256`, `:263`, `:270`, `:283`, `:426`, `:433`, `:440`, `:447`, `:454`, `:470`, `:477`, `:484`, `:491`, `:507`, `:514`, `:521`, and the `TOP_LEVEL_DEFERRED.view` reason at `:880`), and one expect failure message at `notification-event-migration-retirement.test.ts:165`. - **Controls.** Lit: `ai/build-progress.test.ts` (2 / 2) and three files directly in `src/` (`assembled-package-body` 4 / 4, `compose-key-dispositions-export.pin` 5 / 5, `compose-stacks-action-collision-shape` 3 / 3), outside the group, read the same at the base and at the head. Dark: the 16 files read 0 at the head while 141 of their lines still carry `#` plus digits, every one of them a comment line. Planted in a scratch tree: an id put into the rewritten "page component copy, keyed by component id" title reads 1 / 1 (`title:describe`), the base text put back into the `:440` ledger reason reads 1 / 1 (`other`), and an id put into a `metrics.test.ts` comment reads 0. - **A wider pattern** (any `#` plus digits) reads the same as the gate pattern in all 16 files at the base, and 0 in all 16 at the head. - **At the head:** 128 messages / 130 ids in 37 files. The 16 files read 0 / 0, `system/` is absent, and no other file moved. ## How the area was chosen `system/` is taken in name-ordered file groups near the ~100-id bound, the rule stages 20 to 26 used. Stage 26 named this group at 70 ids, and this census reads 70, so no re-cut was needed. **Named for the next stage** (cut from the head census, 128 / 130): - **The files directly in `src/`:** 30 files, 118 messages / 120 ids (117 / 119 titles, 1 / 1 other, at `stack-cross-reference-envelope.test.ts`). The largest file is `stack-inline-action-crossref.test.ts` at 13, and no file needs splitting. It fits one PR and one text-only proof at 120, 20% over the ~100 bound. If the seat holds to "within about 10%", the name-order cut is two groups: `assembled-package-body.test.ts` through `inline-grid-column-carriers.test.ts` (18 files, 61 ids) and `root-entry-migrations-split.pin.test.ts` through `stack.test.ts` (12 files, 59 ids). - The needles: one stage, with an at-tier review. The four colour literals stay, as stage 21 decided. ## What each id became - **22 literals (24 ids)** now state a decision in words. - **1 literal (1 id)** gets its subject back in words. - **40 literals (45 ids)** drop a number the string already explains. Every cited record was fetched with all its comments through REST. 37 records are cited, plus one decision-batch number (below): 35 answer 200, and 2 answer 404. The two that answer 404 were read from what landed, through the commits endpoint (this checkout is shallow): - **#10926**, from `d173125fb8` (#11438): the component-translation `submitLabel` copy key is retired, option A per the maintainer ruling of 2026-08-22; - **#12493**, from `aa5994e17a` (#12626, found through its `@objectstack/spec` CHANGELOG entry): the catalog gains two situation keys, `record_write_denied` and `approval_recall_not_submitter`, each its own sentence, "deliberately not `record_access_denied` restated". **The ledger reasons in `metadata-form-zod-reconciliation.test.ts`** (17 "other" strings). Before any was rewritten, every reader of the ledger and of the file was found: - **The file's own assertions** read the `why` text: `e.why.startsWith(reason)` (the class phrase that leads each ruled root row), `toContain('5861442317')` (the ruling record id, in every ruled root row), ``toContain(`the \`${editor.type}\` type`)`` and `toContain(editor.surface)` (the editor names), the unspellable union arms in backticks, and `why.length > 20`. Every rewrite keeps all of them, so no assertion moves: only the card numbers go, and the record id `5861442317` stays. - **Outside the file:** `packages/spec/scripts/lib/zod-graph.ts`, `zod-graph.test.ts`, `scripts/pm/check-widening-tells.mjs`, `metadata-form-declared-rows.pin.test.ts`, three `*.form.ts` comments and the CHANGELOGs name the file. None reads a `why` string: they cite the file in prose or comments. No gate, generated artifact, docs table or self-test reads the text. So no non-test file moves. - **#19332's ruling is record `5861442317`** (batch #229 item 3, A on all five groups). Each reason already states its class and why, so "(ruling record 5861442317, #19332)" becomes "(ruling record 5861442317)" in 15 rows. - **`:433`** cited #19330 too: "(ruling record 5861442317; per-arm view forms, ruled: one registered form per view kind)". #19330's ruling A (`5754204415`): "`view` is reconciled PER ARM. Each view kind … gets its own registered metadata form". - **`:454`** cited "#18164 batch #209 item 1 A" after the record id `5755653853`. #18164's ruling `5755653853` is decision batch #209 item 1, letter A, so `#209` is a batch number, not a citation (#209 itself is an unrelated 2026 docs PR). The reason already says what was decided ("the picker placed there"; "its offer was decided as that picker in the object designer's select-field editor"), so it now reads "(ruling record 5861442317; the picker placed there by ruling record 5755653853)". - **`:880`** (`TOP_LEVEL_DEFERRED.view`) already says "It is reconciled per arm, each arm against its own registered form", so "(the #19330 ruling, letter A)" becomes ", as ruled". **"ruled" appears in two rewritten strings**, both on #19330's ruling A (`5754204415`): `:433` and `:880` above. **The same-id titles stage 26 listed:** - the five `(#15679)` titles (`metrics:500`, `object-storage:864`, `registry-config:215`, `tracing:524`, `worker:561`) now say "carry their unit in the key name" / "carries its unit in the key name". #15679 is #14478's ruling B (`5548763981`) for `system/`: the fifteen duration keys carry their unit in the key name. That is stage 25's #15677 reading and stage 26's form; - `translation.test.ts`'s six: `#16772` and `#6080` state their decisions (below); `#10926`, `#21257`, `#11287` and `#4667` drop, because each title already says it (retired, retired, the keys the resolver acts on, retired). **Stated in words** (22 literals): | record | literal (under `system/`) | now reads | the decision | |:--|:--|:--|:--| | #19332, #19330 | `metadata-form-zod-reconciliation.test.ts:433` | "(ruling record 5861442317; per-arm view forms, ruled: one registered form per view kind)" | Above. | | #3786 | `metadata-form-zod-reconciliation.test.ts:886` | "metadata form ↔ Zod reconciliation — a hand-written form held to its schema by a gate" | The template for the hand-copied-list pattern: derive from the one source, and where it cannot be derived, a coverage assertion is the gate. | | #15679 (#14478 ruling B) | `metrics.test.ts:500`, `object-storage.test.ts:864`, `registry-config.test.ts:215`, `tracing.test.ts:524`, `worker.test.ts:561` | "… carry their unit in the key name" / "… carries its unit in the key name" | Above. | | #15939, #14478 | `metrics.test.ts:584` | "metrics JSDoc-only durations carry their unit in the describe and the key name" | #15939's ruling (`5564447683`, option 2): a key whose JSDoc names a unit its describe does not is a divergence, refused; the unit moves into the describe, where #14478's rule puts it in the key name. Ruling A (`5635659224`) remediates per file. | | #17785 | `tracing.test.ts:565` | "the OTel exporter and performance durations carry their unit in the describe and the key name" | The tracing file's remediation under #15939's ruling A: the four keys renamed with their unit, and the unit published in the describe. | | #16194 | `notification-event-migration-retirement.test.ts:165` (expect message) | "… — its runner was retired, with no operator door and no boot-time invoker" | The ruling (`5582372148`, batch #88): retire; no operator door and no platform invoker. | | #7414 | `operation-message.test.ts:101` | "operation message catalog — permission_denied, the 403 refusal as localized user copy" | The 403 refusal renders through the operation message catalog in the caller's locale, naming no object, operation or position. | | #7451 | `operation-message.test.ts:193` | "operation message catalog — the row-level user copy, a sentence per situation" | The row-level denials get their own keys (`record_access_denied`, `record_change_not_allowed`), not the grant denial restated. | | #12493 (404) | `operation-message.test.ts:306` | "… sharing write denial and approvals recall, two keys of their own" | What landed in `aa5994e17a`, above. | | #5933 | `settings-manifest.test.ts:230` | "Specifier.valueDomain — a declared standard domain is the boundary, `options` a UI list" | When `valueDomain` is declared, the standard domain is the enforcement boundary and `options` degrades to a UI convenience list. | | #5131 | `settings-manifest.test.ts:246` | "is optional — an undeclared specifier keeps exhaustive-options semantics, enforced at save" | A `select` value outside its `options` is refused at save. #5933 keeps that for an undeclared specifier. | | #7327 | `settings-manifest.test.ts:306` | "`visible` — the settings visibility grammar, narrowed to what the save-time evaluator runs" | Direction (b): narrow the declared type to the grammar the save-time evaluator implements, not CEL. | | #15811 | `settings-manifest.test.ts:338` | "REFUSES an `ast`-only envelope — an evaluated slot requires a non-blank `source`" | Ruling A (`5644350409`, batch #122 item 2): every engine-evaluated expression slot requires a non-blank `source`. | | #4938 | `stack-server.test.ts:61` | "server: carries only keys with a consumer — the retired HttpServerConfig keys stay out" | The maintainer ruling A (`5173147201`): the unreachable `HttpServerConfigSchema` and its seven dead keys are retired. | | #16772 | `translation.test.ts:840` | "dashboard global-filter copy, addressable from a bundle by filter name" | Finding B: `dashboards.NAME.globalFilters.KEY` becomes a bundle group, keyed by the filter name. | | #6080 | `translation.test.ts:901` | "page component copy, keyed by component id" | Page component copy gets a bundle address by component id. | | #7646 | `translation.test.ts:1082` | "screen-flow copy — a `flows` bundle group, runner chrome kept out" | The recorded ruling (`5253154523`): a `flows` surface for flow, screen and field copy; runner chrome stays in the console's own catalog. | | #3957 | `validation-message.test.ts:90` | "renderValidationMessage — English output is unchanged, the field label in place of the API name" | Messages name the field by its label, through the message catalog. The describe pins the English output as before, label for API name. | **Subject back in words** (1 literal): `translation.test.ts:713` "should reject the retired shape …" now names it, "the retired object-first `o.` shape". #3778 retired that shape for the `translation` type. **Dropped where already stated** (40 literals, 45 ids). A number goes only where the string already says its decision. Examples: the 15 ledger reasons above; `:880`'s "(the #19330 ruling, letter A)"; the tails `(#5280)`, `(#14327)`, `(#19332)`, `(#18124)` x2, `(#5933)`, `(#4001)` x3, `(#14478, #14519)`, `(#14519)`, `(#15939, #14478)` on "→ schemaCacheTtlSeconds", `(#10926)`, `(#21257)`, `(#11287)`, `(#15178)`, `(#19620)`, `(#4667)`; and the prefixes `#18118` x2 (before "the retired CEL arm"), `[#16194]` x2, `[#4616]` and `[#4739 / #16325]`. The one 404 number among them (#10926) goes only where the title already states what landed. **No file is renamed.** ## Readers - **Needles:** none. The 17 ledger reasons are data the file's own assertions read for their class phrase, record id and editor names, all kept (above); none reads an id. The one declared expect message is a failure message (the second argument of `expect`), not an expected value. `notification-event-migration-retirement.test.ts` reads the `NOTIFICATION_EVENT_MIGRATION_ID` docblock for a claim matrix's absence and for `RETIRED` / `os migrate` / `boot-time invoker` / `files-to-references`, none of them an id. No title or message in the group is matched against a source docblock or another file's text. - **Test-name filters:** none. No tracked script, workflow or package config passes `-t` / `--testNamePattern` to vitest; the one vitest `-t` hit is a README example under `packages/qa/dogfood` filtering its own fixture. - **Snapshots:** none. No `__snapshots__` directory is tracked under `packages/spec`, and none of the 16 files calls a snapshot matcher. - **Projects:** all 16 files run in `local`; none is in `packages/spec/vitest.repo-tests.json`. The base-versus-head run below takes both projects anyway. - **By substring:** every old literal, its id-bearing fragment and a window around each id (193 needles) was searched with `git grep` at the base, across the tracked tree outside its own file. No gate, doc, filter, snapshot, QA checklist entry or `scripts/check-*.mjs` self-test reads one. The 26 hits are 16 published CHANGELOG lines, which quote "form ↔ Zod reconciliation (#3786)" and "strict from birth (#4001)" as release text, and 10 sibling hits among the five `(#15679)` titles of this group, all rewritten here. - **One code comment quotes a title:** `tracing.test.ts:560` says "a describe headed `Span.duration carries its unit`". The new title keeps that prefix. ## Text-only proof Stage 10's scratch tool (`textonly10.cjs`, md5 `d5e4801dbb4329ab1984da91e92fc47c`) compares base and head file by file on three legs: 1. **Skeleton:** the full AST, with string pieces masked. It must be identical. 2. **Comments:** every comment, byte-equal. 3. **Strings:** each changed string leaf must sit in a test-call title position or on a declared line, must carry a tracker id before, and must carry no `#` plus digits after. This stage declares the 18 lines named above. - **Result:** 16 of 16 files SAME on all three legs, with the per-file counts predicted in writing before any edit (2026-10-06T13:25:38Z). - **Totals:** 63 changed string leaves in 63 literals: 45 titles and 18 declared. The diff's `+` and `-` lines are exactly the 63 planned lines as multisets, and every file keeps its line count. - **Controls (14 of 14 as predicted on the first run, on scratch copies, each anchor hit once):** identifier rename DIFF; numeric literal DIFF; comment edit COMMENT DIFF; a non-title string given an id VIOLATION; a rewritten title given a new id VIOLATION; a title that was id-free at base edited VIOLATION; one title reverted to base SAME; an `it.each` row given an id VIOLATION; an undeclared expect message changed VIOLATION; a title re-split into a `+` chain DIFF; a declared ledger reason reverted to base SAME; the declared deferral reason given a new id VIOLATION; the declared expect message given a new id VIOLATION; a template-literal title given a new id VIOLATION. - **Templates and tables:** no `.each` title, no `$name` / `%s` placeholder and no table row changes. **Test counts:** the 16 files were run at the base, before the edit, and at the head, in the same worktree, with `--project local --project repo`. Both sides read 747 tests in 16 files, all passed, with the same count and status sequence per file in 16 of 16. 302 full test names change, and each changed name equals the base name with the planned replacements applied: 0 mismatches. One full name repeats on each side, the same one: an `it.each` pair under "translation unknown-key strictness" that already printed alike at the base. No head name carries `#` plus digits (302 base names did). No source escape sits in a planned anchor, so the comparison tool met none. ## Changeset: `skip-changeset` Measured, not assumed: - `npm pack --dry-run` of `@objectstack/spec` lists 2068 files. 0 of the 16 touched files are in it, and no `*.test.ts` at all (`files[]` ships `src/**/*.zod.ts`, not tests). The controls `src/system/translation.zod.ts`, `src/system/metrics.zod.ts` and `dist/index.mjs` are in it. - In the built `dist/`, two new phrases and an old one each read in 0 files. The control `Unrecognized key` reads in 42. So this PR publishes nothing, and no changeset is added. ## Verification (at `320cf687c7`) - `pnpm turbo run build` over all packages: 71 / 71, through the shared verify lock (turbo exit 0, recorded to a file). - `@objectstack/spec`: - `vitest run --project local`: 619 files, 18485 passed, 1 todo. - `typecheck`: exit 0, including `check:test-typecheck` (52 files / 246 errors / 135 pinned signatures held). Its program holds all 16 group files, counted by path with `tsc --listFilesOnly -p tsconfig.test.json`. - `check:generated`: all 15 generated artifacts up to date, against the `dist/` the build above wrote. - **Gates:** `dispatch-gates --commands` derived 79 families, the same 79 as stage 26. All 79 exit 0. `--ran` reconciles: 79 derived, 79 run, 0 NOT-MEASURED, 0 UNRUN, every family with its exit code recorded. The five roster families marked as sharing a directory with this diff (`check:meta-url-spelling`, `check:spec-changes`, `check:authz-resolver`, `check:error-code-casing`, `check:filter-alias-parity`) each exit 0. - **ESLint, a proven narrowing:** `--no-inline-config` over the 16 files reads 0 errors and 0 warnings. The population comes from ESLint's own config: 16 configured, 0 ignored. No file sets `parserOptions.project` or `projectService`, so no untouched file's verdict can move. - `check-governed-merges --test`: NOT governed, 126 changed lines (+63 / -63). - A control-byte scan over the 16 changed files finds none. ## `main` since the base Re-fetched just before this PR opened, `origin/main` was one commit past the base (`6befe19c6e`, #21990). It touches 4 files in `packages/metadata-protocol` and `.changeset/`, none of the 16 and none under `packages/spec/src/system/`, so `main` was not merged. `git merge-tree` onto `6befe19c6e` is clean, and none of the 4 open PRs touches any of the 16 files. ## Acceptance notes - **Same-id test titles in other packages** stay: 37 lines in 14 packages (`plugin-security` 9, `lint` 5, `cli` 4, `objectql` 4, `service-settings` 4, `core` 2, `spec/scripts` 2, and one each in `metadata-protocol`, `metadata`, `plugin-approvals`, `qa/dogfood`, `sdui-parser`, `service-automation` and `service-i18n`), each package's share under the #20513 lane children. Examples: `plugin-security/src/permission-denied-user-copy.test.ts`'s four `#7414 —` describes and `metadata/src/migrations/notification-event-migration-retirement.test.ts:54`'s `[#16194]` twin. No same-id title is left in this card's own census. - **Kept record ids in the ledger reasons:** `5861442317` (held by the file's own `toContain('5861442317')` assertion) and `5755653853` are GitHub comment ids of ruling records, outside the gate's three-to-five-digit pattern, not tracker numbers. - **Code comments with live ids** remain in these files, among them the `fieldGroups` / `inlineColumns` / root-coordinate ledger banners in `metadata-form-zod-reconciliation.test.ts` (six comment lines still say "5861442317, #19332"), the `// #7646 —` banner in `translation.test.ts` and the `#17785, ruling A on #15939` block in `tracing.test.ts`. Code comments are not this card's share. --- _Generated by [Claude Code](https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9c3bec0 commit f7b8a59

16 files changed

Lines changed: 63 additions & 63 deletions

‎packages/spec/src/system/metadata-form-zod-reconciliation.test.ts‎

Lines changed: 21 additions & 21 deletions
Large diffs are not rendered by default.

‎packages/spec/src/system/metadata-persistence.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ describe('PackagePublishResultSchema', () => {
573573
// (`filesystem-loader.ts`, `database-loader.ts`) or writes a literal `0`
574574
// (`memory-loader.ts`, `remote-loader.ts`). Milliseconds, integral, non-negative
575575
// — which is exactly `DurationMs`.
576-
describe('metadata load/save result durations declare milliseconds (#18124)', () => {
576+
describe('metadata load/save result durations declare milliseconds', () => {
577577
it('loadTime refuses a fractional millisecond count and a negative span', () => {
578578
const fractional = MetadataLoadResultSchema.safeParse({ data: null, loadTime: 42.5 });
579579
expect(fractional.success).toBe(false);

‎packages/spec/src/system/metrics.test.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ describe('MetricsConfigSchema', () => {
497497
// gate's mechanical `sizeSeconds`: `size` is byte/row-count vocabulary elsewhere
498498
// in this spec, and the parent key is already `window`, so `windowSeconds` would
499499
// read `window.windowSeconds`.
500-
describe('metrics window and period lengths carry their unit (#15679)', () => {
500+
describe('metrics window and period lengths carry their unit in the key name', () => {
501501
const sliBase = {
502502
name: 'api_availability',
503503
label: 'API Availability',
@@ -581,7 +581,7 @@ describe('metrics window and period lengths carry their unit (#15679)', () => {
581581
// Three of the five new names are not the mechanical suffix: see the tombstone
582582
// prose on each key for why `windowSeconds`, `periodSeconds` and a bare
583583
// `intervalSeconds` were rejected.
584-
describe('metrics JSDoc-only durations carry their unit (#15939, #14478)', () => {
584+
describe('metrics JSDoc-only durations carry their unit in the describe and the key name', () => {
585585
const sliBase = {
586586
name: 'api_availability',
587587
label: 'API Availability',
@@ -734,7 +734,7 @@ describe('metrics JSDoc-only durations carry their unit (#15939, #14478)', () =>
734734
//
735735
// Both keep the `.positive()` floor they already declared, so the accepted set
736736
// narrows only by the integer requirement `DurationSeconds` carries.
737-
describe('metrics duration rows declare seconds through the type (#18124)', () => {
737+
describe('metrics duration rows declare seconds through the type', () => {
738738
const window = { durationSeconds: 300, sliding: true };
739739

740740
it('slideInterval refuses a fractional second count', () => {
@@ -821,7 +821,7 @@ describe('metrics duration rows declare seconds through the type (#18124)', () =
821821
* delete it, because the day it silently stops being true is the day the
822822
* retirement stops being audible in one of its two spellings.
823823
*/
824-
describe('#18118 ServiceLevelIndicator.successCriteria — the retired CEL arm', () => {
824+
describe('ServiceLevelIndicator.successCriteria — the retired CEL arm', () => {
825825
const sli = (successCriteria: unknown) => ServiceLevelIndicatorSchema.safeParse({
826826
name: 'api_latency',
827827
label: 'API Latency',

‎packages/spec/src/system/notification-event-migration-retirement.test.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ const PRE_RETIREMENT_MATRIX = `/**
121121
* - \`details.outcome\`: the four-valued result, verbatim.
122122
*/`;
123123

124-
describe('[#16194] adr-0030-notification-event: the id left the creation-attested set', () => {
124+
describe('adr-0030-notification-event: the id left the creation-attested set', () => {
125125
it('CREATION_ATTESTED_MIGRATION_IDS is exactly the TWO surviving ids, in order', () => {
126126
// Literal on purpose. A length alone would not notice which member went,
127127
// and a `not.toContain` alone would pass on an array that lost everything.
@@ -157,12 +157,12 @@ describe('[#16194] adr-0030-notification-event: the id left the creation-atteste
157157
});
158158
});
159159

160-
describe('[#16194] adr-0030-notification-event: the ruled receipt-claim matrix is withdrawn', () => {
160+
describe('adr-0030-notification-event: the ruled receipt-claim matrix is withdrawn', () => {
161161
it("the id's docblock no longer states a ledger-claim matrix", () => {
162162
const doc = notificationEventDoc();
163163
expect(
164164
statesClaimMatrix(doc),
165-
'a receipt-claim matrix is back on an id no code can write a row for — re-read #16194',
165+
'a receipt-claim matrix is back on an id no code can write a row for — its runner was retired, with no operator door and no boot-time invoker',
166166
).toBe(false);
167167
});
168168

‎packages/spec/src/system/notification.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe('NotificationChannelSchema', () => {
5757
// gate that cannot fail. Sabotage-verified in the PR: S1 re-declares a removed
5858
// const in notification.zod.ts, S2 re-exports it from another entry under the
5959
// bare name (the route a "./system does not export it" assertion would miss).
60-
describe('[#4616] notification-template orphan removal', () => {
60+
describe('notification-template orphan removal', () => {
6161
/** Names that must not be exported by ANY public entry point. */
6262
const REMOVED = [
6363
// #4616 — this change.

‎packages/spec/src/system/object-storage.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ describe('ObjectStorageConfigSchema', () => {
861861
// twin mirrors carries no unit token. No gate can catch the twin being renamed
862862
// along with this one — the marker exempts it either way — so a find-and-replace
863863
// that harmonised the two would land silently. The pin below is the only guard.
864-
describe('object-storage durations carry their unit (#15679)', () => {
864+
describe('object-storage durations carry their unit in the key name', () => {
865865
it('REFUSES the retired `AccessControlConfig.maxAge` with the rename in the message', () => {
866866
const result = AccessControlConfigSchema.safeParse({ corsEnabled: true, maxAge: 3600 });
867867
expect(result.success).toBe(false);

‎packages/spec/src/system/operation-message.test.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ describe('operation message catalog', () => {
9898
* `packages/plugins/plugin-security/src/permission-denied-user-copy.test.ts`,
9999
* against the real middleware and a real `II18nService`.
100100
*/
101-
describe('operation message catalog — permission_denied (#7414)', () => {
101+
describe('operation message catalog — permission_denied, the 403 refusal as localized user copy', () => {
102102
/**
103103
* The vocabulary a business user must never read in a permission refusal.
104104
* `positions` is the internal authorization noun the reporter quoted; the
@@ -190,7 +190,7 @@ describe('operation message catalog — permission_denied (#7414)', () => {
190190
* capability AND-gate) deliberately reuses it, so its catalog coverage above is
191191
* already the coverage for that gate.
192192
*/
193-
describe('operation message catalog — the row-level user copy (#7451)', () => {
193+
describe('operation message catalog — the row-level user copy, a sentence per situation', () => {
194194
/**
195195
* The vocabulary a business user must never read in a row-level refusal. It
196196
* is the #7414 list plus the two nouns these particular gates leaked:
@@ -303,7 +303,7 @@ describe('operation message catalog — the row-level user copy (#7451)', () =>
303303
* this catalog block is the only pin the keys have — same battery the #7451
304304
* family keys get.
305305
*/
306-
describe('operation message catalog — sharing write denial and approvals recall (#12493)', () => {
306+
describe('operation message catalog — sharing write denial and approvals recall, two keys of their own', () => {
307307
/**
308308
* The vocabulary a business user must never read in these refusals. It is
309309
* the #7451 list plus the exact nouns the two measured raw strings leaked:

‎packages/spec/src/system/registry-config.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ describe('RegistryConfigSchema', () => {
212212
// lines apart, both bare, and the `min(1000)` bound on the timeout reads as one
213213
// second under the right unit and sixteen minutes under the wrong one — both in
214214
// range, so no parse could have caught the mistake.
215-
describe('registry duration keys carry their unit (#15679)', () => {
215+
describe('registry duration keys carry their unit in the key name', () => {
216216
const url = 'https://registry.example.com';
217217

218218
it('REFUSES the retired `syncInterval` with the rename in the message', () => {

‎packages/spec/src/system/settings-manifest.test.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ describe('SpecifierSchema — layout-only specifiers', () => {
195195
});
196196
});
197197

198-
describe('SpecifierValueDomainSchema — the closed standard-domain vocabulary (#5933)', () => {
198+
describe('SpecifierValueDomainSchema — the closed standard-domain vocabulary', () => {
199199
it('accepts exactly the three domains with measured authoring pull', () => {
200200
for (const d of ['iana_time_zone', 'iso_4217_currency', 'iso_3166_alpha2']) {
201201
expect(() => SpecifierValueDomainSchema.parse(d)).not.toThrow();
@@ -227,7 +227,7 @@ describe('SpecifierValueDomainSchema — the closed standard-domain vocabulary (
227227
});
228228
});
229229

230-
describe('Specifier.valueDomain (#5933)', () => {
230+
describe('Specifier.valueDomain — a declared standard domain is the boundary, `options` a UI list', () => {
231231
it('SURVIVES the parse — a dropped key is the defect this closes', () => {
232232
// #5712's dev measured the current shape by smuggling a `format` key in:
233233
// Zod stripped it and `parse()` returned `undefined`, so the manifest had
@@ -243,7 +243,7 @@ describe('Specifier.valueDomain (#5933)', () => {
243243
expect(parsed.valueDomain).toBe('iana_time_zone');
244244
});
245245

246-
it('is optional — an undeclared specifier keeps #5131 exhaustive-options semantics', () => {
246+
it('is optional — an undeclared specifier keeps exhaustive-options semantics, enforced at save', () => {
247247
const parsed = SpecifierSchema.parse({
248248
type: 'select',
249249
key: 'provider',
@@ -303,7 +303,7 @@ describe('Specifier.valueDomain (#5933)', () => {
303303
});
304304
});
305305

306-
describe('`visible` — the settings visibility grammar (#7327)', () => {
306+
describe('`visible` — the settings visibility grammar, narrowed to what the save-time evaluator runs', () => {
307307
const withVisible = (visible: unknown) =>
308308
SpecifierSchema.safeParse({ type: 'text', key: 'smtp_host', label: 'Host', visible });
309309
const firstMessage = (visible: unknown): string => {
@@ -335,7 +335,7 @@ describe('`visible` — the settings visibility grammar (#7327)', () => {
335335
expect(withVisible({ dialect: 'cel', source: "${data.provider === 'smtp'}" }).success).toBe(true);
336336
});
337337

338-
it('REFUSES an `ast`-only envelope — #15811 moved this slot onto the evaluated rule', () => {
338+
it('REFUSES an `ast`-only envelope — an evaluated slot requires a non-blank `source`', () => {
339339
// It used to pass: the AST is opaque at this layer and the grammar walk had
340340
// nothing to read, so the slot admitted an envelope `evaluateVisibility`
341341
// could never run and the refusal arrived at the tenant's next save. Since

‎packages/spec/src/system/stack-server.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('server: reaches the runtime through defineStack', () => {
5858
});
5959
});
6060

61-
describe('server: carries only keys with a consumer (#4938 stays shut)', () => {
61+
describe('server: carries only keys with a consumer — the retired HttpServerConfig keys stay out', () => {
6262
it('declares exactly `security` and `trustProxy`', () => {
6363
// The hard constraint from the 2026-08-03 adjudication. If this list grows,
6464
// the new key must have arrived with an executor — the whole reason the
@@ -90,7 +90,7 @@ describe('server: carries only keys with a consumer (#4938 stays shut)', () => {
9090
});
9191
});
9292

93-
describe('server.security.rateLimit is strict from birth (#4001)', () => {
93+
describe('server.security.rateLimit is strict from birth', () => {
9494
it('accepts every declared key', () => {
9595
expect(ServerRateLimitConfigSchema.parse({ enabled: true, windowMs: 1000, maxRequests: 3 }))
9696
.toEqual({ enabled: true, windowMs: 1000, maxRequests: 3 });

0 commit comments

Comments
 (0)