…ript block (objectstack-ai#6135) (objectstack-ai#6144)
* feat(tooling): pin the fence vocabulary so no spelling hides a TypeScript block
`check-doc-snippet-types` compiles `ts` / `tsx` / `typescript` fences and
nothing else, so a TypeScript block fenced any other way is invisible to it —
objectui#5867, whose remediation lane collects its population from ```plaintext
fences only. `plaintext` is not the only spelling of an unhighlighted fence:
objectui#6135 measured a ```text block opening `interface FileUploadSchema {`
sitting outside the gate AND outside the lane that exists to close it.
Adds `scripts/check-doc-fence-languages.mjs`, which reads block BODIES with
objectstack-ai#5867's own binding triage classifier rather than pinning a list of languages —
so `txt`, `console`, `raw` or a bare fence with no info string at all cannot
reopen the gap. Two failure modes are reported apart, because only the first can
be auto-classified: a KNOWN unhighlighted spelling (objectstack-ai#5867's population,
mechanical remedy, baselineable) and a spelling nobody has thought of (a human's
call, never baselined; zero in the tree today).
`KNOWN_UNHIGHLIGHTED_TS_FENCES` is objectstack-ai#5867's remaining population per file — 92
files, 128 blocks — shrink-only in the shape objectui#6133 landed for
`KNOWN_HAND_TYPED_GUARDS`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
* fix(tooling): classify the new Doc Fence Language check in the Dependabot gate
`scripts/dependabot-merge-gate.mjs` partitions every check a pull request
produces into required and optional buckets, and an unclassified blocking check
is one the gate would let a Dependabot merge past. `doc-fence-languages.yml`
carries no trigger-level path filter, so every pull request produces it.
Found by `scripts/__tests__/dependabot-merge-gate.test.ts`, which is the pin
that exists for exactly this.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
* fix(tooling): lower the fence baseline for objectstack-ai#5867 batch 4 and objectstack-ai#6137
`check:doc-fences` went red on its FIRST CI run, reporting nine of its own
entries as STALE — `block-schema.mdx` baselined at 10 now carries 0, and the same
for `fields/auto-number`, `fields/object` and six `plugins/` pages. Nothing was
wrong with the tree: objectstack-ai#6136 (objectstack-ai#5867 batch 4) and objectstack-ai#6137 merged while this branch was
open and re-fenced 23 blocks across those 9 files.
That is the shrink-only baseline doing exactly what it is for, unstaged, on its
first run, with the remedy printed. The remedy is followed literally: the nine
zero lines are deleted and nothing else moves. The population is RE-DERIVED on
the merged base rather than subtracted by hand — 105 blocks / 83 files, and the
diff against the old map is nine deletions with no line added and no number
raised.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
---------
Co-authored-by: Claude <noreply@anthropic.com>
Part of #5867
Batch 4 of N, taking the two groups batch 3's handback named as the only unblocked ones:
pluginsandblocks. All readings below are at branch head4430ac30d, and every heavy run went through the container's shared verify lock.What this changes
19 fences re-fenced from
```plaintextto```tsacross 7 whole pages —content/docs/blocks/block-schema.mdx(10) and sixcontent/docs/plugins/*.mdx(9: charts 1, editor 1, form 2, grid 2, markdown 1, view 2) — socheck-doc-snippet-typescompiles them.Triage's classifier is the one applied, unwidened: a plaintext block whose first line starts with
import/export/interface/type X =/const x: Tis code. Genuinely-prose blocks on the same pages are left alone — 12 of them survive across the batch pages, includingblock-schema.mdx'sslotContentillustration, which opens with a comment and would not parse.No
FRAGMENT_MARKERwas declared. The gate,UNGATED_DOCSand the ledger are untouched;scripts/is not in the diff.The defects compiling them found, all fixed rather than marked
All on
block-schema.mdx; the six plugins pages compiled untouched, as batch 2's probe 2 predicted.BlockSlot.defaultContentis typedSchemaNode, never importedSchemaNodeBlockSchema, never importedBlockSchemaBlockLibrarySchema, never importedBlockLibrarySchemaheroBlock, defined in a different block on the pagedeclare const heroBlock: BlockSchemacardBlock, defined in a different block on the pagedeclare const cardBlock: BlockSchemamyBlock, the reader's own valuedeclare const myBlock: unknowndeclare constis this repo's existing idiom for a value a snippet does not define — seven prior uses acrosscomponents/basic/icon.mdx,guide/notifications.mdandguide/troubleshooting.md.The defect that only appeared once the first fix landed
Resolving
BlockLibrarySchemaun-masked one the unresolved name had been suppressing. Both Marketplace Example listings carried:While
BlockLibrarySchemawasTS2304, its annotation degraded toanyand the member was never checked. With the import in place the gate reddened it asTS2741: Property 'type' is missing in type '{}' but required in type 'BlockSchema'—BlockLibraryItem.schemais a requiredBlockSchema, and an empty object is not one. Both now carry a real minimal block schema naming the listing they belong to. This is the #5044 class exactly: a block teaching a shape the types reject, under a gate that reported the page as covered.Verification
Gate, before and after, on the built tree:
133e2ea1e)4430ac30d)The gate's own verdict line after:
Every covered documentation snippet compiles against the built types.The--build-filterclosure is byte-identical before and after.Other gates, exit codes captured before any pipe, quoting each gate's own verdict line:
check:doc-typesexit=0 —Every documented component type is registered.docs:check-linksexit=0 —Links are valid across 15 scan roots.check:control-bytesexit=0 —OK (scanned 5081 tracked text file(s); skipped 85 binary)Vitest, from the repo root:
check-doc-snippet-types·check-doc-component-types·check-doc-links·check-changeset-presence—Test Files 4 passed (4), Tests 185 passed (185).Lint, narrowed and the narrowing measured: the diff is 7
.mdxfiles plus one.changeset/*.md. ESLint's own configuration reports every one of them asFile ignored because no matching configuration was supplied—eslint.config.jsmatches only**/*.{ts,tsx}, and type-aware linting is not enabled, so this diff cannot move the verdict on any untouched file. File count read from--format json: 2 probed, 2 ignored, 0 errors.Render check
pnpm site:buildgreen. The reader-visible half is measured against a rebuilt baseline rather than asserted: the site was rebuilt withcontent/docsreverted to the pre-batch commit, counted, then restored under a trap.block-schema.mdxrenders as literal<pre>blocks, so its count is exact:Ten blocks moved from unstyled to tokenised — the page's whole share of the batch — and the one surviving prose block still carries zero token spans.
The six plugins pages render most blocks through the RSC flight payload, so the same before/after counter was run on both representations, reading keyword spans:
Build note, unrelated to this diff and identical to batches 1–3: the site build needs
@object-ui/plugin-ganttand@object-ui/plugin-mapbuilt first, both outside the gate's--build-filterclosure.Scope selection was measured, not eyeballed
All 22 candidate blocks across all 8 candidate files were re-fenced in a throwaway probe, the mutation proved on disk first (per-file plaintext counts dropped to their expected values;
git diff --statshowed 22 insertions / 22 deletions), the tree rebuilt, the gate run, and the tree restored undertrap … EXIT INT TERMusinggit checkout HEAD --on the two directories, never the bare form. The probe readCovered blocks: 339 — 228 to compile(206 + 22, so every re-fence landed in the population) and named exactly one file this batch then excluded.Excluded, with a measured reason
content/docs/plugins/plugin-dashboard.mdx— 3 blocks, whole file left as plaintext. Its TypeScript Support block fails the syntax phase (TS1109onwidgets: [...], an English ellipsis at expression position), which #6122 already records. Measuring behind that failure found more than #6122 knew: the block also importsDashboardSchemaandMetricCardSchema, and neither name exists anywhere — not on@object-ui/plugin-dashboard's built export surface, not in@object-ui/types, not declared in anypackages/*/src. The syntax failure had been masking both. Reported on #6122 rather than filed fresh, because that card already owns this file's defect record and is in flight; the comment there also points at #5015 / PR #5069, which settled the identical fabricated-name defect in this package's README and pins the correct form, so the file needs no new ruling.The 7 blocks in 6
UNGATED_DOCSpages were not re-fenced and should not be: those documents are not compiled at all, so re-fencing moves blocks-to-compile by zero. Left alone deliberately, not overlooked.Population, re-derived
146 blocks / 102 files on
origin/main133e2ea1e, reproducing batch 3's reading exactly. Widening the derivation's fence-language set totextandplainmoves it to 147/103 and surfaces one block the whole lane has been blind to — filed as #6135, unassigned, with the file it names blocked on #6122.Remainder after this batch: 110 blocks / 85 files, handed back on the card in batch 3's shape.
Generated by Claude Code