Skip to content

docs(fields): annotate four Field Schema blocks against the exported *FieldMetadata, and document FieldWidgetComponentProps once - #6146

Merged
yinlianghui-tw merged 1 commit into
mainfrom
claude/issue-6138-fields-schema-block-parity
Aug 24, 2026
Merged

docs(fields): annotate four Field Schema blocks against the exported *FieldMetadata, and document FieldWidgetComponentProps once#6146
yinlianghui-tw merged 1 commit into
mainfrom
claude/issue-6138-fields-schema-block-parity

Conversation

@yinlianghui-tw

Copy link
Copy Markdown
Collaborator

Part of #6138 — batch 1 of 2. Deliberately not a closing reference: the card covers all 26 content/docs/fields pages and this PR converts four of them.

What was wrong

Every content/docs/fields page opens with a ## Field Schema block that declares an interface of its own. A self-declared interface with no imports type-checks no matter what it says, because nothing in it refers to anything the packages export. check-doc-snippet-types reported those pages green and structurally could not see whether the documented shape matched the shipped one.

The proof that today's green is vacuous, and that it stops being vacuous

Same page (content/docs/fields/text.mdx), same wrong key (tooltip, which no exported field type declares), two block forms. The mutation was confirmed on disk by grep before any gate result was read, on both legs, and each leg carried a trap … EXIT INT TERM restore.

Leg A — the pre-fix block, restored from main (bfdb9f906):

injected marker 'tooltip' occurrences: 1
28: tooltip?: string; // MUTATION: no exported type declares this
pre-fix form still in place ('interface TextFieldSchema' occurrences): 1
Semantic phase: 227 of 227 block(s) judged, 0 failed.
Every covered documentation snippet compiles against the built types.
os-verify-lock: VERDICT command-exit 0

A key that exists in no shipped type passes green. That is the vacuity, measured rather than argued.

Leg B — the post-fix annotated literal, same page, same key:

injected marker 'tooltip' occurrences: 1
33: tooltip: 'hover me',
post-fix form in place ('TextFieldMetadata' occurrences): 3
pre-fix form absent ('interface TextFieldSchema' occurrences): 0
[semantic] content/docs/fields/text.mdx:33:3 TS2353: Object literal may only specify known properties, and 'tooltip' does not exist in type 'TextFieldMetadata'.
Semantic phase: 227 of 227 block(s) judged, 1 failed.
os-verify-lock: VERDICT command-exit 1

It reddens, and it names the key. Restore leg, confirmed on disk:'tooltip' occurrences: 0, 'interface TextFieldSchema' occurrences: 0, 'TextFieldMetadata' occurrences: 3, and git status --short / git diff HEAD --stat both empty.

No build sits between the mutation and the measurement here — the gate reads the .mdx from disk directly. What the built dist/ governs is the types the annotation resolves against, and the gate's own control line proves that (quoted below).

Why the widget-prop keys moved instead of being deleted

