Skip to content

feat(spec): retire the element:form element at element grain (#9249, ADR-0049) - #11244

Merged
os-sam merged 5 commits into
mainfrom
claude/issue-9249-element-form-verdict
Aug 23, 2026
Merged

feat(spec): retire the element:form element at element grain (#9249, ADR-0049)#11244
os-sam merged 5 commits into
mainfrom
claude/issue-9249-element-form-verdict

Conversation

@claude

@claudeclaudeBot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Fixes#9249

ADR-0049 enforce-or-remove verdict and retirement for element:form, at ELEMENT grain, per the #9220 / PR #9250 mechanism (kept ComponentPropsMap row, D2 strip conversion, all-repo verdict recording). Clause-② applies (the strip changes the accepted set) — needs:contract-review expected.

Element-grain verdict — re-taken 2026-08-23, recorded verbatim

The prior WIP's verdict was never written down (withdrawal audit on the card); it is re-taken here on today's merged refs, per the dispatch.

objectstack — origin/main @ dd84ddd796d32a1deb9b8b71165c9bce5ddac30a

Runtime-reader closure — zero hits in every runtime/consumer package:

$ git grep -n "element:form" origin/main -- 'packages/core' 'packages/runtime' 'packages/rest' \
'packages/plugins' 'packages/services' 'packages/client' 'packages/client-react' \
'packages/metadata' 'packages/metadata-protocol' 'packages/objectql' 'packages/cli' \
'packages/adapters' 'packages/platform-objects' 'packages/qa' 'examples' 'skills'
(no output)
exit=1

Positive control (same query space, live block type — must be non-zero for the zero to count):

$ git grep -c "record:related_list" origin/main -- 'packages/platform-objects' 'examples'
origin/main:packages/platform-objects/CHANGELOG.md:3
origin/main:packages/platform-objects/src/pages/sys-organization.page.ts:4
origin/main:packages/platform-objects/src/pages/sys-position.page.ts:3
origin/main:packages/platform-objects/src/pages/sys-user.page.ts:8
exit=0

Full-tree enumeration: 16 files contain element:form; every one is (a) the spec declaration itself and its generated artifacts (component.zod.ts, page.zod.ts, translation.zod.ts describe strings, component.test.ts, format-type.test.ts, i18n-resolver.test.ts), (b) the packages/lint validator halves this PR retires (validate-page-field-bindings.ts:200 binding row, validate-react-page-props.ts comments), (c) docs/audit/CHANGELOG prose — the 2026-06 page-liveness audit itself lists element:form under "Aspirational (render 'Unknown component type')" — or (d) untouched neighbor fixtures inside other retirements' conversion fixtures.

Reader-closure reasoning: page components are rendered by objectui, never by this repo's runtime; the only programmatic readers of the component-type vocabulary are the packages/lint validators, whose dispatch is via ComponentPropsMapgit grep -ln "ComponentPropsMap" origin/main outside packages/spec/ returns only packages/lint/* sources plus docs/CHANGELOG prose, and ElementFormProps outside spec's own generated artifacts appears only in generated reference docs. No runtime package reads the element; the lint rows are declaration-driven validation, not consumption.

objectui — origin/main @ 3ece13e331b65e31b0cadbfb9feeb2fa50a3fd4a (fetched 2026-08-23)

$ git grep -n "element:form" origin/main
docs/audits/2901-spec-enum-renderer-coverage.md:99 (audit: "24 of 34 registered. Hard: ai:chat_window, element:filter, element:form" — NOT registered)
packages/app-shell/CHANGELOG.md:12391 (history: palette entry removed — "no renderer")
packages/app-shell/src/views/metadata-admin/previews/__tests__/block-config.test.ts:166
(comment describing the exclusion pin: expect BLOCK_TYPE_META element:form toBeUndefined)
packages/app-shell/src/views/metadata-admin/previews/block-types.ts:156
('element:form': 'no renderer — use the object-bound `object-form` block')
packages/components/src/renderers/basic/elements.tsx:18 (stale comment — objectui#4935's cleanup scope, untouched by this PR)
exit=0

Renderer-registry check — zero, with a passing positive control:

$ git grep -n "element:form" origin/main -- 'packages/core/src/registry'
(no output)
exit=1
$ git grep -n "element:button" origin/main -- 'packages/core/src/registry'
packages/core/src/registry/public-blocks.ts:91: 'element:button',
exit=0

cloud — SETTLED on the card (not re-taken, per the standing ruling)

Two independent zero-readings with passing positive controls at cloud refs 5f1bf23f and a11458b (issue #9249, comments of 2026-08-20 and 2026-08-21).

Verdict: dead at element grain. Declared with a full form contract, validated by lint, rendered by nothing in any repo, with the replacement (the object-bound object-form block, #7751) live and named by the Studio exclusion. Premise valid; retirement proceeds.

What this PR does

WIP audit trail

The branch's pre-existing WIP commit 65402414 (audit input per the withdrawal comment) was audited file-by-file against .claude/skills/spec-property-retirement and the #9220 / PR #9250 precedent. Audit outcome: kept, with one correction — its measurement refs (objectstack @c684d00cfc, objectui @76ceb1e) named a verdict that was never recorded anywhere; all citations (six entry files, the conversion comment, the changeset) now carry the re-taken, recorded readings above. Liveness ledger: no entries exist for either element's props (matches the merged element:filter precedent) — nothing owed.

Reverse verification (from committed state 712b269f)

Predicted direction, stated before running: exactly 3 failures in component.test.ts — the six-key refusal pin, the bare-node materializes-nothing pin, the kept-map-row refusal pin; the bare-node PageComponent pin stays green (node-level parse never dispatches into the props schema); everything else stays green.

Mutation: the six tombstones swapped back to the pre-retirement declarations via an anchored single-occurrence replace; confirmed on disk (injected-anchor grep = 1, deleted-anchor grep = 0) before running. The spec suite resolves these tests through relative src imports (same package), so no dist rebuild is required for this leg; both legs still ran the disk-confirmation step. Restore leg via git checkout from HEAD, script carried a restore trap for EXIT/INT/TERM; restore confirmed on disk (injected-anchor = 0, restored-anchor = 1).

Observed: mutated tree — Tests 3 failed | 196 passed (199), exactly the three predicted pins, zero collateral. Restored tree — Tests 199 passed (199). Direction matches prediction exactly.

Test and gate readouts (head 72f5cab9)

All heavy runs were serialized through scripts/pm/os-verify-lock.sh; verdicts below quote each runner's own printed result line, with exits captured before any pipe.

  • @objectstack/spec build + suite: Test Files 417 passed (417) / Tests 11098 passed (11098); verify-lock VERDICT command-exit 0.
  • Typecheck (spec, lint, platform-objects): each package Done; verify-lock VERDICT command-exit 0 (spec's gate line: check:test-typecheck: OK — 55 file(s) / 263 error(s) held in test-typecheck-debt.json (shrink-only)).
  • @objectstack/lint tests: Test Files 80 passed (80) / Tests 2251 passed (2251).
  • @objectstack/platform-objects tests: Test Files 27 passed (27) / Tests 432 passed (432).
  • @objectstack/dogfood tests: first full run 1 failed | 893 passed | 3 skipped (897) — the one red was the STALE-covers finding above; after the ledger fix, test/expression-conformance.test.ts re-ran green (Test Files 1 passed (1) / Tests 3 passed (3)). Declared narrowing for the re-run: the fix touches only expression-conformance.ledger.ts, whose sole importer (measured by grep across packages/) is that one test file, and the rest of the suite had just passed at the same tree minus a comment-only ledger edit.
  • Gate union derived from the ACTUAL diff by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (provenance line: derived at commit 72f5cab9 in this checkout; --repo assertion holds). All 36 path-derived + convention-triggered families ran locally: PASS across the board — including check:adr-0087-registration, check:variant-docs, check:liveness, check:engine-double-contract, check:where-matcher, check:type-check-coverage, check:nul-bytes — except check:dev-prereqs, which failed on a workspace-build precondition (eight packages this worktree had never built; its own text: "not a list of problems"), cleared by building those packages' closures — re-run green (67 package build artifacts present). check:type-check-debt --re-measure readout: OK — 33 ledger entr(ies) re-measured in 630.6s, 1896 raw tsc error(s) total, none above its recorded number (the lower-able surplus notes are pre-existing and informational).
  • pnpm --filter @objectstack/spec check:generated: all 14 artifact gates green after regeneration (check:api-surface's earlier "stale" was the documented stale-dist phantom, cleared by rebuild).
  • Whole-repo pnpm lint (eslint, repo-wide) is CI-owned and was not run locally; no lint-rule surface is touched by this diff.

Fences honored


Generated by Claude Code

…ADR-0049)
No renderer or reader anywhere — measured objectstack c684d00, objectui
76ceb1e, cloud 5f1bf23f/a11458b (thread readings). All six ElementFormProps
keys are retiredKey tombstones behind the kept ComponentPropsMap row; D2
strip conversion element-form-removed under protocol 18; enum value dropped;
lint COMPONENT_FIELD_SPECS entry dropped; three conversion fixtures re-seated
off the retired neighbor; docs and baselines regenerated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4h3medzvhB9rpfoja9jcw
…generate
The withdrawal audit found the WIP's measurement was never written down; the
verdict is re-taken on today's merged refs (objectstack dd84ddd, objectui
3ece13e33 — zero element:form readers, positive controls passing; cloud stays
settled per the card's two recorded readings) and the six retired-key entries,
the D2 conversion comment and the changeset now cite those refs. Regenerated:
migration-registry concat, authorable surface/defaults, reference docs,
openapi restore.
Retiring element:form removed the last ExpressionInputSchema member the
cel-ui row's 'submit predicates' half covered; the ADR-0060 ratchet
correctly reported STALE covers. Deleted rather than re-pointed, the
mapping.zod.ts:expression (#5552) way; the summary drops the dead half.
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/lint, @objectstack/dogfood, @objectstack/spec, touching 19 documentable anchor(s).

3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/api/error-handling-client.mdx(via onSubmit (literal))
  • content/docs/protocol/objectui/index.mdx(via onSubmit (literal))
  • content/docs/ui/pages.mdx(via PageComponentType (symbol))

1 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v17.mdx(via ComponentPropsMap (symbol))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 8 changed file(s) yielded no anchor (packages/spec/authorable-defaults/ui.json, packages/spec/authorable-surface/ui.json, packages/spec/src/migrations/entries/retired-keys/18.ui__ElementFormProps__aria.ts, …) — pages documenting those are invisible to this run
  • 6 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 45 of 221 client-bound route-ledger rows — the other 176 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run: node scripts/docs-audit/affected-docs.mjs --bridge-coverage

Coarse fallback — 127 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 3ece7704a338e1cb954796c35fb41f7a6e1d8bc4packageMentionDocs.

Which tree this was computed on

This run read content/docs from f7e692ce739b64538e2067d6c681fb8f75ecf38b — the merge of head 72f5cab986e68e4bfccb18c1b9072137429c04b9 into base 3ece7704a338e1cb954796c35fb41f7a6e1d8bc4, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin f7e692ce739b64538e2067d6c681fb8f75ecf38b && git checkout f7e692ce739b64538e2067d6c681fb8f75ecf38b
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 3ece7704a338e1cb954796c35fb41f7a6e1d8bc4 72f5cab986e68e4bfccb18c1b9072137429c04b9 && git checkout -B drift-repro 3ece7704a338e1cb954796c35fb41f7a6e1d8bc4 && git merge --no-ff 72f5cab986e68e4bfccb18c1b9072137429c04b9
node scripts/docs-audit/affected-docs.mjs --json 3ece7704a338e1cb954796c35fb41f7a6e1d8bc4

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 3ece7704a338e1cb954796c35fb41f7a6e1d8bc4 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@os-sam
os-sam marked this pull request as ready for review August 23, 2026 07:02
@os-sam
os-sam added this pull request to the merge queueAug 23, 2026
Merged via the queue into main with commit 7345308Aug 23, 2026
42 checks passed
@os-sam
os-sam deleted the claude/issue-9249-element-form-verdict branch August 23, 2026 07:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:systemprotocol:uiteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ADR-0049 candidate: element:form declares a full form contract with no renderer registration found in objectstack/objectui

2 participants

@os-sam@claude