Skip to content

tooling(skills): check-doc-json-fences gains a skills/objectui/** leg — the strict authoring face judges the published guides, 8 deliberate counter-examples declared (objectui#12204) - #12221

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-12204-doc-json-skills-leg
Oct 12, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/issue-12204-doc-json-skills-leg

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #12204
Clause-②: no

What this PR does

scripts/check-doc-json-fences.mjs gains a fourth SCAN_SURFACE leg: every .md page under skills/objectui/ (16 pages, 70 json/jsonc fences on this branch), anchor skills/objectui/rules/protocol.md. The strict authoring face (StrictAnyComponentSchema, read from the built @object-ui/types ./zod entry — the face objectui validate uses) now judges the node documents a customer's agent copies from the published guides. The maintainer's ruling: 「B2:扩 doc-json 门禁一条腿(推荐)」 — option B of objectui#12135's 速读终稿.

Untouched, as ruled: scripts/check-skill-examples.mjs, its MARKER (os:check), its MARKED_FLOOR (70 json), every os:check marker line, the three existing legs, the RESOLUTION / REFUSES / ACCEPTS controls, the face resolution, every fence's content. No new gate; no workflow change — doc-snippet-types.yml already runs check:doc-json on pull requests after the filtered build (read; the existing wiring test pins it).

The adjacency conflict, measured, and the one rule added

Every json/jsonc fence under skills/objectui/ carries the os:check HTML-comment line DIRECTLY above it (census on BASE 54159d3: 70 of 70 fences, none inside a blockquote), and check-skill-examples.mjs requires exactly that adjacency (its header: 「Marker ADJACENCY is strict, and an orphan is a failure」). This gate's declaration must also be the nearest line above the fence. Only one line can be directly above.

Measured on BASE with scanJsonFences over a fixture — declaration line, then the os:check line, then the fence: attached=false consumed=[false]. The declaration dangled and the fence stayed undeclared; a page could not carry both gates' lines above one fence.

The rule added, inside this gate only: when the line directly above a json/jsonc fence is the os:check opt-in line at the fence's quote depth, the attachment walk steps over that ONE line and reads the line directly above it — three contiguous lines at one depth. Nothing else is stepped over on that path: a blank line, prose, a second opt-in line, an opt-in line that is not itself directly above the fence, or a declaration at another quote depth all leave the declaration dangling (and the fence refused). The opt-in spelling lives in this gate as SKILL_OPT_IN_LINE, spelled rather than imported — an import would couple this gate's attachment rule to the sibling's module and its typescript import; the test file pins it equal to check-skill-examples.mjs's MARKER, so a drift is a red test rather than a silent detachment of every declaration under the bundle. check-skill-examples.mjs is not touched.

Same fixture after the rule: the trio attaches (attached=true consumed=[true], also inside a blockquote at one depth); every other separation still reads attached=false consumed=[false].

The deliberate counter-examples — the gate's own output decided

Leg added, no declaration yet — pnpm check:doc-json exit 1:

❌  JSON doc fences: 8 finding(s) — the strict authoring face is the face `objectui validate` judges with.
  skills/objectui/guides/schema-expressions.md:33 card · :45 text · :424 list · :548 text · :554 text · :611 text
  skills/objectui/rules/protocol.md:120 card · :173 data-table
scan surface: … · every .md page under skills/objectui/ (16 page(s)) — 240 page(s), 322 json/jsonc fence(s)
judged node documents: 252 — 238 accepted, 6 declared fragment(s) the face refuses as declared, 8 refused
not judged: 0 not JSON · 3 not an object · 55 without a string `type` · 12 with a `type` no node schema declares

The same 8 the card predicted, all deliberate. The leg's own buckets — 70 fences, 48 node documents, 18 without type, 3 not an object, 1 unresolved type (module, in guides/plugin-development.md) — equal PR objectui#12138's measurement. The keyword stays fragment: the gate's header already names 「a deliberately refused example that shows the error」 as a kind of fragment, so no sibling keyword was minted — one keyword, the reason says the kind.

Each gets one declaration line in the gate's existing HTML-comment spelling, directly above the os:check line. Sample, rules/protocol.md, the WRONG card:

  • Before — three lines: the bold lead-in **❌ WRONG — renders an empty card:**, the os:check HTML-comment line, then the fence.
  • After — four lines: the lead-in; an HTML-comment line reading doc-json: fragment — deliberate counter-example: a title parked under props never reaches the card renderer, and props is no declared key; the os:check line; then the fence.

(HTML-comment lines are spelled in words in this body because the sanitizer eats tag-shaped text.) Every reason says what the example deliberately shows; none claims a check (the gate applies VERIFICATION_CLAIM; the shortest reason is 108 characters against the 12 minimum); none cites an issue number, the bundle's rule.

After the eight declarations — pnpm check:doc-json exit 0:

judged node documents: 252 — 238 accepted, 14 declared fragment(s) the face refuses as declared, 0 refused
controls: RESOLUTION, REFUSES, ACCEPTS hold over 205 node type(s); anchors content/docs/blocks/forms.mdx read, packages/plugin-dashboard/README.md read, README.md read, skills/objectui/rules/protocol.md read
✅  Every judged JSON node document on the scan surface passes the strict authoring face.

Baseline on BASE (three legs): 224 pages, 252 fences, 204 judged, 198 accepted, 6 declared, 0 refused, exit 0.

Sibling gate, unchanged

node scripts/check-skill-examples.mjs on BASE and after: Semantic phase: 18 of 18 ts fence(s) judged, 0 failed. · JSON phase: 70 fence(s) parsed, 0 failed. · Every marked skill example holds up against the built types. Its --self-test: 60 cases pass, before and after.

Line budget — skills/objectui/**, the PM's ceiling of +8

file before after
skills/objectui/guides/schema-expressions.md 640 646
skills/objectui/rules/protocol.md 375 377
bundle, every .md under skills/objectui/ 4815 4823

+8 exactly: the eight declaration lines and nothing else.

Tests and gates — final commit 8ebcd56

  • pnpm exec vitest run scripts/__tests__/check-doc-json-fences.test.ts scripts/__tests__/check-skill-examples.test.ts, under the shared verify lock: Test Files 2 passed (2) · Tests 158 passed (158). New pins: the scanner's three-line step-over in both directions (attached; dangling for a blank line, prose, a second opt-in line, a displaced opt-in line, another depth, a non-json fence); the opt-in spelling equal to the sibling's MARKER; RED for an undeclared refused fence under skills/objectui/, named at its line; GREEN for a declared one through the opt-in line; dangling plus refused for every other separation; stale through the opt-in line; the leg walks .md under skills/objectui/ only, last, in sorted order, and no other skills tree; the skills anchor is on the leg and owed; the real bundle's declared pages orphan none of the sibling's opt-in lines (scanSkillFences). The existing CLI-door parity pin (validateAuthoredDocument) now runs over the corpus with the leg, and the it.each(SURFACE_ANCHORS) pin covers the skills anchor.
  • Ablation after the commit, through the objectstack checkout's scripts/ablation-replace.mjs (anchor hit 1→0 and marker 0→1 on disk, restored to the HEAD blob with git diff HEAD empty): with the one-line step-over disabled, the test file reds 4 of 45 — the step-over pin, the GREEN declaration-through-opt-in pin, the stale-through-opt-in pin, and the real-bundle orphan pin's non-vacuity guard — and check:doc-json exits 1 with 16 findings: 8 dangling declarations plus the same 8 refused.
  • pnpm type-check:scripts exit 0; --listFiles includes the test file.
  • node scripts/check-skills-paths.mjs ✅ 89/90 resolve, 1 baselined · node scripts/check-skill-eval-tokens.mjs exit 0 · node scripts/check-control-bytes.mjs ✅ 8459 tracked files · node scripts/check-shell-escape-residue.mjs ✅ · node scripts/check-new-cross-file-line-citations.mjs 0 new · node scripts/check-changeset-presence.mjs ✅ no changeset owed · changeset guards (claims / fixed / no-major / overwrite) ✅.
  • Repo-wide pnpm lint and the rest of the farm: CI's run, not measured here.

Also touched

content/docs/guide/ci-cd-pipeline.md — the page that inventories the gates said 「Three legs」 and listed skills/** as not read; it now says four and names the declaration shape. Not governed and published by no package; the existing wiring test pins only the script name and path there.

Acceptance notes

  • skills/objectui/guides/plugin-development.md carries one jsonc fence whose type is module, which no node schema declares; the gate counts it in the unresolved bucket and judges nothing — it is a plugin-manifest example, not a node document. Observation only, no card.
  • .changeset/12204-doc-json-skills-leg.md is an empty-frontmatter changeset: skills/**, scripts/ and content/docs/ sit in no package's files[]. objectui has no skip-changeset label; none was minted.

维护者速读(草稿)

改了什么。 门禁 check-doc-json-fences(pnpm check:doc-json)多扫一条腿:skills/objectui/ 下全部 .md 页面里的 json/jsonc 节点文档,用 objectui validate 同一张严格面判定。这些示例是客户的 agent 通过 npx skills add 装进自己仓库后照抄的样板。为了与既有的 os:check 标记共存,门禁学会越过紧贴围栏上方的那一行 os:check、往上再读一行声明;八个故意写错的反例各加一行声明,写明它故意展示什么。围栏内容、os:check 标记、check-skill-examples 门禁本身一字未动。

为什么改。 维护者 2026-10-12 点名「B2:扩 doc-json 门禁一条腿(推荐)」。此前这 70 个围栏只被要求「能解析」,不被要求「合法」:客户 agent 照抄一个不合规的键,objectui validate 会拒,而发布面上没有任何东西提前拦住。现在同一张严格面在发布前就判。

风险与代价(含回滚)。 代价是 skills/objectui/** 净增 8 行(4815 → 4823),全是渲染为空的 HTML 注释,读者看不见。风险:今后在这两份指南里新增一个故意写错的例子,门禁会红,作者需要加一行声明 —— 这正是门禁的用途;门禁对每条声明逐次重判,例子一旦变合法,声明即报过期,只减不增。回滚 = revert 本 PR 的一个 commit;不涉及发版、不动任何包。

席位意见。 (留空,席位定稿)

你要做的。 本 PR 命中受管面 skills/**,停在 draft 等一条获授权的 APPROVED review;批准后由认领席翻 ready、入队。你只需判断:八行声明的措辞是否准确描述了各反例故意展示的错误(见上方 sample 与 diff)。


Generated by Claude Code

…, and the 8 deliberate counter-examples carry its declaration (objectui#12204)

The strict authoring face now judges the json/jsonc node documents of the
published skill bundle: a fourth SCAN_SURFACE leg walks every .md page under
skills/objectui/ (anchor rules/protocol.md). Every such fence carries
check-skill-examples' opt-in line directly above it, and that gate requires
it exactly there, so this gate's declaration lookup steps over exactly that
one line (declaration, opt-in line, fence — three contiguous lines at one
quote depth; anything else leaves the declaration dangling). The opt-in
spelling is spelled in this gate and pinned equal to the sibling's in the
test file, never imported.

Measured on the tree before the rule: the three-line shape did not attach.
With the leg added and no declaration: 8 refused, all deliberate
counter-examples (6 in guides/schema-expressions.md, 2 in rules/protocol.md).
Each now carries one doc-json: fragment line whose reason says what the
example deliberately shows; green after, 14 declared, 0 refused.
check-skill-examples unchanged at 18 ts / 70 json marked, 0 failed. No
fence content, os:check marker or check-skill-examples rule changes.
skills/objectui line budget: +8 exactly (bundle 4815 -> 4823).

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CinRQcE6T8SvMbhH8D3NhS
@github-actions github-actions Bot added documentation Improvements or additions to documentation tests labels Oct 12, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 8ebcd56a4318d8064d258bfe6c78adc472ba7de0
Local-runs: none

Scope: the governed rule-text face — skills/objectui/guides/schema-expressions.md (+6) and skills/objectui/rules/protocol.md (+2): eight doc-json: fragment declaration lines, nothing else in the published bundle; the gate scripts/check-doc-json-fences.mjs and its test ride the same PR. Inputs: card objectui#12204 (body, the claim 6121363447, the dev's report 6121846322), PR objectui#12221 (body, the 6-file list, the net diff against main), the check-runs on this head. Read 2026-10-12T09:55Z.

① Derived judgments

  • The eight declarations, read one by one: each sits directly above the os:check line that sits directly above its fence, and each reason says what the counter-example deliberately shows (a title or content parked under props; value retired from text; list with no children slot; an object literal inside an expression; invented keys) — no reason claims the fence was checked. The fence bodies and every os:check line are byte-unchanged (+8 lines, the budget exactly; bundle 4815 → 4823). RIGHT: the counter-examples stay honestly labelled and the published teaching text gains no claim.
  • The gate: a fourth SCAN_SURFACE leg (SKILLS_ROOT = 'skills/objectui', .md pages in a stable walk order, anchor rules/protocol.md); the declaration lookup steps over exactly one SKILL_OPT_IN_LINE (<!-- os:check -->, spelled in this gate and pinned equal to check-skill-examples' MARKER in the test, never imported) at the fence's own quote depth — any other line between leaves the declaration dangling. Measured: with the leg and no declarations the gate refused exactly the 8 counter-examples; with them, 252 judged, 238 accepted, 14 declared, 0 refused. check-skill-examples.mjs, its marker and floor untouched; that gate unchanged at 18 ts / 70 json, 0 failed. RIGHT: the one authority (the strict face the CLI imports) now reads the published guides; the two gates stay uncoupled.
  • No accept set and no public surface changes: Clause-②: no is correct.

② Semver level

skills/**, scripts/ and content/docs/ sit in no package's files[]; the empty-frontmatter changeset .changeset/12204-doc-json-skills-leg.md is this repository's "no release" declaration. RIGHT.

③ Boundary flags

  • Deviation declared and accepted: a sixth file, content/docs/guide/ci-cd-pipeline.md (+11/−7), the gate's own inventory page, which said "three legs" and listed skills/** as not read — not governed, published by no package, and leaving it stale would make the docs lie about the gate.
  • Ablation (committed state, on-disk proof, restore proven): the step-over disabled reds 4 of 45 test rows and the gate exits 1 with 16 findings (8 dangling + 8 refused) — the rule is load-bearing both ways. One pre-existing leg-order pin updated to see the fourth, empty leg on fixture trees.
  • Noted, not filed (carrier none): one jsonc fence in guides/plugin-development.md has type: 'module', which no node schema declares — the gate's unresolved bucket, a plugin-manifest example.
  • Check-runs on this head at review time: 25 success / 3 skipped / 13 in progress, 0 failed; mergeable_state reads behind (the base moved) — the landing merges main into the head first.

Implemented-by: claude/issue-12204-doc-json-skills-leg
Reviewed-by: session_01CinRQcE6T8SvMbhH8D3NhS

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)· PR objectui#12221 · objectui#12204

席位 1(session_01CinRQcE6T8SvMbhH8D3NhS,huangyiirene)对照自己读的 diff(6 文件 +270/−44)校正 dev 草稿后定稿 · 2026-10-12T09:57Z。

改了什么:check-doc-json-fences 门禁多走一条腿——对外发布的 skills/objectui 技能包里全部 16 页 .md、70 个 json/jsonc 围栏,用 objectui validate 同一张严格面判「标成正例的节点文档是否真合法」。8 个刻意写的反例各加一行既有的 doc-json: fragment 声明(写明它故意展示什么错),技能包净 +8 行,围栏正文一字未动;os:check 标记与 70 条解析下限不动,check-skill-examples 读数不变(18 ts / 70 json,0 失败)。顺带把门禁自己的说明页(content/docs/guide/ci-cd-pipeline.md,原写「三条腿、skills 不读」)改成四条腿。

为什么改:你今天点名的 B2。上周那条标 ✅ 却被校验器拒收的示例是靠人碰巧发现的;schema 一收紧,示例就会静默过期——现在是门禁在每个 PR 上替你盯着。

风险与代价(含回滚):零运行时影响,只多一条门禁腿与 8 行声明。一个必须先解的机制冲突已实测解决:技能包里每个围栏上方本就紧贴着 os:check 标记行,而声明也要求紧贴——改法是让 doc-json 门禁学会越过恰好一行同类标记(多一行、少一行都判悬空,测试两面钉死),check-skill-examples 不动。回滚 = revert 本 PR;以后 schema 收紧时技能示例会在同一 PR 变红,这是预期行为。

席位意见:ACCEPT。契约复核(达档、在席)PASS 已贴本 PR;消融实验证明越过规则是承重的(关掉它 → 4 条测试红、门禁 16 条发现)。CI 复核时 25 绿 / 3 跳过 / 13 在跑、0 红;base 已前移,落地前席位先合一次 main。

你要做的:同意即给一个 APPROVED review;落地由席位先合 main 再走队列。这是你今天三条裁决里最后一张。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 12, 2026 10:08
@os-zhuang
os-zhuang enabled auto-merge October 12, 2026 10:08
…the markdown-test-inputs ledger

`Test (shard 1/8)` on PR objectui#12221 (head 8ebcd56) failed one test,
`scripts/__tests__/markdown-test-inputs.test.ts > the derived class > every
candidate the scanner finds has been adjudicated, and every entry exists`:
`auditTree` returned two `unadjudicated-document` findings for
`scripts/__tests__/check-doc-json-fences.test.ts` -- "resolves
`skills/objectui/SKILL.md`" and "resolves `skills/objectui/rules/protocol.md`",
each "in neither `reads` nor `notRead`". That PR taught check-doc-json-fences
a fourth SCAN_SURFACE leg (every `.md` under `skills/objectui/`, anchor
`rules/protocol.md`) while the ledger entry for the gate's agreement test
still described three legs.

The entry's `reads` gains `skills/objectui/**` in the ledger's own tree
spelling (`matchesEntry` matches any markdown under the prefix, as the
`content/docs/**` and `packages/**` legs already do), and the entry's comment
names the change that added it. No `notRead`: the test's real-corpus walk
reads the tree, and the two pages the scanner resolves by name are inside it.

Measured on this worktree with
`pnpm exec vitest run scripts/__tests__/markdown-test-inputs.test.ts`:
at 8ebcd56 exit 1 (1 failed | 24 passed, the two findings above); with this
commit exit 0 (25 passed). Also green: check-doc-json-fences.test.ts
(45 passed), check-pending-changeset-literals.test.ts (15 passed, it imports
the ledger), `pnpm type-check:scripts` exit 0.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CinRQcE6T8SvMbhH8D3NhS
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 8167d5e47
Local-runs: none

Scope: the same governed rule-text face as the record on 8ebcd56a4318d8064d258bfe6c78adc472ba7de0 (comment 6121916632): skills/objectui/guides/schema-expressions.md (+6) and skills/objectui/rules/protocol.md (+2), eight doc-json: fragment declaration lines. This head is that head plus one commit, the seat's REWORK round 1 (the markdown-test-inputs ledger); one record, one head, so the verdict is re-rendered here. Inputs: compare/8ebcd56a4...8167d5e read by the seat 2026-10-12T10:33Z (1 commit, 1 file, scripts/markdown-test-inputs.mjs +6/−2, the patch read in full); the PR's state; the check-runs on this head.

① Derived judgments

  • The rework touched none of the PR's governed files: the one commit changes one ADJUDICATED entry (the test scripts/__tests__/check-doc-json-fences.test.ts gains skills/objectui/** in reads, the entry's own glob style, no notRead) and its comment, four lines in the entry's voice, stating the anchor as the gate spells it (rules/protocol.md). The eight declarations, the fence bodies, every os:check line and the gate itself are byte-identical to the reviewed head. Every judgment of the previous record stands unchanged; Clause-②: no is correct.
  • The fix is the ledger's by design: the ledger exists so that a test's markdown read set is declared (its header, the objectui#8857 class); the PR taught the gate's agreement test a fourth tree, so the declaration follows. RIGHT — the test, the gate and the skills were not bent to the ledger.

② Semver level

Unchanged: scripts/** ships in no package; the PR's empty-frontmatter changeset covers this commit (check-changeset-presence at 8167d5e: 7 files, 0 published, none owed — the dev's run, verdict line quoted in the report).

③ Boundary flags

  • os-zhuang APPROVED on 8ebcd56a4 (2026-10-12T10:08Z), flipped the PR ready and enabled auto-merge; the main ruleset reads dismiss_stale_reviews_on_push: false and require_last_push_approval: false, so the approval stands on this head. The seat cleared needs-user-decision (2026-10-12T10:17Z).
  • Check-runs on this head at review time: 27 success / 3 skipped / 11 in progress, 0 failed; Test (shard 1/8) — the one red on the previous head — in progress. The dev reproduced that red locally at 8ebcd56a4 (1 failed, the two CI findings) and the same command green at 8167d5e (25 passed); the gate's own test 45/45; the ledger's other importer 15/15.
  • mergeable_state reads behind; the landing is os-zhuang's auto-merge through the merge queue, which builds against main under the strict up-to-date policy — the seat does not move the head again.

Implemented-by: claude/issue-12204-doc-json-skills-leg
Reviewed-by: session_01CinRQcE6T8SvMbhH8D3NhS

VERDICT: PASS


Generated by Claude Code

@os-zhuang
os-zhuang added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit adfbe3b Oct 12, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-12204-doc-json-skills-leg branch October 12, 2026 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation tests

Projects

None yet

3 participants