Skip to content

Commit 8f59304

Browse files
ci(spec-shape-gate): register the retirement of addRecord mode / formView and the widened DroppedFieldsEvent reason (#25091)
Refs #25055 Clause-②: no The hourly `Spec Shape Gate` on `main` has been red since `fbb42d900` on five diagnostics that no registry entry covers. This PR registers the two spec changes behind them in `scripts/ci/spec-shape-retirements.json`, so the gate reads them as `known (registered: …)` and stops failing. The seat moves the card #25055 to done once the next hourly run on `main` concludes `success`, so the first line above is `Refs`, not a closing keyword. ## The two entries Two entries are appended after the existing three, in the grammar `parseRegistry` reads (`scripts/ci/spec-shape-gate.mjs`, THE REGISTRY). Each entry has exactly the six keys. Each pattern has exactly `file`, `code` and `message`, and the `message` is the diagnostic's full first line. | entry | objectstack PR, merge commit | objectui file | code | message | downstream card | |---|---|---|---|---|---| | A | #24970, `fde7456352318872704c24feadaa6660b9bc649b` | `packages/types/src/__tests__/p2-spec-exports.test.ts` (`:143`, `:144`) | TS2322 | M1 | objectstack-ai/objectui#13308 | | A | (same entry) | `packages/types/src/__tests__/p1-spec-alignment.test.ts` (`:184`, `:185`) | TS2322 | M1 | objectstack-ai/objectui#13308 | | B | #24778, `7532ea3c0893a08a518739aebfe7c0751211f53d` | `packages/data-objectstack/src/spec-symbol-batch6.test.ts` (`:253`) | TS2344 | M2 | objectstack-ai/objectui#13309 | ```text M1: Type 'string' is not assignable to type '{ '[REMOVED] Key retired: run `os validate` for its migration.': never; }'. M2: Type 'false' does not satisfy the constraint 'true'. ``` - **Entry A, `retired`:** the list view's and the page `list-view` node's `addRecord.mode` and `addRecord.formView`, retired as `retiredKey()` tombstones with ADR-0087 drop conversions (`add-record-mode-form-view-removed`). objectui still has two spec-alignment tests in `packages/types` that type a value carrying both keys. A pattern carries no line number, so its two patterns cover all four diagnostics. - **Entry B, `retired`:** "nothing retired -- the spec WIDENED a union". `DroppedFieldsEvent['reason']` gained `stored_expression`. objectui's batch-6 spec-symbol pin `_ReasonIsTheEnum` asserts the exact four-member union. - Both texts say the entry is deleted when its downstream card is done. `registered_at` is `2026-10-21` for both, the UTC date of the commit. - The line numbers in the table are where the diagnostics are now. The patterns do not record them. The file is otherwise unchanged. A script made the edit. It checked that the file at `BASE` (`a39389eb51`) re-serialises byte-identical (2-space JSON, key order, trailing newline). It took the messages from the run's own `##[error]` annotation lines. It checked them against the two identical messages already registered from earlier real runs (objectui#12654 pattern 2 and objectui#12711). It then confirmed that the new text begins with BASE's bytes up to the last existing entry, which leaves `$comment` and the three existing entries byte-unchanged. It confirmed that exactly two entries were appended, each with the six keys in order, and that `parseRegistry` reads 5. The diff is +33 / -0, in one file. Nothing changes in the reader, its grammar, the workflow, any objectui file or any changeset. ## The premise reading - **Run:** the newest completed hourly `schedule` run of `Spec Shape Gate` on `main` when this PR was opened. It is `39565602478` (job `119106999551`) at objectstack `c67f244f5ae99874c8dc756cab1f8de69769841b`, against objectui `main` `3aafc0d530`. It was read through the job log (`get_job_logs`). It reports `5 NEW diagnostic(s) in 3 objectui file(s)`, and its five `##[error]` lines are `spec-symbol-batch6.test.ts:253:7` TS2344, `p1-spec-alignment.test.ts:184:9` and `:185:9` TS2322, and `p2-spec-exports.test.ts:143:9` and `:144:9` TS2322. The messages are M1 and M2 above. There was no sixth diagnostic. - **objectui has not moved:** objectui `main` is now `2794254099`, 2 commits ahead of `3aafc0d530` (compare API). Neither commit touches any of the three files. Read through REST at that sha, the lines are as the run reports them: `mode` / `formView` at `:143`/`:144` and `:184`/`:185`, and the `Equal` against the four-member union at `:253`. - **Attribution:** `git log e4d604e..fbb42d9 -- packages/spec` (non-shallow checkout) lists exactly two commits, `fde7456352` (#24970) and `7532ea3c08` (#24778). `fde7456352` replaces `AddRecordConfigSchema`'s `mode` / `formView` with `retiredKey(ADD_RECORD_MODE_RETIRED)` / `retiredKey(ADD_RECORD_FORM_VIEW_RETIRED)` in `packages/spec/src/ui/view.zod.ts`. `7532ea3c08` widens `DroppedFieldsEventSchema.reason` to five arms in `packages/spec/src/data/data-engine.zod.ts`. Each `merge_commit_sha` was read from REST and matches the seat's reading. `merge-base --is-ancestor` gives exit 0 for both commits against `origin/main` and exit 1 against the last green head `e4d604efd3`. The control leg, an older green head `78ab6474ca` against `e4d604efd3`, gives exit 0. The gate's own attribution table reads only the newest 40 pulls of the 51-commit range, so neither producing PR appears in it. ## Offline proof (at `cff984e88d`) - `node scripts/ci/spec-shape-gate.mjs --self-test`: exit 0, `spec-shape-gate --self-test: 60/60 passed across 7 batteries`. - The typecheck log was built by hand from the run's five annotation lines, in the runner's grouped shape that `parseDiagnostics` reads. Each package gets a `##[group]` header naming `@object-ui/data-objectstack:type-check` or `@object-ui/types:type-check`. Under it, tsc's package-relative lines appear bare (`src/__tests__/p2-spec-exports.test.ts(143,9): error TS2322: M1`), followed by `##[endgroup]`. - Every leg ran `node scripts/ci/spec-shape-gate.mjs report --log LOG --sha cff984e --status 2 --downstream /home/user/objectui --registry REG`, with no `--event`, so no attribution was attempted: | leg | registry | log | exit | verdict line | |---|---|---|---|---| | the entries | this branch (blob `3ab0be6ba2`) | the five | 0 | `spec-shape-gate: 5 diagnostic(s), all registered retirements -- known, not red.` with `#### known -- 5 diagnostic(s) covered by 2 registered retirement(s)`: `:253` reads `known (registered: objectstack-ai/objectui#13309, objectstack PR #24778: …)`, and `:143`, `:144`, `:184` and `:185` read `known (registered: objectstack-ai/objectui#13308, objectstack PR #24970: …)` | | CONTROL: before | `BASE` (blob `c93a0f3dac`) | the five | 1 | `⛔ **5 NEW diagnostic(s) in 3 objectui file(s)**` | | CONTROL: a sixth, other code | this branch | the five, plus `spec-symbol-batch6.test.ts(20,10): error TS2305: Module '"@objectstack/spec/contracts"' has no exported member 'DroppedFieldsEventProbe'.` | 1 | `⛔ **1 NEW diagnostic(s) in 1 objectui file(s)**` (the TS2305), with the five still `known` | | breadth (the limit below) | this branch | the five, plus another TS2344 M2 at `spec-symbol-batch6.test.ts(256,7)` | 0 | `spec-shape-gate: 6 diagnostic(s), all registered retirements -- known, not red.` | The BASE leg's five `::error` annotation messages match the run's five `##[error]` lines byte for byte, except for the sha (`diff` exit 0). So the hand-built log yields the same rows the real run parsed. ## The batch-6 breadth limit Entry B's pattern is file + `TS2344` + `Type 'false' does not satisfy the constraint 'true'.` That is the full message, but the message is the generic one every failed `Assert` of an `Equal` prints. So until objectstack-ai/objectui#13309 is done, any OTHER `Assert` in `packages/data-objectstack/src/spec-symbol-batch6.test.ts` that reds with that message also reads `known`. The breadth leg above shows this. The registry grammar has no narrower spelling: a pattern names a file, a code and a message substring, and nothing else (no line, no symbol). This PR widens no pattern beyond file + code + full message and does not change the grammar. Entry A's message names the retired-key tombstone type, so it covers a TS2322 against that tombstone in its two files. In those two files, that means a retired key. ## Live proof The workflow's `pull_request` trigger is path-filtered to this registry, so this PR runs the gate. That run compiles objectui `main` against this commit, and it is the live reading of the two entries. Its conclusion and its `known` lines are recorded in the `os-dev-report` comment on #25055, not here. The hourly run `39573264707` (at `4feccc2685`, without this registry) was in progress when this PR was opened. ## Gates (at `cff984e88d`) - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` names the tree (`objectstack-ai/objectstack` at `cff984e88d`) and the change set (1 path, +33 / -0). It derived 22 commands: 14 pnpm and 8 direct node. All 22 exited 0, and each exit code was captured before any pipe. Among them, `pnpm check:spec-shape-gate` reports `60/60 passed across 7 batteries`. `pnpm check:nul-bytes` reports `OK (scanned 11643 text file(s) …; no raw ASCII control bytes)`. `pnpm check:cross-package-test-inputs` reports `OK: 31 package(s) read outside themselves, all declared …`. - `--ran` on the `COMMAND :: exit CODE` record: `Run reconciliation — 22 derived, 22 run, 0 NOT-MEASURED, 0 UNRUN.`, a derived zero, because all 22 recorded an exit code. - `git grep spec-shape-retirements` finds only the workflow and the gate script reading this file, and no test reads it. - `git merge-tree --write-tree origin/main HEAD` at `origin/main` `4feccc2685` gives exit 0 and tree `b3ba654e64`. The 3 commits on `main` since `BASE` touch neither `scripts/ci/` nor the workflow. - No package is touched, so no build closure or package tests apply. The PR's check-runs are CI's to report. ## Changeset There is no changeset. `scripts/ci/` sits under the private root package (`@objectstack/spec-monorepo`, `private: true`), and `scripts/ci/` holds no `package.json`. Of the 73 manifests that declare `files[]`, none names `scripts/ci` or `spec-shape`. As a positive control, `packages/spec`'s `files[]` names `dist`. `skip-changeset` applies. ## Acceptance notes - The newest run, `39565602478`, lists the three existing entries as matching nothing: objectstack-ai/objectui#12654, objectstack-ai/objectui#12711 and objectstack-ai/objectui#13022. All three cards are `closed` / `completed`, on 2026-10-16, 2026-10-16 and 2026-10-19. Under the registry's own `$comment`, an entry is deleted once its card is done, so those three are due for pruning. This PR's ruling keeps them byte-unchanged. Noted, not filed; carrier: none. --- _Generated by [Claude Code](https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 31f0f27 commit 8f59304

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

‎scripts/ci/spec-shape-retirements.json‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,39 @@
4747
"message": "Object literal may only specify known properties, and 'status' does not exist in type '{ \"[REMOVED] Key retired: run `os validate` for its migration.\": never; }'."
4848
}
4949
]
50+
},
51+
{
52+
"retired": "the list view's and the page `list-view` node's `addRecord.mode` and `addRecord.formView`, retired as keys -- retiredKey() tombstones on the one AddRecordConfig every list-view door shares, with ADR-0087 drop conversions (`add-record-mode-form-view-removed`) -- objectui still authors both keys in two spec-alignment tests in `packages/types` that type a value carrying them (an `AddRecordConfig` in p2-spec-exports, a `ListViewSchema` in p1-spec-alignment); the entry is deleted when the downstream card closes",
53+
"objectstack_pr": 24970,
54+
"objectstack_commit": "fde7456352318872704c24feadaa6660b9bc649b",
55+
"downstream_card": "objectstack-ai/objectui#13308",
56+
"registered_at": "2026-10-21",
57+
"matches": [
58+
{
59+
"file": "packages/types/src/__tests__/p2-spec-exports.test.ts",
60+
"code": "TS2322",
61+
"message": "Type 'string' is not assignable to type '{ '[REMOVED] Key retired: run `os validate` for its migration.': never; }'."
62+
},
63+
{
64+
"file": "packages/types/src/__tests__/p1-spec-alignment.test.ts",
65+
"code": "TS2322",
66+
"message": "Type 'string' is not assignable to type '{ '[REMOVED] Key retired: run `os validate` for its migration.': never; }'."
67+
}
68+
]
69+
},
70+
{
71+
"retired": "nothing retired -- the spec WIDENED a union: `DroppedFieldsEvent['reason']` gained a fifth arm, `stored_expression` (a stored field whose declared expression the engine computes on every write). objectui's batch-6 spec-symbol pin `_ReasonIsTheEnum` asserts the exact four-member union (`readonly`, `readonly_when`, `primary_key`, `computed`) with a TS2344 `Equal` pin, so the widened union reds it; the entry is deleted when the downstream card closes",
72+
"objectstack_pr": 24778,
73+
"objectstack_commit": "7532ea3c0893a08a518739aebfe7c0751211f53d",
74+
"downstream_card": "objectstack-ai/objectui#13309",
75+
"registered_at": "2026-10-21",
76+
"matches": [
77+
{
78+
"file": "packages/data-objectstack/src/spec-symbol-batch6.test.ts",
79+
"code": "TS2344",
80+
"message": "Type 'false' does not satisfy the constraint 'true'."
81+
}
82+
]
5083
}
5184
]
5285
}

0 commit comments

Comments
 (0)