Skip to content

ci(spec-shape-gate): register the retirement of addRecord mode / formView and the widened DroppedFieldsEvent reason - #25091

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-25055-spec-shape-registry
Oct 21, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-25055-spec-shape-registry

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

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
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 e4d604efd3..fbb42d900 -- packages/spec (non-shallow checkout) lists exactly two commits, fde7456352 (feat(spec)!: addRecord says what renders — enabled required, position top, mode/formView retired #24970) and 7532ea3c08 (feat(spec,objectql): report a caller value a stored expression replaced, as DroppedFieldsEvent reason stored_expression #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 cff984e88d2bece104a7e7040344ce99f48831ba --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


Generated by Claude Code

…View and the widened DroppedFieldsEvent reason

Two entries in the Spec Shape Gate's retirement registry, appended after
the existing three in the grammar parseRegistry reads:

- objectstack PR 24970 (fde7456), addRecord.mode / addRecord.formView
  retired as retiredKey() tombstones: two TS2322 patterns, one per
  objectui packages/types spec-alignment test, downstream card
  objectstack-ai/objectui#13308.
- objectstack PR 24778 (7532ea3), DroppedFieldsEvent['reason'] widened
  with stored_expression: one TS2344 pattern on objectui's batch-6
  spec-symbol pin, downstream card objectstack-ai/objectui#13309.

Each pattern is file + code + the diagnostic's full first-line message,
taken from scheduled run 39565602478 at c67f244.

Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Seat review

ACCEPT · domain:devx seat 1 · os-warren · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-21T09:24Z · head cff984e88d · card #25055 (claim 6311811675, report 6312532977)

This seat readies the PR and queues it with auto-merge.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 21, 2026 09:25
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 21, 2026 09:25
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit 8f59304 Oct 21, 2026
47 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-25055-spec-shape-registry branch October 21, 2026 09:59
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Oct 28, 2026
…in with stored_expression subtracted (objectui#13309) (objectstack-ai#13311)

Fixes objectstack-ai#13309
Clause-②: no

## What was red

objectstack-ai/objectstack#24778 (merge `7532ea3c08`) added a fifth arm,
`stored_expression`, to `DroppedFieldsEventSchema.reason`. The batch-6
pin `_ReasonIsTheEnum` in
`packages/data-objectstack/src/spec-symbol-batch6.test.ts` stated the
union as exactly four members, so objectstack's hourly Spec Shape Gate
(objectui `main` compiled against the spec built from objectstack
`main`) reports `TS2344` on it.

## The change

The objectui#11206 shape, as the card prescribes: `_ReasonIsTheEnum` now
asserts `Equal` of (`DroppedFieldsEvent['reason']` with
`'stored_expression'` removed by `Exclude`) against `'readonly' |
'readonly_when' | 'primary_key' | 'computed'`. `_ReasonIsNotString` is
kept unchanged. The comment above it says: the `Exclude` is a no-op at
the pin; on objectstack `main` it subtracts exactly the new arm, so any
other new arm is still a remainder `Equal` refuses; at the pin bump that
carries `stored_expression` the `Exclude` is dropped and the union
becomes five members (the objectui#13178 tripwire in
`writeWarningToast.test.ts` fails on that bump to say so).

No source file changed. `.objectstack-sha` did not move. A
`.changeset/13309-dropped-fields-reason-pin.md` with an empty
frontmatter is added because `check-changeset-presence` counts a test
file under `src/` as published source (it exits 1 without it, measured).

## Measurements (test file blob identical at `7f58b8c400` and head
`6ee70cebc3`; the head commit adds only the changeset)

| spec compiled against | tree | `pnpm --filter
@object-ui/data-objectstack run type-check` |
|:--|:--|:--|
| pinned spec (`.objectstack-sha` `06cab4849a`) | this branch | exit 0 |
| pinned spec | base `2794254099` | exit 0 (control) |
| spec built from objectstack `main` `28c9a2cb66` | base `2794254099` |
exit 2, `TS2344` on `_ReasonIsTheEnum` (the card's red, reproduced) |
| spec built from objectstack `main` `28c9a2cb66` | this branch | exit 0
|

The `main` side reproduces the gate's own wiring: an objectstack
worktree at `origin/main`, `pnpm install --frozen-lockfile --filter
@objectstack/spec...`, `pnpm --filter @objectstack/spec build`, `npm
pack --ignore-scripts`, then `node scripts/ci/spec-shape-gate.mjs
inject` into this worktree (marker file present in the resolved copy,
`stored_expression` in its declarations). The closure
(`@object-ui/data-objectstack^...`) was rebuilt against it before the
type-check. Afterwards the injected copy was removed and `pnpm run
setup` reinstalled the pin (no marker left, no `stored_expression` in
the installed declarations), and the pin row above was re-measured after
a fresh closure rebuild.

**Sixth-arm probe (one-shot, not kept):** a local alias `_ProbeReason` =
the reason union plus `'sixth_arm_probe'` was put in place of
`DroppedFieldsEvent['reason']` inside the `Exclude`. On-disk anchor
count checked before compiling (1). Result: `TS2344` on
`_ReasonIsTheEnum`, exit 2, against both the `main`-built spec and the
pinned spec. Restored with `git checkout HEAD -- PATH` under an `EXIT
INT TERM` trap; proof is the HEAD blob hash comparison (match) and `git
diff HEAD` empty.

## Gates (local, at the branch head)

- vitest, root form, `--maxWorkers=1`: `spec-symbol-batch6.test.ts` +
`writeWarningToast.test.ts` 2 files / 36 tests passed;
`deleteViewContract.types.test.ts` + `queryDataset.test.ts` (the other
tests naming the file) 2 files / 38 tests passed. The full
`packages/data-objectstack/` and `packages/app-shell/` directories are
declared to CI.
- `check:phantom-deps`, `check:self-import`,
`check:unreferenced-sources`, `check:doc-example-readers`,
`check:handler-key-reads`, `check:side-effects-array`,
`check:element-data-source-declaration`, `check:spec-symbols`,
`check:action-forward-parity`, `check:designer-field-key-parity`,
`check:icon-record-names`, `check:i18n-keys`, `check:i18n-drift`,
`check:i18n-designer-parity`, `check:control-bytes`,
`scripts/check-hand-rolled-comment-mask.mjs`,
`scripts/check-changeset-fixed.mjs`,
`scripts/check-changeset-presence.mjs`: all exit 0.
- `check:spec-floors`: exit 1, the known prerelease-floor reading for
`@object-ui/types` on `main`; not touched here.
- Lint, narrowed: `eslint --no-inline-config --format json` on the one
changed `.ts` file: 1 file, 0 errors, 0 warnings. The package's `lint`
is `eslint .`, so the file is in its population; type-aware linting is
off (no `project` / `projectService` in the printed config), so this
diff cannot move any untouched file's verdict.

## Acceptance notes

- objectstack-ai/objectstack#25055 (the objectstack half) has PR
objectstack-ai/objectstack#25091 open, not merged, registering this
diagnostic in `scripts/ci/spec-shape-retirements.json` with this card as
`downstream_card`. Once this lands, that entry reads "matched nothing in
this run" and is deleted when this card closes.

---

_Generated by [Claude
Code](https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants