Skip to content

docs(guides,tooling): clear three .md pages off the doc-snippet ledger (#5174 batch 3) - #5983

Merged
yinlianghui-tw merged 1 commit into
mainfrom
claude/issue-5174-md-ledger-batch3
Aug 24, 2026
Merged

docs(guides,tooling): clear three .md pages off the doc-snippet ledger (#5174 batch 3)#5983
yinlianghui-tw merged 1 commit into
mainfrom
claude/issue-5174-md-ledger-batch3

Conversation

@yinlianghui-tw

@yinlianghui-twyinlianghui-tw commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Part of #5174

Batch 3 of the .md ledger triage. Walks guide/plugin-development, guide/schema-rendering and guide/theming off UNGATED_DOCS, clearing 81 diagnostics. guide/layout and guide/component-registry are the two entries that remain on this card.

Verified at final commit 2f6207692, working tree clean and byte-identical to what is pushed; the gate union below was re-run after that commit.

Note on this body: GitHub's sanitizer ate every short angle-bracket fragment on the first write, including inside backticks (Record[keyof ColorPalette, …] became Record, and a -- PATH placeholder became -- ). Placeholders below are therefore spelled without angle brackets on purpose.

Ledger

beforeafter
UNGATED_DOCS entries4946
covered documents173176
covered blocks203241
blocks compiled135147
declared fragments6894

Per page, diagnostics actually cleared:

pagediagnosticsblocksfragmentscompile (untouched / edited)
content/docs/guide/plugin-development.md251394 (2 / 2)
content/docs/guide/schema-rendering.md271174 (2 / 2)
content/docs/guide/theming.md2914104 (3 / 1)
total81382612 (7 / 5)

Only the two honest routes were used; no third.

Four real documented-API defects, fixed rather than declared away

1. guide/theming — the theme documents were mostly keys the engine drops. The largest single defect this card has surfaced, and it was hidden the way #5138 describes: all three Theme objects were annotatedTheme while the annotation itself errored (Theme was never imported in two of them), so TypeScript never excess-checked the literals underneath. The ledger entry recorded the annotation error and nothing beneath it.

With the annotation resolving, the brand palette alone had ten of its fourteen colors keys off ColorPaletteprimary-foreground, foreground, muted, muted-foreground, ring, destructive, destructive-foreground, secondary-foreground, accent-foreground are Shadcn CSS variable names, not palette keys — plus radius and fonts, neither of which is a Theme key at all, and no label, which is required.

This is not a typing nicety. generateColorVars iterates COLOR_TO_CSS_MAP, which is typed as a Record keyed by keyof ColorPalette:

for (const [key, cssVar] of Object.entries(COLOR_TO_CSS_MAP)) {
const value = colors[key as keyof ColorPalette];

so a key that is not on ColorPalette can never be emitted — it is dropped in silence at runtime. The page was teaching theme JSON most of which the engine ignores. The fix routes it through the two doors that do work: the real palette keys, each annotated with the variable it emits (text--foreground, surface--card, error--destructive, textSecondary--muted-foreground), and customVars for the rest, which the engine emits verbatim as a --KEY: VALUE declaration and which is the declared escape hatch for exactly this.

2. guide/plugin-development — the documented Vitest example could not run. Under "Testing Plugins", the test asserts toBeInTheDocument() five times with no @testing-library/jest-dom import. That matcher is not a Vitest one; the repo's own tests all import it. A reader copying that block got neither the types nor the matcher.

3. guide/schema-rendering — the page's very first example did not type-check.body: { /* ... */ } is not assignable to SchemaNode | SchemaNode[] (TS2322). Given a real node.

4. guide/schema-rendering — the restated BaseSchema named CSSProperties from nowhere. Now says where it comes from.

Invariants

Checked programmatically by importing origin/main's copy of the script and this branch's copy and comparing key sets:

  • ledger 49 → 46; ADDED ledger entries: []
  • covered set 173 → 176, strictly grows; previously-covered docs newly ungated: none — the UNGATED_DOCS hunk contains only removals, exactly the three batch pages
  • REMOVED entries = exactly the three batch pages and nothing else
  • surviving entries with a non-measured reason: [] across all 46

Gate strictness proven byte-for-byte, not argued. Everything from the Fence scanning banner to EOF — scanFences, listDocuments, derivePackageTypePaths, analyze, compileSnippets, reporting, main — is byte-identical to origin/main: 475 lines, sha dd9e52a11f116f3b on both sides. DOC_EXTENSIONS, TS_FENCE_LANGUAGES, FRAGMENT_MARKER, MIN_REASON_LENGTH and COMPILER_OPTIONS each hash identical. The script diff is the three removed entries plus the ledger docblock's own prose.

--build-filter cost (#4846) — re-measured, not assumed

Filters 20 → 20, and the two filter sets are textually identical. Turbo build tasks 33 → 33, task sets identical package-by-package from --dry=json (tasks ADDED: [], tasks REMOVED: []). Three more covered pages cost this gate zero extra CI build work — the packages they import were already in the closure. Nothing for the maintainer to weigh under #4846.

(Batch 2 moved filters 19 → 20; this batch moves nothing. The real turbo run reports 32 successful where --dry enumerates 33 — the difference is @object-ui/test-support#build, which the dry run lists but which carries no build command. Both sides measured the same way, so the zero delta stands.)

Gates

Exit codes captured before any pipe; every line quotes the gate's own printed verdict.

gateverdict
check-doc-snippet-types.mjsexit 0 — Scanned 222 document(s): 176 covered (40 of them hold a ts/tsx block), 46 ungated · Covered blocks: 241 — 147 to compile, 94 declared fragment(s). · Syntax phase: every block parsed · Semantic phase: 147 of 147 block(s) judged, 0 failed. Controls green: resolution landed on packages/types/dist/index.d.ts, sentinel produced TS2305, positive control 0 diagnostics
scripts/__tests__/check-doc-snippet-types.test.tsTest Files 1 passed (1) · Tests 20 passed (20) — running the script is not running its test; both were run
check-doc-component-types.mjsexit 0 — Scanned 183 doc file(s) (.mdx + .md), 1056 code block(s), 886 type literal(s) · Every documented component type is registered.
check-doc-links.mjsexit 0 — Links are valid across 13 scan roots.
check-control-bytes.mjsexit 0 — OK (scanned 4950 tracked text file(s); skipped 85 binary), plus a manual control-byte grep over all four changed files: no hits
check-changeset-presence.mjsexit 0 — 4 file(s) changed, 0 of them under the src/ of a package the release covers · No source of a released package changed in this range, so no changeset is owed. Verdict followed; none added
check-changeset-no-major.mjsexit 0 — No changeset declares a major bump.
check-lint-coverage.mjsexit 0 — 46/46 packages linted, 0 with outstanding errors (0 total).
lint:root (the complete root eslint task)exit 0 — 0 errors, 26 warnings, all pre-existing; the changed .mjs reports errorCount 0 warningCount 0. Run whole, not narrowed
pnpm checkexit 0 — All checks passed

Lint population read from eslint's own --format json: 166 files, 0 of them .md, so the three changed .md files are outside eslint's population by its own config; the other 46 per-package lint tasks are scoped to packages/*, apps/*, examples/*, which this diff does not touch.

Changeset: none owed — the presence gate says so and its verdict was followed. ⛔ No skip-changeset label: #4912 / #3724 establish that label was never a real mechanism in this repo, and none was created or applied.

Reverse verification

Predictions written to disk before each run with the direction stated; mutation proven by grepping the specific text meant to change; trap … EXIT INT TERM restore; restore leg actually run and verified. No build artifact sits between mutation and thing-under-test on either leg — the gate reads the markdown straight from disk and the dist/*.d.ts it compiles against is untouched — so no rebuild was needed.

Leg 1 (revert theming.md only, keep its ledger removal). Predicted exit 1; exactly 29 diagnostics all on that page; fragments 94 → 84; blocks-to-compile 147 → 157; NOTE printed; direction MORE; TS2353 on the corporateTheme literal and TS2304 'Theme' on the brand block. Observed exit 1, 29 diagnostics all on that page, Covered blocks: 241 — 157 to compile, 84 declared fragment(s)., Syntax phase: 2 block(s) failed to parse, NOTE printed, TS2353: … 'primary-foreground' does not exist in type 'ColorPalette' and TS2304: Cannot find name 'Theme'. Match including direction.

Leg 2 (revert all three pages). Predicted exit 1; exactly 81 split 25 / 27 / 29 per page; fragments 94 → 68; blocks-to-compile 147 → 173; covered blocks 241 unchanged; NOTE printed; direction MORE. Observed exit 1, 81 diagnostics split exactly 25 plugin-development / 27 schema-rendering / 29 theming — matching the baseline to the unit and per pageCovered blocks: 241 — 173 to compile, 68 declared fragment(s)., Syntax phase: 4 block(s) failed to parse, NOTE printed. Match including direction.

A restore leg failed the first time round, and is reported rather than quietly re-run.git checkout origin/main -- PATH writes the index as well as the worktree, so the trap's git checkout -- PATH restored from the polluted index and left the mutation on disk — reporting success while changing nothing. It was caught by the post-leg git status, not by the trap. Both legs were then re-run with git checkout HEAD -- PATH, and both reproduced their first run byte-identically (diff -q clean on both outputs). Restore verified after each: git status clean, git diff HEAD empty, 26 markers back on disk (9 / 7 / 10), gate exit 0 with 147 of 147 block(s) judged, 0 failed. Nothing was lost — the work was committed before reverse verification began.

Zone 2 assumptions — both re-measured, both held

Generated by Claude Code

Walk `guide/plugin-development`, `guide/schema-rendering` and `guide/theming`
off `UNGATED_DOCS`, clearing 81 diagnostics (25 / 27 / 29). The ledger goes
49 -> 46 entries and the covered set 173 -> 176; `guide/layout` and
`guide/component-registry` are the two that remain.
38 blocks come under the gate: 26 declared fragments and 12 that compile, of
which 7 already compiled untouched and 5 were edited to. Only the two honest
routes were used.
Four genuine documented-API defects were fixed rather than declared away:
- `guide/theming`'s three `Theme` objects were annotated `Theme` while the
annotation itself errored, so TypeScript never excess-checked the literals.
With it resolving, the `brand` palette had ten of fourteen `colors` keys off
`ColorPalette` -- `"primary-foreground"`, `foreground`, `muted`, `ring`,
`destructive` and the other `*-foreground` pairs are Shadcn CSS VARIABLE
names, not palette keys -- plus `radius` and `fonts`, neither a `Theme` key,
and no `label`, which is required. `generateColorVars` iterates
`COLOR_TO_CSS_MAP`, so every one of those was dropped in silence at runtime.
Routed through the two doors that do work: real palette keys, each annotated
with the variable it emits, and `customVars` for the rest.
- `guide/plugin-development`'s Vitest example asserted `toBeInTheDocument()`
with no `@testing-library/jest-dom` import.
- `guide/schema-rendering`'s first example set `body: { /* ... */ }`, which is
not a `SchemaNode`.
- the same page's restated `BaseSchema` named `CSSProperties` from nowhere.
Gate strictness is unmoved: everything from the `Fence scanning` banner to EOF
is byte-identical to `main` (475 lines, same sha), as are `DOC_EXTENSIONS`,
`TS_FENCE_LANGUAGES`, `FRAGMENT_MARKER`, `MIN_REASON_LENGTH` and
`COMPILER_OPTIONS`. `--build-filter` is unchanged at 20 filters / 33 turbo
build tasks, both sets identical package-by-package.
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