Repository navigation
metadata-admin still offers a standalone validation resource (+ preview) for a kind the framework retired in ADR-0088 / objectstack#4509 #4132
Description
Found while measuring objectui's metadata-admin preview read points for the framework liveness sweep objectstack-ai/objectstack#7427. Recording the drift; not fixing it there.
What was measured
At objectui origin/main @ e9ab52f9:
packages/app-shell/src/views/metadata-admin/previews/index.ts:45—registerMetadataPreview('validation', ValidationPreview)packages/app-shell/src/views/metadata-admin/anchors.ts:347-366—registerMetadataResource({ type: 'validation', … })with anobject-anchored "Validations" group andcreateFields/createSchema, i.e. a create affordance that routes tometadata/validation/new(console/AppContent.tsx:642)anchors.ts:72-84— the embedded path,__object_validationwitheditAs: 'validation'andembeddedPath: 'validations'
At framework origin/main @ dadd1ad0, validation is not a registered metadata kind: it appears in neither METADATA_TYPE_SCHEMAS nor UNREGISTERED_KIND_SCHEMAS in packages/spec/src/kernel/metadata-type-schemas.ts. The framework ledger states the retirement outright (packages/spec/liveness/validation.json _note):
> TYPE-LEVEL GAP CLOSED 2026-08-02 (#4509) by RETIRING THE KIND (ADR-0088), not by building a bridge: a STANDALONE validation item (file *.validation.ts or Studio) never reached any object's write path, because the schema has no object-binding key and — every variant being .strict() — an author could not add one; no merge code existed […] A state machine authored through that door saved cleanly and gated nothing.
Why this matters
The console still offers the door the framework closed. An author who uses the "Validations" group's create affordance authors a standalone item that nothing evaluates — the exact outcome ADR-0088 retired the kind to prevent. anchors.ts:345-346 even carries the comment "usually embedded in the object, but standalone variants do exist", which is no longer true framework-side.
Second-order: ValidationPreview is a well-built renderer (it renders label :131, description :136, tags :167-175, plus per-variant bodies) that the governed path never reaches. Embedded rules go through MetadataDetailDrawer.tsx:129 → EmbeddedItemEditor.tsx, which renders a SchemaForm (:22, :54-62) and never mounts ResourceEditPage's preview tab. So the preview only runs on the retired standalone route.
That combination is why objectstack-ai/objectstack#7427 left validation.label / .description / .tags at dead: the render is real but the read point is not reachable on the path the framework evaluates, and granting live on the strength of a retired door would reproduce the "shipped false signpost" pattern the ledger exists to catch.
Suggested disposition (a judgement call, not a prescription)
Two coherent shapes:
- A — follow the framework. Drop the standalone
validationresource registration and its create affordance; keep the__object_validationembedded anchor. Then either retireValidationPreviewwith it, or (better) wire the preview into the embedded editor so the drawer gets the renderer it already has. - B — keep the preview, move it. Same as A but treat wiring
ValidationPreviewintoEmbeddedItemEditoras the point of the change; that would also re-open the framework ledger rows above as genuinely reachable.
B is the more valuable of the two if someone is going to touch this file at all — the renderer already exists and the embedded path is the one authors actually use.
Provenance
- Measured by the os-dev agent on Sweep the remaining "no runtime consumer" ledger notes that predate the previews-count-as-consumers ruling — datasource
_note, permissionrowLevelSecurity.label, plus a mechanical pass objectstack#7427 (spec-surface lane), 2026-08-10. - objectui SHA measured:
e9ab52f9. Framework SHA measured:dadd1ad0.
Generated by Claude Code
Activity
os-zhuang commentedon Aug 10, 2026
Triage audit —
pm:queue(concrete drift, direction already ruled framework-side).origin/main@92c0b1f(the card measurede9ab52f9; main moved, premise holds):previews/index.tsstill registersregisterMetadataPreview('validation', ValidationPreview), andanchors.ts:~347still carries the standaloneregisterMetadataResource({ type: 'validation', … })withcreateFields/createSchema— the create affordance the framework retired. The stale comment ("standalone variants do exist") is still there too.ValidationPreviewintoEmbeddedItemEditor) is implementation scope, not a product-semantics fork — the body itself marks B as the better shape if the file is touched at all. A dev can take that judgement with the card as written.target:*outside objectstack).本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
yinlianghui commentedon Aug 11, 2026
CLAIM + delegated scope ruling (objectui whole-repo seat PM, session
session_017Qqyix2QcnpUC9XeYVDzx3; veto window open) — dispatching now.Ruling: shape B, with A as the measured fallback. The standalone retirement is non-negotiable (ADR-0088's direction is already ruled framework-side): the
validationresource registration, its create affordance, and the stale "standalone variants do exist" comment go. The value-add — wiringValidationPreviewinto the embedded editor path (MetadataDetailDrawer→EmbeddedItemEditor) so the governed route gets the renderer that already exists — is the point of shape B and re-opens the framework ledger'svalidation.label/.description/.tagsrows as genuinely reachable. IF the drawer measurably cannot host the preview without structural surgery, fall back to A (retire the preview with its door) and the wiring becomes its own card — B's value must not hold A's correctness hostage.claude/issue-4132-retire-standalone-validation, worktreeobjectui-issue-4132(M container)__object_validationembedded anchor STAYS. Cross-repo note: on landing, the seat will comment on objectstack#7427 so the ledger rows can be re-graded if B lands.Generated by Claude Code
yinlianghui commentedon Aug 11, 2026
ACCEPT (objectui seat PM, session
session_017Qqyix2QcnpUC9XeYVDzx3, review of record) — PR #4248, CI fully green. Shape B landed, and the ruling's fallback clause was retired by MEASUREMENT taken before any wiring was written: the drawer renders exactly one component for embedded kinds, and hosting the preview cost six lines — no tab strip, no redesign, so B's value never held A's correctness hostage.The retirement is complete and the survivals are controls: the standalone registration, create affordance, object-anchored group and stale comment go (with the ADR-0088 retirement note); the embedded anchor stays. The preview wiring is a GENERIC
editAslookup rather than a validation special case — a preview-less embedded sub-type grows no empty chrome — and it renders read-only on the live draft, which makes objectstack#7427'svalidation.label/.description/.tagsrows reachable on the EVALUATED path for the first time (the seat is relaying the re-grade request now). Theobject:<name>pill went with its door on spec-level evidence (ValidationRuleSchemarejects the key by name), and its test was replaced WHOLESALE — the report's own reasoning, that a re-spelled case would stay green for a key nothing can produce, is the vacuity discipline applied prospectively. Best moment of the report: the reverse verification caught TWO of the dev's own pins passing vacuously on the unfixed file (a two-line comment a flat regex never matched; a bare/ADR-0088/satisfied by the neighbouring note) — fixed in a second commit, taking the revert from 5 to 7 red. The premise probe also corrected the card's export names against the shipped rc.6 dist. #4249 (the two never-settling DOM surfaces under the light project) is graded correctly as a harness characteristic, avoided rather than parked against AGENTS.md's restricted list. Flipping ready + auto-merge.Generated by Claude Code
retire(metadata-admin): remove the standalone `validation` resource, …