Repository navigation
Commit 030a7b8
Fixes #24162
Clause-②: no (narrowing)
Retires the page component type `record:json` and its props def
`RecordJsonProps`, refused by name through
`RETIRED_PAGE_COMPONENT_TYPES`. This follows the maintainer's ruling
quoted on the card (「业务上没有这个需求啊,处理审批的人为什么需要看json」) and triage grade
`6232511377`. `record:json` was declared spec first (#23745,
`97b8e7a51d`) for one face, the approval request page's raw JSON panel,
and that face was dropped. No renderer was built, no page placed it, and
its one planned producer (PR #23837) was closed unmerged. It shipped in
`18.0.0-next.3`. Under the no-staging rule, this PR removes it in the
next prerelease, with its own changeset. The shape is the
`ai:chat_window` retirement (PR #21531, `48eb9c193`), surface for
surface.
Dev session: `session_01LKyb454ATwXXksfRnB8Xiy` (cloud dispatch from the
`domain:spec#2` seat, claim `6232774903`).
## Accept set, before → after, at each door
| door | before (`eda6f14b7b`) | after (this head) |
| --- | --- | --- |
| `PageComponentType` (enum alone) | accepts `record:json` | refuses:
`invalid_value` with the retirement prescription (the enum error map). A
stranger such as `record:jsonl` keeps zod's own message |
| `PageComponentSchema.type` (node) | accepts `{ type: 'record:json' }`
| refuses: `code: 'custom'`, `path: ['type']`,
`params.retiredComponentType: 'record:json'`, message = the
prescription. Bare, `{}`-bag and populated alike |
| `PageSchema` (what `os validate` / save parse) | accepts the node |
refuses at `regions[i].components[j].type`, one issue per node |
| `ComponentPropsMap['record:json']` (props gate, `check-yaml-examples`,
vocabulary) | strict `RecordJsonProps`: `field` (req.), `label`,
`requiredPermissions` (req., min 1) | row kept as
`retiredComponentProps('record:json')` (`z.never`): every bag refused,
`{}` included, `invalid_type` at `[]` with the prescription |
| lint `component-type-unknown` | silent (known type) | `error` at
`…type`, message = the prescription's head, hint = its "Delete the …"
sentence |
| lint `component-props-*` | judged the bag against the strict row |
`component-props-invalid` `error` at `…properties` for every bag |
| typo suggester | offered `record:json` for `record:jsn` | no longer
offers it (out of `KNOWN_COMPONENT_TYPE_CANDIDATES`) |
| print pages | `PRINT_REFUSED_PAGE_COMPONENT_TYPES` row | row removed:
a retired type is refused at the parse before any print rule reads it
(the map's own docblock rule) |
| exports | `RecordJsonProps` (const + type), JSON Schema
`ui/RecordJsonProps` | removed, the JSON Schema unpublished |
Everything else is byte-identical, including the record blocks' own
fail-open `requiredPermissions` gate. The open string arm stays open.
The prescription (one string, all doors): "`record:json` was removed in
@objectstack/spec 18 (ADR-0049) — it shipped only in the 18.0.0-next.3
prerelease, declared for one raw-JSON panel on the approval request
page, and that panel was dropped: … Delete the `record:json` component
node and put nothing in its place." It names no replacement, by ruling,
and carries no tracker number (`check:doc-authoring`).
## The precedent's surfaces, and whether this PR touches each
| PR #21531 surface | here |
| --- | --- |
| value leaves `PageComponentType`, joins `RETIRED_PAGE_COMPONENT_TYPES`
with a prescription, no tracker number | ✅ `page.zod.ts` |
| enum docblock + `PageComponentSchema.type` `.describe()` name the
retirement | ✅ |
| props def deleted, row kept as `retiredComponentProps` | ✅
`component.zod.ts`, plus the factory's docblock list |
| D3 semantic entry, one `STEP18_RATIONALE` fragment,
`RETIRED_DEFS_BY_MAJOR[18]` entry | ✅ `ui-record-json-retired` (inserted
at its sorted id, `order: 100` = max + 1),
`retired-defs/18.ui__RecordJsonProps.ts`; `registry.ts` generated, not
committed |
| no D2 conversion | ✅ none, see below |
| pins at every door with a control | ✅
`component-record-json-retirement.test.ts` (replaces
`component-record-json.test.ts`) |
| vocabulary pin | ✅ `component-type-vocabulary.test.ts`: known through
the row, not a candidate, `record:` still reserved |
| `component-props-unknown-members.pin.test.ts` line | n/a:
`RecordJsonProps` had no `z.unknown()` member |
| generated baselines | ✅ see Ratchets |
| `content/docs/ui/pages.mdx` hand-written list | n/a: it never listed
`record:json` (grep 0) |
| lint comment naming the def | n/a: no lint source named
`RecordJsonProps` |
| **differs: print classification row** | removed (the precedent had
none) |
| **differs: a lint pin existed** | `validate-record-json-23745.test.ts`
is **flipped** into a refusal pin, not deleted: both lint rules, the
shared `runAuthoringRules('validate')` pipeline, and the typo case, with
`record:approvals` as the live control. Kept rather than deleted because
the map-driven `flags %s` case in `validate-component-types.test.ts`
covers only the type rule, not the props rule or the pipeline |
| **differs: a renderer contract existed** | its census pins move:
`component-record-block-field-security.test.ts` (the
`requiredPermissions` census loses `record:json`),
`component-record-related-list-parent-23134.test.ts` (the whole-bag set
gains it), `type-alias-convention.pin.test.ts`
(`Iso_ui_component__RecordJsonProps` removed, 789 → 788 and the prose
counts) |
| tree-scoped absence pin (playbook §4) | ✅ new: a walk of the five
roots `@objectstack/spec` already declares in
`cross-package-test-inputs.mjs`, judging the authoring shape (a `type`
key valued `record:json`), with its exclusions written beside it.
Registered in `vitest.repo-tests.json`, which
`check:cross-package-test-inputs` demanded |
## D2 decision: none registered
The playbook's §3 conversion is a per-key `stripKeys`. Here the whole
element leaves, so there is no key a walker could strip that leaves a
valid node behind. Deleting an authored page node is a layout decision,
and the `element-filter-removed` docblock rules that a conversion must
not make it. The precedent registered none for the same reason. The D3
entry carries the delegated deletion. A user on `next.3` meets the
prescription at `os validate`.
Because `packages/spec/src/conversions/registry.ts` is not edited, the
carried correction from contract review `6142098559` item A does **not**
ride this PR (per the dispatch: only if that file is edited).
## Ratchets: a whole-def removal, so all four move
Each was regenerated by its generator. The two hand deletions are the
ones the build gate prescribes.
| artifact | movement | proof |
| --- | --- | --- |
| `json-schema.manifest/ui.json` | −1 (`ui/RecordJsonProps`) | build: "1
schema(s) left the published set since eda6f14, each declared
(#4725): json-schema/ui/RecordJsonProps.json — RETIRED_DEFS_BY_MAJOR,
major 18." |
| `authorable-surface/ui.json` | −3 (`field`, `label`,
`requiredPermissions`) | build: "ui/RecordJsonProps:* (3 line(s)) — def
no longer emitted by this build; whole-schema removals are adjudicated
by json-schema.manifest/" |
| `api-surface/ui.json` | −2 (`RecordJsonProps (const)`, `(type)`) |
`gen:api-surface` |
| `declaration-map/ui.json`, `export-origins/ui.json` | −1 each |
`gen:declaration-map`, `gen:export-origins` |
| strictness-ledger counts `ui.md` | `ui/` sites 214 → 213,
`component.zod.ts` 81 → 80 | `gen:strictness-ledger` |
| reference docs `index.mdx`, `ui/component.mdx`, `ui/page.mdx` |
`RecordJsonProps` section gone, enum list −1 | `gen:docs` |
| `authorable-defaults/`, `docs-import-surface.baseline.json` |
unchanged: the def was default-free and never in the docs import surface
| `check:generated` green |
| `authorable-surface.base.json` | untouched | — |
`check:generated` on the final head: `✓ All 14 generated artifacts are
up to date`. No `skills/**` path moved, so `check-governed-merges` is
not owed.
## Consumer grep on this head
`git grep -e 'record:json' -e RecordJsonProps -- . ':!**/CHANGELOG.md'
':!.changeset/'`. `**/CHANGELOG.md` and `.changeset/` are excluded
because they are release-owned records of what `next.3` shipped and are
not edited here (seat ruling). The hits:
- the retirement kit itself: `page.zod.ts`, `component.zod.ts`, the two
entry files, `registry.ts.template`, the five spec test files and the
lint pin;
- `content/docs/references/ui/page.mdx`: 2 lines, the regenerated
`.describe()` naming it as retired.
The control in the same query shape is `record:approvals`, which hits in
9 files. The `.objectui-sha` pin is not touched (objectui `main`: 0
hits, per the card).
## Ablation (fix committed first, `scripts/ablation-replace.mjs`,
restored by blob)
The subject resolves by relative import (`./page.zod`,
`./component.zod`) to `src`, so no `dist` rebuild was involved.
- **Mutation:** the map key renamed to `record:json-ABLATED` (held), and
the row turned into `emptyProps('record:json')`. Tool output: "anchor 1
-> 0, blob fee472c -> 9927e199cb36".
- **Result:** 7 failed, 24 passed. The failures are the map pin, the row
pin, `PageComponentSchema`, `PageSchema` at the element path, the enum
error map, the vocabulary pin and the candidate-list pin.
- **Restore:** both files back to their `HEAD` blobs (`e3f3674b323f`,
`fee472ca872d`), and `git diff HEAD` is empty.
## Gates (local, final head `26e52c407`)
- spec `build` exit 0. `check:generated` `✓ All 14 generated artifacts
are up to date`.
- spec vitest `--project local --maxWorkers=2`: 691 files, 20969 passed,
1 skipped, 1 todo. The new walk runs under `--project repo`: 10 of 10
passed.
- spec `typecheck` exit 0, with `check:test-typecheck: OK`.
- lint: closure built, then `vitest`: 142 files, 6812 passed, 5 skipped.
`typecheck` exit 0.
- Downstream importers of the changed symbols, with the closure built
first: platform-objects, mcp and cloud-connection
`canonical-expression-envelopes` (15, 11 and 16 passed),
metadata-protocol `protocol.runtime-authoring-gate` (145 passed),
showcase `command-center-metric-filter` (3 passed), dogfood
`expression-conformance` (7 passed).
- `check-platform-checklist --changed-from origin/main`: OK, 0 anchors
lost.
- `dispatch-gates --ran`: "✓ 110 derived famil(ies) accounted for — 108
run, 2 NOT-MEASURED". Every family exited 0 except the two below.
- NOT MEASURED: `check:dual-build-cjs-loads`. Reason: it needs a
whole-repo build, and it exited 3 with PREREQUISITE NOT MET.
- NOT MEASURED: `check:type-check-debt`. Reason: repo-wide tsc, killed
by the 420s per-gate cap on the shared box. The two packages this PR
touches typecheck green. Both are declared to CI.
- NOT MEASURED: spec `test:repo` as a whole. It belongs to CI (`Test
Core`); only this PR's new repo-project file was run.
- Changeset gates, with this body as the `--event` payload:
- `check-adr-0087-registration`: "✓ 1 declared-breaking changeset(s) …
[BREAKING+bang+clause-②-narrowing] registered ui-record-json-retired
(new here: ui-record-json-retired)".
- `check-changeset-no-major`: "✓ This diff introduces no `major` bump."
and "✓ LEVEL AXIS: this PR declares clause-② `no (narrowing)`, and no
package whose published source … it moves is graded `patch`".
- `check-empty-changeset`: exit 0.
## Deviations, stated
- **`Clause-②: no (narrowing)`, not the claim's `Clause-②: no`.** The
dispatch asked for the spelling the gates accept for a narrowing today.
`check-changeset-no-major.mjs` reads `(narrowing)` as the BREAKING arm
and stands the level axis down on a bare `no`. The newest merged
narrowings (`24131-rest-public-form-required`,
`24062-authored-install-scope-project`) carry the same line.
- The spec pin file is renamed `component-record-json.test.ts` →
`component-record-json-retirement.test.ts`, the `*-retirement.test.ts`
house name. Its accept pins are flipped, not kept.
## Acceptance notes
- `.changeset/pre/23745-record-json-block.md` and
`packages/spec/CHANGELOG.md` are untouched. They record what `next.3`
shipped, and this PR's changeset records the retirement (seat ruling).
`content/docs/releases/` is untouched.
- objectui#12490 (face 4) stays its `domain:ui` owner's call, per
triage.
- Fixed container overhead, measured: `pnpm install --frozen-lockfile`
52s. The first spec build took 252s on the shared box, and later ones
431–462s.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01LKyb454ATwXXksfRnB8Xiy)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent cb8756b commit 030a7b8
23 files changed
Lines changed: 546 additions & 332 deletions
File tree
- .changeset
- content/docs/references
- ui
- docs/audits/2026-07-unknown-key-strictness-ledger.counts
- packages
- lint/src
- spec
- api-surface
- authorable-surface
- declaration-map
- export-origins
- json-schema.manifest
- src
- migrations
- entries
- retired-defs
- semantic
- 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 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
37 | | - | |
| 36 | + | |
| 37 | + | |
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| |||
364 | 364 | | |
365 | 365 | | |
366 | 366 | | |
367 | | - | |
| 367 | + | |
368 | 368 | | |
369 | 369 | | |
370 | 370 | | |
| |||
375 | 375 | | |
376 | 376 | | |
377 | 377 | | |
378 | | - | |
| 378 | + | |
379 | 379 | | |
380 | 380 | | |
381 | 381 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
17 | | - | |
| 16 | + | |
| 17 | + | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| |||
1790 | 1790 | | |
1791 | 1791 | | |
1792 | 1792 | | |
1793 | | - | |
1794 | | - | |
1795 | | - | |
1796 | | - | |
1797 | | - | |
1798 | | - | |
1799 | | - | |
1800 | | - | |
1801 | | - | |
1802 | | - | |
1803 | | - | |
1804 | | - | |
1805 | | - | |
1806 | 1793 | | |
1807 | 1794 | | |
1808 | 1795 | | |
| |||
0 commit comments