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

@claude claude Bot 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

claude added 5 commits August 21, 2026 18:27
…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.

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:system protocol:ui tests tooling labels Aug 23, 2026
@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 queue Aug 23, 2026
Merged via the queue into main with commit 7345308 Aug 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 free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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