The round-1 measurement (posted on #6138) found that all 26 pages diverge from their exported *FieldMetadata, and on 24 of them the divergence is entirely FieldWidgetComponentProps members — a real, exported, reader-facing surface filed under a heading that says "Field Schema". Deleting them would have deleted correct API. So the two shapes are separated:

  • ## Field Schema becomes a literal annotated with the exported *FieldMetadata, so the sealed type's excess-property check judges every documented key.
  • The runtime half moves to one new page, content/docs/fields/widget-props.mdx, linked from each converted page.

The new page carries no hand-maintained key list.FieldWidgetComponentProps has 76 members, and a prose restatement of a declared surface with nothing judging it is the defect class #6086 is open for. Instead the page carries a gate-compiled tsx widget example and a gate-compiled ts block on the metadata/props distinction, names the type as the source of truth, and describes the five categories the type is assembled from rather than enumerating members. Every member name the prose leans on also appears inside a compiled block, so the compiler judges it.

Three defects the conversion forced out

  • date.mdx documented the range bounds as min / max. DateFieldMetadata declares min_date / max_date, and the sibling datetime.mdx already documented that spelling. Two witnesses agree and one copy diverged, so the docs are corrected and the type is untouched.
  • textarea.mdx named TextAreaFieldMetadata; the export is TextareaFieldMetadata (lowercase a). A name that must resolve, so it now does — an annotation that itself errors is the gate's own documented false-green mechanism.
  • rich-text.mdx named RichTextFieldMetadata, which does not exist at all. Its own block says type: 'markdown' | 'html', so it resolves against the existing MarkdownFieldMetadata / HtmlFieldMetadata pair. No type was minted.

rich-text.mdx also documented five editor keys. Measured against the source rather than assumed: RichTextField reads rows (const rows = richField?.rows || 8;, through an as any) and reads none of toolbar, preview, minHeight, maxHeight — the last two have zero occurrences anywhere in packages/fields/src. All five come out of the annotated block; the one that is genuinely consumed but declared by neither MarkdownFieldMetadata nor HtmlFieldMetadata is filed with that measurement as #6140 (open, unassigned, not addressed here).

Fence re-derivation on current origin/main

Re-derived at claim rather than reused from round 1, since #6134 merged in between:

pagefence of its Field Schema blocktaken here?
24 pages incl. location.mdxtslocation.mdx was re-fenced by #6134 (merged) — not re-fenced again
auto-number.mdxplaintextnot taken — held by in-flight PR #6137, which re-fences and rewrites it
object.mdxplaintextnot taken — same PR

So nothing was left for this PR to re-fence that another claim does not already hold. #5867's in-flight batch (PR #6136) touches content/docs/blocks and content/docs/plugins only — no overlap.

Verification

Blocks-to-compile identity, written before the run and matched exactly: four conversions are one-block-for-one-block (already ts-fenced, one block each, before and after), and the new page adds two compiled blocks and zero fragments, so the delta is +2 and the declared-fragment count must not move.

baseline (bfdb9f906)predictedafter (85f3eaea4)
documents scanned222223223
covered (holding a ts/tsx block)178 (71)179 (72)179 (72)
ungated444444
covered blocks336338338
to compile225227227
declared fragments111111 (unmoved)111

Gates at the final commit 85f3eaea4 (working tree clean), each quoting its own verdict line, exit codes captured before any pipe:

 resolution Module name '@object-ui/types' was successfully resolved to
'/home/user/objectui-6138/packages/types/dist/index.d.ts'
sentinel importing 'ThisNameIsDefinitelyNotExported' produced 1 diagnostic(s) (TS2305)
positive importing 'ComponentSchema' produced 0 diagnostic(s)
undeclared importing '@floating-ui/react-dom' … produced 1 diagnostic(s) (TS2307)
Semantic phase: 227 of 227 block(s) judged, 0 failed.
Every covered documentation snippet compiles against the built types.
__EXIT_doc_snippets=0
✅ Every documented component type is registered.
__EXIT_doc_types=0
✅ check-control-bytes: OK (scanned 5089 tracked text file(s); skipped 85 binary).
__EXIT_control_bytes=0

The resolution control line is the proof the annotations bind to the builtdist/*.d.ts rather than to src/ — the dependency closure was built first (turbo run build, the gate's own --build-filter set, VERDICT command-exit 0).

Render check, read back from the served HTML of all five pages (all HTTP 200): the new page renders its title, its SlugWidget example, toDomProps, aria-required and the categories section; text.mdx renders TextFieldMetadata / pattern_message and the link to the new page; date.mdx renders min_date / max_date; textarea.mdx renders TextareaFieldMetadata; rich-text.mdx renders both MarkdownFieldMetadata and HtmlFieldMetadata and the #6140 reference. Negative assertions on the same HTML: interface TextFieldSchema, DateFieldSchema, TextAreaFieldMetadata, RichTextFieldMetadata, minHeight and maxHeight are all gone from the rendered pages.

Declared narrowing. ESLint's own config (eslint.config.js) scopes every rule block to **/*.{ts,tsx}; this diff contains 0.ts/.tsx files (7 files: 5 .mdx, 1 .json, 1 changeset .md), so no file in eslint's population changed and no untouched file's verdict can move — type-aware linting is not enabled. Root vitest is not implicated for the same measurement: no source or test file changed. CI runs the full farm regardless.

Not done here

FRAGMENT_MARKER was not used; UNGATED_DOCS and the ledger are untouched; no type was minted; no gate was weakened. The remaining 22 pages are PR 2, and the two plaintext pages stay with #6137.


Generated by Claude Code

…*FieldMetadata, and document FieldWidgetComponentProps once
The `Field Schema` block on every `content/docs/fields` page declared an
interface of its own, so the doc-snippet gate compiled it vacuously: a
self-declared interface with no imports type-checks no matter what it says.
Each converted block is now a literal annotated with the field type's exported
`*FieldMetadata`, so the sealed type's excess-property check judges every
documented key. The widget-prop keys the pages carried under the same heading
(`value`, `className`, `disabled`) are real exported API filed under the wrong
heading, so they move to one new page documenting `FieldWidgetComponentProps`
rather than being deleted.
Three defects the conversion forced out: `date.mdx` documented `min`/`max`
where `DateFieldMetadata` declares `min_date`/`max_date`; `textarea.mdx` named
`TextAreaFieldMetadata` where the export is `TextareaFieldMetadata`; and
`rich-text.mdx` named a `RichTextFieldMetadata` that does not exist, now
resolved against the existing `MarkdownFieldMetadata`/`HtmlFieldMetadata` pair.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@yinlianghui-tw@claude