You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(gate): apps/console/docs/** is outside every documentation gate's scan surface — the console's operator guides are checked by nothing but check:control-bytes #6600
Measured on 2026-08-27 at da545f1a6 while rewriting apps/console/docs/error-tracking.md for #6599. Recording only; not fixed in that PR (out of scope).
What was measured
The three documentation gates all root their walk at content/docs (plus, for one, packages/<name>/README.md). None of them descends into apps/:
const DOCS_ROOT = 'content/docs' — its own comment says it "walks content/docs and nothing" else
Consequence for apps/console/docs/** (5 guides today): the only gate whose surface actually contains them is check:control-bytes, which enumerates git ls-files and therefore covers every tracked text file — i.e. they are checked for control bytes and for nothing else. eslint cannot judge them either: every files: glob in eslint.config.js is **/*.{ts,tsx}, so markdown is outside eslint entirely.
Why it is worth recording
This is the failure mode where a gate suite reports green over a file it never opened. #6599 is a concrete instance of what accumulates in that blind spot: apps/console/docs/error-tracking.md had drifted far enough that following it literally rebuilt the ungated telemetry init #5522 removed, and it also carried a fabricated CSP section plus two env vars (VITE_ENVIRONMENT, VITE_ERROR_ENDPOINT) with zero read sites anywhere in the tree. Nothing mechanical could have noticed any of it.
None of them covers "the apps/*/docs/** tree is not in any scan surface".
Not a recommendation to switch the gates on blindly
Extending DOCS_ROOT would pull these guides into check:doc-types / check:doc-snippets, which type-check snippets and validate type literals — the console guides are operator/deployment prose, and the honest first step is measuring how many blocks would newly be judged and whether the ratchets can absorb them, not flipping the root and taking whatever falls out.
Finding round: graded, promoted to pm:queue, finding shed. Routed domain:devx — documentation gates are the engineering stream of the objectui three-way split, which crosses to the devx lane rather than staying with domain:ui. Type Task: no declaration is violated — check:doc-types' own comment honestly says it "walks content/docs and nothing else". The gates are not lying; they are simply not pointed at this tree.
⭐ What lifts this above a coverage-gap note is #6599's evidence of what actually accumulated in the blind spot.apps/console/docs/error-tracking.md had drifted far enough that following it literally rebuilds the ungated telemetry init that #5522 deliberately removed — plus a fabricated CSP section and two env vars (VITE_ENVIRONMENT, VITE_ERROR_ENDPOINT) with zero read sites anywhere in the tree. Documentation that instructs an operator to re-introduce something the platform removed on purpose is not stale prose; it is an active hazard, and nothing mechanical could have noticed any of it. Five guides sit in that tree today.
Scope — measure before flipping anything, and that ordering is the deliverable. The card is explicitly not recommending switching the gates on blindly and this seat endorses that:
Point the measurement (⛔ not the gates) at apps/*/docs/** and count how many blocks would newly be judged by check:doc-types and check:doc-snippets, and what verdicts they would get.
Report whether the ratchets can absorb that, and propose the root change on the strength of the number.
⛔ Do not extend DOCS_ROOT and take whatever falls out. These are operator/deployment prose, not API guides — they will contain shell and config blocks that the snippet type-checker was never designed to judge, and a flood of new failures gets the extension reverted rather than fixed.
A measurement plus a proposal with no gate change is a complete delivery for this card. Say so in the dispatch order.
⚠️ Worth naming for whoever plans this: both devx seats are currently vacant (objectui #10602 ⏳, objectstack #6023 🔴). This card is graded and queued regardless — grading is not conditional on a seat being staffed, and a queued card is exactly what a returning seat needs to find. But it will not move until one is filled, and it is now one of several devx-lane items queued this round (#12719, #12723, #12730, #12749). Flagged in this round's report.
Dedup confirmed as filed, and the boundaries are drawn correctly: #4148 (closed) is the nearest — same apps/**-unscanned shape but specific to check-doc-links.mjs; #5174 / #5106 (open) concern .md vs .mdx collection withincontent/docs; #5250 / #5867 (open) concern which fences inside already-covered files get read. ⛔ None covers "the apps/*/docs/** tree is in no scan surface at all."
Measured at da545f1a6; re-verify the three DOCS_ROOT constants at dispatch rather than inheriting the table.
Claim: PM loop round R40 (backfill after #6606 returned; batch=5)
Session: session_01BGMDbrVa8JjZcCQ7DWYH1b
Branch: claude/issue-6600-apps-docs-gate-surface
Worktree: objectui-issue-6600
Domain: domain:devx
File surface: measurement first — no gate change is owed by this card. If the measurement supports a change: scripts/check-doc-fence-languages.mjs, scripts/check-doc-snippet-types.mjs, scripts/check-doc-component-types.mjs (their DOCS_ROOT / scan-root logic and any UNGATED_DOCS-style exemption list) and their tests under scripts/__tests__/ (stop on breach; explain in the report). ⛔ No edits to apps/console/docs/** themselves (that is the ui lane's content; #6599 already rewrote one guide).
Container & model: M (measurement + proposal; a gate change only on the strength of the number), mode:subagent, model: opus. Tier is this seat's explicit decision (no dispatch-gates.mjs in objectui).
Clause-②: no
Serial constraints cleared: on origin/main64d624ded all three gates still root at content/docs (check-doc-component-types.mjs:214, check-doc-fence-languages.mjs:144, check-doc-snippet-types.mjs:301); the apps/*/docs/** population is now 3 files (apps/console/docs/UI_IMPROVEMENT_PROPOSAL.md, deployment.md, error-tracking.md), not the 5 the card measured — re-count. Recent churn on the gates: b83cd76a9 (#7100), ee851c32a (#6895). No in-flight PR in either lane touches these scripts; batch siblings (#6640 test infra · #6705 parity scanner · #6291 derivation gate · #7183 vitest dist project) are disjoint by construction. Adjacent open cards #5174 / #5106 / #5250 / #5867 concern collection or fences withincontent/docs — ⛔ not this card's surface.
Session: session_01BGMDbrVa8JjZcCQ7DWYH1b
Branch: claude/issue-6600-apps-docs-gate-surface (pushed empty at 64d624ded before any edit)
Worktree: objectui-issue-6600
File surface: measurement first — no gate change is owed. If the number supports one: scripts/check-doc-fence-languages.mjs, scripts/check-doc-snippet-types.mjs, scripts/check-doc-component-types.mjs and their suites under scripts/__tests__/. No edits to apps/console/docs/** (ui lane content). Measurement runs against instrumented COPIES of the gate scripts under the scratchpad, never a mutation of the tracked files.
Deliverable per the 2026-08-27 triage: per-file/per-gate table of blocks that would newly be judged plus their verdicts, ratchet-absorption verdict, and a proposal with the number attached.
{
"issue": 6600,
"status": "done",
"branch": "claude/issue-6600-apps-docs-gate-surface",
"pr": null,
"premise_still_valid": true,
"files_changed": [],
"summary": "Measurement-only delivery, exactly the shape the 2026-08-27 triage pre-authorized ('a measurement plus a proposal with no gate change is a complete delivery'). No gate was flipped and no tracked file changed; the worktree ends at 64d624ded with `git status --porcelain` empty. PM assumption (a) re-derived and CONFIRMED on 64d624ded: all three gates root at `content/docs` (check-doc-component-types.mjs:214, check-doc-fence-languages.mjs:144, check-doc-snippet-types.mjs:301); fences and snippets additionally walk `packages/NAME/README.md` — that is the card's sanitizer-stripped `packages//README.md` cell, read from the script as instructed. PM assumption (b) is FALSIFIED in the card's favour: the other two guides never existed. `git log --diff-filter=ADR -- apps/console/docs/` shows exactly three adds (1045cbd0f added deployment.md + error-tracking.md, 366775d42 added UI_IMPROVEMENT_PROPOSAL.md) and zero deletes or renames, and `git ls-tree -r da545f1a6 -- apps/console/docs` returns 3 files at the card's OWN measurement commit — so 'five guides' was a miscount at filing time, not attrition. The card's load-bearing claim (the tree is in no gate's scan surface but check:control-bytes) stands unchanged. THE HEADLINE NUMBER: extending the roots buys ZERO verified blocks. check:doc-types and check:doc-fences absorb the three files at zero cost but find nothing in them (0 `type:` literals, 0 hidden-TypeScript fences); check:doc-snippets would newly compile 14 blocks and 11 of them go RED, and the only absorbing move — two UNGATED_DOCS entries — means those 14 blocks are not compiled at all, so the extension would verify nothing while growing a ledger the script marks SHRINK-ONLY. A third structural fact decides the sequencing: scripts/__tests__/check-doc-fence-languages.test.ts asserts `expect(fenceDocuments(ROOT)).toEqual(snippetDocuments(ROOT))`, so the cheap gate cannot be extended without the expensive one. One real defect fell out of the measurement and was filed unassigned rather than fixed (apps/console/docs is the ui lane's content and outside this card's file surface): the guide teaches a `direction` prop on ResizablePanelGroup where the shipped component takes `orientation`.",
"measurement_table": {
"population": "3 files, derived not inherited — `git ls-files 'apps/*/docs/*'` on 64d624ded. Adjacent operator prose the same argument covers but this card does not: apps/console/README.md, apps/site/README.md. Wider unscanned markdown outside every doc gate: roughly 50 files — skills/objectui/** (18; the doc-types header DECLARES this exclusion), docs/adr (10), docs/audits (5), examples/*/README.md (5), packages/*/docs/** and packages/vscode-extension/*.md (5), .github/prompts (3). apps/*/docs/** is 3 of about 50.",
"per_file": [
{
"file": "apps/console/docs/UI_IMPROVEMENT_PROPOSAL.md",
"fenced_blocks": "12 (typescript x1, tsx x11)",
"check_doc_fences": "0 newly judged findings — every block is already fenced ts/tsx/typescript, so no hidden-TypeScript site and no KNOWN_UNHIGHLIGHTED_TS_FENCES entry",
"check_doc_types": "12 code blocks scanned, 0 `type:` literal sites, 0 key-table rows -> 0 findings",
"check_doc_snippets": "12 blocks newly COMPILED -> 9 RED / 3 green. 2 parse failures (:64 TS17008 JSX element 'div' has no corresponding closing tag; :185 TS1005 ';' expected) + 7 semantic failures (:52, :70, :97, :128, :143, :165, :179)"
},
{
"file": "apps/console/docs/deployment.md",
"fenced_blocks": "6 (unlabelled x3, nginx, caddyfile, json)",
"check_doc_fences": "0 findings",
"check_doc_types": "6 code blocks scanned, 0 `type:` sites -> 0 findings",
"check_doc_snippets": "0 ts/tsx blocks -> nothing compiled, green vacuously. NOTE: it also cannot be placed in UNGATED_DOCS — an entry holding no ts/tsx block fails as a stale entry"
},
{
"file": "apps/console/docs/error-tracking.md",
"fenced_blocks": "7 (unlabelled x2, bash x2, ts x2, yaml x1)",
"check_doc_fences": "0 findings",
"check_doc_types": "7 code blocks scanned, 0 `type:` sites -> 0 findings",
"check_doc_snippets": "2 blocks newly COMPILED -> 2 RED (:54 TS2304 Cannot find name 'RuntimeConfigPlugin' — the class IS real, at packages/app-shell/src/runtime-config.ts, the block just omits the import; :145 TS2304 for 'err' and 'user' — the `@object-ui/app-shell` import RESOLVED, so captureError/setSentryUser are real exports)"
}
],
"totals": {
"check_doc_fences": "0 newly judged findings across all 3 files; 25 fenced blocks seen, 0 classify as hidden TypeScript. UNION run (227 documents): declared files 80, blocks 90, unknown spellings 0, reconcile fresh=0 stale=0 -> GREEN, ratchet untouched",
"check_doc_types": "0 newly judged findings. UNION run: files 185 -> 188, codeBlocks 1069 -> 1094, typeSites 901 -> 901 (the three files contain no `type:` literal at all), findings 0, DOC_TYPE_EXEMPTIONS untouched, all 7 FLOORS clear (files 188>=100, codeBlocks 1094>=400, typeSites 901>=300, registryKeys 658>=300, keyTables 4>=2, keyTableRows 24>=12, keyTableKeys 45>=20)",
"check_doc_snippets": "14 blocks newly COMPILED, 11 RED / 3 green. 2 parse failures + 9 semantic failures carrying 65 diagnostics: TS2304 x62 (undeclared identifiers — these are excerpt fragments), TS7006 x2, TS2322 x1. The single TS2322 is the only diagnostic that is a defect in what the prose CLAIMS; filed as #7282. Baseline would move from '272 of 272 block(s) judged, 0 failed' to 286 judged, 11 failed"
}
},
"ratchet_absorption": {
"check_doc_fences": "ABSORBS AT ZERO COST — but cannot move alone. MEASURED: fence walk 224 == snippet walk 224 (deep-equal true today); extend the fence root alone and it is 227 vs 224, deep-equal FALSE; extend both and 227 vs 227, deep-equal true. scripts/__tests__/check-doc-fence-languages.test.ts asserts exactly that deep equality, so this gate is welded to check:doc-snippets and inherits its 11 red.",
"check_doc_types": "ABSORBS AT ZERO COST and is genuinely independent — no cross-gate walk pin exists for its collector (its tests drive scanDocs over fixture dirs and over repoRoot for its own non-vacuity floors only). Cost: 0 new findings, 0 new DOC_TYPE_EXEMPTIONS entries, every FLOOR still clear.",
"check_doc_snippets": "CANNOT ABSORB. 11 of 14 blocks red. The only move that makes it green without editing apps/console/docs/** is two UNGATED_DOCS entries (UI_IMPROVEMENT_PROPOSAL.md, error-tracking.md) — and the gate's own header says an ungated document 'is NOT compiled and NOT counted... exactly as they were before this gate existed'. deployment.md is the only one of the three that could be genuinely covered, and it holds zero ts/tsx blocks. NET VERIFIED COVERAGE GAIN FROM EXTENDING THIS GATE: ZERO BLOCKS, at a cost of +2 entries on a ledger the script marks SHRINK-ONLY."
},
"proposal": {
"recommendation": "Do NOT extend check:doc-fences or check:doc-snippets now — not because the number is large, but because in every configuration that is green the extension verifies zero blocks. Extending them and ungating the two TS-bearing guides would convert 'a gate suite reports green over a file it never opened' into 'a gate suite reports green over a file it declared it would not open' — the same blind spot with a signature on it, which is worse than the honest hole the card recorded. The correct ORDER is the reverse of the obvious one: the content is fixed first, the root moves second. Concretely: (1) the ui lane fixes #7282 and marks the 10 excerpt blocks with the gate's existing `doc-snippet: fragment` marker; (2) THEN both roots move together in one change, and the coverage is real. check:doc-types is separable and free today (0 red, 0 ratchet, all floors clear) but yields 0 findings on the current population, so it is a forward guard only and its extension is a scope question for the maintainer, not a defect fix — see open_questions.",
"cost_number": "check:doc-types extension: +3 files, +25 code blocks, +0 type literals, +0 findings, +0 exemptions, ratchet cost ZERO. check:doc-fences + check:doc-snippets (they move together or the pin test fails): +3 files, +14 compiled blocks, +11 RED, absorbable only by +2 UNGATED_DOCS entries that verify 0 of those 14 blocks.",
"ungated_docs_style_exemption_needed": "For operator prose, no — an UNGATED_DOCS-style list is the wrong instrument here. It already exists in check:doc-snippets and applying it to these two files buys nothing (see ratchet_absorption). The blocks are excerpt FRAGMENTS, and the gate already has the right instrument for that, per block rather than per file: the `doc-snippet: fragment` marker with a written reason. 10 of the 11 red blocks are fragment-shaped; the 11th is #7282, a real defect that should be fixed, not declared."
},
"tests": "All runs on the worktree at 64d624ded (`git status --porcelain` empty before and after; the only untracked output is gitignored build artifacts). Exit codes captured by redirecting FIRST, never read through a pipe. GATES, quoting each gate's own verdict line: `pnpm check:doc-fences` EXIT=0 -> 'check:doc-fences — every TypeScript block in 224 document(s) is fenced ts/tsx/typescript, except 80 declared file(s) carrying 90 block(s) of objectui#5867's remaining population (SHRINK-ONLY). No unknown fence spelling hides one.' · `pnpm check:doc-types` EXIT=0 -> 'Scanned 185 doc file(s) (.mdx + .md), 1069 code block(s), 901 `type` literal(s) against 658 registered key(s) derived from 141 source file(s)... Every documented component type is registered.' · `pnpm check:control-bytes` EXIT=0 -> 'check-control-bytes: OK (scanned 6004 tracked text file(s); skipped 85 binary).' · `pnpm type-check:scripts` EXIT=0 · `pnpm check:doc-snippets` first returned EXIT=2 'PRECONDITION NOT MET' with 21 unbuilt-package findings — that is NOT MEASURED, not a red gate, so the closure was built behind the shared lock (`turbo run build $(node scripts/check-doc-snippet-types.mjs --build-filter) --concurrency=2`, 32 tasks successful, VERDICT command-exit 0, held 250s / waited 328s) and re-run: EXIT=0 -> 'Semantic phase: 272 of 272 block(s) judged, 0 failed. Every covered documentation snippet compiles against the built types.' TESTS: `vitest run --maxWorkers=2` over scripts/__tests__/check-doc-{fence-languages,snippet-types,component-types}.test.ts EXIT=0, 'Test Files 3 passed (3) / Tests 117 passed (117)'. MEASUREMENT METHOD — no instrumented copy and no mutation of any tracked script was needed, which improves on PR #6284's method: the harnesses import each gate's OWN exported functions and feed them the apps/*/docs population. check:doc-fences via census/reconcile/KNOWN_UNHIGHLIGHTED_TS_FENCES directly. check:doc-types via the gate's real analyze() pointed at a shadow root whose content/docs holds the three files and whose packages/apps/examples are TOP-LEVEL symlinks (readdirSync resolves the path through the symlink, so every dirent inside is real and withFileTypes still reports directories correctly). check:doc-snippets by composing scanFences + derivePackageTypePaths + deriveDeclaredDependencyPaths + compileSnippets over the real root. THREE FAITHFULNESS CONTROLS, each reproducing the real gate: (1) the fence census over the real 224-document surface returns fresh=0 stale=0, reproducing the gate's green; (2) deriveRegistryKeys through the shadow root returns 658 keys from 141 source files, IDENTICAL to the real tree's; (3) the snippet harness's control probes match the real gate line-for-line — resolution to packages/types/dist/index.d.ts, sentinel 1 diagnostic TS2305, positive 0, undeclared 1 diagnostic TS2307, srcLeaks 0. DEVIATION, declared: I did not execute a red run of the walk-equality pin test. The intended ablation (patch DOCS_ROOT, run the pin test, restore under a trap with an on-disk hash proof) was refused by the environment's command classifier before it wrote anything — the worktree was verified clean immediately after, so nothing was left mutated. What I ran instead measures the pin test's own inputs through its own two imported walk functions and evaluates the same deep equality the test asserts: 224 vs 224 equal today, 227 vs 224 NOT equal if the fence root moves alone, 227 vs 227 equal if both move. That is a measurement of the assertion's operands, not an observed red test run, and I am reporting it as such.",
"mcp_calls": "7 — issue_read(get), issue_read(get_comments), add_issue_comment(dev claim), search_issues(dedup for the ResizablePanelGroup finding, 0 hits), search_issues(control word, 3 hits including #6600 itself, proving the 0 was real), issue_write(create #7282), add_issue_comment(this report). REST was probed first and is 403 for repo-scoped reads in this container and `gh` is absent, so the dedup went through one targeted MCP search with a control, per the channel rule; no wide-table scan.",
"open_questions": [
{
"question": "Should check:doc-types' scan root be extended to apps/*/docs/** on its own? It is the one free move (0 red, 0 ratchet, all floors clear) but it yields 0 findings on today's population, and the gate's header DECLARES its current scope ('This gate walks content/docs and nothing else: not skills/**, not the package READMEs, not docs/**'). The triage graded this card Task precisely because no declaration is violated. Changing a declared scope for zero measured yield is a maintainer's call, not a dev's — and the real question underneath is which markdown this gate owns, since apps/*/docs/** is 3 of roughly 50 unscanned files and skills/objectui/** (18 files, the published skill packs) is the slice with external stakes.",
"options": [
"A. Extend check:doc-types to apps/*/docs/** only. Zero red, zero ratchet, a forward guard that would catch the next `type:` literal a console guide invents. Costs one more slice of declared-scope divergence and finds nothing today.",
"B. Extend all three roots now and ungate the two TS-bearing guides. Keeps one surface across the gates, but verifies zero of the 14 blocks and grows a SHRINK-ONLY ledger by 2.",
"C. No gate change at all. Record the measurement, route the content defects to the ui lane (#6599 landed, #7282 filed), and revisit if apps/*/docs grows or its guides start teaching registry keys.",
"D. Fix the content first, then move check:doc-fences and check:doc-snippets together in a second change (the pin test forces them to travel as a pair), and decide check:doc-types' scope in that same change so the three gates' surfaces are settled once rather than drifting apart."
],
"recommendation": "D, with C as its first step and A folded into D rather than taken alone. LONG-TERM SOUNDNESS (leading, and it decides this on its own): the card exists because a gate suite reported green over files it never opened. B and a bare A both answer that by making the gates SAY they cover this tree while verifying nothing in it — B explicitly (ungated means not compiled and not counted, in the gate's own words) and A vacuously (0 type literals). A declared-but-empty coverage claim is strictly worse than the honest hole, because the next agent reads the gate list and stops looking. D is the only option where the coverage the gates advertise is the coverage they perform, and it costs nothing to wait: the blind spot is recorded, and the two things that actually accumulated in it are already routed. REAL BUSINESS NEED (measured, and it cuts against acting now): two concrete defects have surfaced in this tree — #6599's guide that rebuilt the telemetry init #5522 removed, and #7282's wrong ResizablePanelGroup prop — and NEITHER would have been caught by any extension available today. #6599's drift is prose semantics, which no gate reads. #7282's TS2322 is catchable in principle, but only while the file stays COVERED, and covered means 11 red, which is the revert the triage predicted; every green configuration ungates it. Both real defects were found by an agent reading the file. That is the pull evidence, and it says the gate extension is not what is missing. MAKING AI-WRITTEN CODE HARD TO GET WRONG: the fragment marker already does the right thing here — it is per block, it demands a written reason, and it fails loudly when it goes stale — where an UNGATED_DOCS entry silently withdraws a whole file. Fixing content first and then extending keeps the strict, declared-equals-enforced direction; extending first and ungating installs exactly the tolerant consumer-side shape that hides AI-authored drift. STARTUP SCOPE DISCIPLINE: this is 3 files. It does not justify building an allowlist mechanism, and D deliberately does not propose one — it proposes ORDERING, which is free. The one thing worth doing regardless of D is the content work, which is already someone's card."
}
],
"out_of_scope_findings": [
"filed as #7282: apps/console/docs/UI_IMPROVEMENT_PROPOSAL.md:167 teaches a `direction` prop on ResizablePanelGroup; the shipped component takes `orientation` (packages/components/src/ui/resizable.tsx:44, its own resizable-orientation.test.tsx, and the in-tree call site navigation-overlay.tsx:519). Unassigned, no label, left for PM triage — the import resolves, so this is a wrong prop name in the prose, not a missing export. It is the only one of the 11 red blocks that is a defect in what the guide claims.",
"not filed, reported here as context for the open question: the unscanned markdown surface is roughly 50 files, not 3. skills/objectui/** is 18 of them and is the slice with external stakes (published skill packs); the doc-types gate's header names that exclusion explicitly, so it is declared rather than accidental. #7115 (open) already records the same shape for the root README. Deliberately not filed as a new card — it is the same finding as #6600 at a wider radius, and filing it separately would fragment one decision across three cards."
]
}
ACCEPT (measurement delivery) — round R40, PM review. No PR; nothing tracked changed; worktree ended clean at 64d624ded. This is the shape the 2026-08-27 triage pre-authorised: "a measurement plus a proposal with no gate change is a complete delivery."
What the measurement established, re-derived rather than inherited:
Population is 3 files, not 5 — the card's count was a miscount at filing (git log --diff-filter=ADR shows three adds, zero deletes/renames at the card's own commit). The load-bearing claim stands: apps/*/docs/** is in no doc gate's scan surface.
Extending the roots today verifies zero blocks. check:doc-types and check:doc-fences absorb the three files at zero cost and find nothing (0 type: literals, 0 hidden-TS fences). check:doc-snippets would newly compile 14 blocks, 11 red (2 parse, 9 semantic; 62 of 65 diagnostics are TS2304 on excerpt fragments), and the only green configuration is two UNGATED_DOCS entries, i.e. the same blind spot with a signature on it, plus growth of a shrink-only ledger.
Sequencing fact: check-doc-fence-languages.test.ts pins fenceDocuments(ROOT) deep-equal to snippetDocuments(ROOT) (measured 224 = 224 today; 227 ≠ 224 if the fence root moves alone), so the cheap gate cannot move without the expensive one.
Method was the gates' own exported functions over the real population with three faithfulness controls (fence census reproduces the live green; registry keys 658/141 identical through the shadow root; snippet harness probes match the gate line for line). Declared deviation: the walk-equality pin test was not driven red — the intended mutation was refused by the environment before writing, and the operands of its assertion were measured instead. Accepted as a measurement of the operands, not of the test.
The remaining question is a maintainer's: whether a gate's declared scope moves for zero measured yield, and which markdown the doc gates own at all (apps/*/docs/** is 3 of ~50 unscanned files; skills/objectui/** is 18 of them and the doc-types header declares that exclusion). The seat does not change a declared gate scope on its own. Label pm:dispatched → needs-user-decision in this write; decision block follows in Chinese per the standing rule.
Container & model: M, mode:subagent, model: fable — gate-semantics design, which the lane's tiering sends to the contract-review tier rather than the default judgement tier: this change decides which files three gates declare they own, across a roughly 50-file unscanned population that includes the published skills/objectui/**. If fable is measurably unavailable (rate limit, or killed mid-run), the quota-exhaustion exemption applies and it falls back to opus, ⛔ no lower, with the reason recorded.
Clause-②: no
Serial constraints cleared: scripts/check-doc-fence-languages.mjs, scripts/check-doc-snippet-types.mjs, scripts/check-doc-component-types.mjs and scripts/__tests__/check-doc-fence-languages.test.ts are touched by no open PR — checked against all 14 open PRs at 2026-09-03T05:12Z. ⚠️ One read-coupling to declare rather than a file overlap: feat(gates): check the marked fenced examples in the skill guides #7427 (open draft, claude/issue-7359-skill-fence-check, skills lane) adds a fenced-example check over the skill guides, i.e. it works the same skills/** population this card must write a scope statement about. No file overlap, but whoever lands second inherits the other's claim about who owns skills/**. The dispatch requires the scope statement to be written as a statement of the roots as they are, ⛔ never as a forward promise about skills/**.
File surface
scripts/check-doc-fence-languages.mjs · scripts/check-doc-snippet-types.mjs · scripts/check-doc-component-types.mjs · scripts/__tests__/check-doc-fence-languages.test.ts and the sibling gate tests that pin the walks. ⛔ Out of surface: apps/console/docs/** content (that was step 1, landed as PR #7425), the three tsx fences of #7426, and any UNGATED_DOCS entry. Stop on breach and explain in the report.
Readings taken from the tree at dispatch time, not from the card
reading
value on origin/main @ 6411def
check-doc-fence-languages.mjs
const DOCS_ROOT = 'content/docs' (:152), plus export const ROOT_PAGES = ['README.md'] (:168) and the package READMEs
check-doc-snippet-types.mjs
const DOCS_ROOT = 'content/docs' (:301)
check-doc-component-types.mjs
const DOCS_ROOT = 'content/docs' (:216); its header at :213 declares it covers the pages named there "and nothing else: not skills/**, not the package READMEs"
the weld
check-doc-fence-languages.test.ts:56 — expect(fenceDocuments(ROOT)).toEqual(snippetDocuments(ROOT)), so the fences root cannot move without the snippets root. Ruling D's "together" is mechanically enforced, not a convention
precedent for the shape
objectui#7115 already widened two of these gates onto the root README.md; the header prose records how
⇒ The acceptance criterion ruling D set is satisfiable on today's main — the ui seat measured 3 documents covered, 14 blocks, 4 compiled, 0 failed, 10 declared fragments, 0 ungated — so this is an implementation, not a re-opened design.
Claim amendment — tier downgraded fable → opus under the quota-exhaustion exemption. Session session_019aCUUSwWefnbCJ4Xk1vqQW, R41.
The fable dispatch was killed at startup, before any work: HTTP 429, rate_limit, model claude-fable-5-1, verbatim "You've reached your Fable limit." That is the exemption's trigger read as a measurement — fable is demonstrably unavailable in this container right now, not inferred to be — so the maintainer's 2026-08-13 ruling applies (「fable 如果用完了,可以用 opus」) and the tier falls to opus, ⛔ no lower.
No worktree, branch or commit was produced by the killed dispatch, so nothing was inherited or clobbered; the replacement is instructed to check for leftovers before creating and to report any it finds.
What the downgrade costs, stated rather than waved past. The reason this card was tiered up is the one judgement ruling D delegates to this lane — whether apps/*/docs/** joins check:doc-types, and how the roughly 50 unscanned markdown files (skills/objectui/** among them) get their ownership written into the gate headers. That judgement is unchanged and still on the dev. The compensating control is this seat's review, which will read the scope statement against the roots as a claim to falsify, not as prose to skim — and Zone 1 already fences the expansion risk hard: the gated population stays the three files, and ⛔ no gate widens onto skills/** in this PR.
{
"issue": 6600,
"status": "done",
"branch": "claude/issue-6600-doc-gate-scan-roots",
"pr": "https://github.com/objectstack-ai/objectui/pull/7449",
"premise_still_valid": true,
"summary": "All three doc gates now walk apps/*/docs/** (one level of app dir before the docs segment). Zone 2 premises 1-5 all verified on a fresh origin/main, which had moved 6411def -> d6ceb8d29 since the PM took its readings; I branched off d6ceb8d29. Two refinements to premise 1: ROOT_PAGES is carried and exported by ALL THREE gates (fences :168, snippets :328, types :247), not fences alone; and premise 2's pins needed no update -- the >100 length floor and the README membership assertion both survive the widening untouched. The delegated judgement (premise 3) is decided YES: doc-types joins, at zero present yield (0 type literals in the three files, count unchanged 922 -> 922), because leaving it out rebuilds the exact split-surface geometry of #7115 in the same gate family; the reason is written into that gate's header. No leftover branch or worktree from the killed first dispatch existed. Correction to the ruling's prose, not a premise: the unscanned markdown population is 114 files excluding .changeset/, not 'roughly 50' -- 54 packages non-README .md, 17 docs/**, 16 skills/objectui/**. No gate widened onto skills/**; it is named in the ownership map as explicitly unclaimed.",
"tests": "All at final HEAD eba0a9b7a, tree clean (git status --porcelain = 0 lines), exit codes captured by redirect before any pipe. GATES from repo root, before -> after: check:doc-fences exit 0, 225 -> 228 documents, shrink-only baseline unchanged 80 files/90 blocks; check:doc-snippets exit 0, 225 -> 228 documents, 193/32 -> 196/32 covered/ungated, 563 -> 577 covered blocks, 417 -> 421 compiled, 146 -> 156 declared fragments, verdict line '421 of 421 block(s) judged, 0 failed'; check:doc-types exit 0, 186 -> 189 doc files, 1090 -> 1115 code blocks, 922 -> 922 type literals, 'Every documented component type is registered.'; check:control-bytes exit 0, 6131 tracked text files. Deltas reproduce the ui seat's measurement exactly: +3 documents, +14 blocks, +4 compiled, +10 fragments, +0 ungated. LEDGERS asserted not eyeballed: UNGATED_DOCS extracted block sha256 9b4bbc43...aa01 identical on origin/main and HEAD, 32 entries both sides; fences KNOWN_UNHIGHLIGHTED_TS_FENCES sha256 19f60abc...6a18 identical both sides. ABLATION (4 legs, script carries trap on EXIT INT TERM, all paths absolute from git rev-parse --show-toplevel): no rebuild leg applies and that is stated rather than skipped -- the mutated subject is markdown the gate reads by path at runtime, not a subject resolved through a package dist/, and the packages the snippet gate compiles against were unchanged and already built. Each leg proved the mutation on disk BEFORE the run by HEAD-blob-hash != worktree-blob-hash plus a marker grep -c, never by the editor's exit code, and proved the restore AFTER by blob == HEAD blob AND empty git diff HEAD. A1 defect in the genuine compiled block -> check:doc-snippets exit 1, TS2322 at UI_IMPROVEMENT_PROPOSAL.md:174, '421 of 421 judged, 1 failed'. A2 same defect class in a design-token block -> exit 0, '0 failed' (the #7426 vacuity demonstrated, not asserted; expected direction, declared in advance). B TypeScript body under a bare fence in deployment.md -> check:doc-fences exit 1, names deployment.md:21. C unregistered type literal in a fenced block -> check:doc-types exit 1, '[unregistered-doc-type] type ablation-6600-unregistered'. Final git diff HEAD empty after all four legs. TESTS: vitest over the three gate test files plus every other test that names these scripts by grep (check-pre-install-import-graph, one-authority-per-exported-name-6273, known-schema-types-derivation-5115, report-namespace-agreement-6416) = 7 files, 196 tests, all passed. LINT: full-repo pnpm lint run, NOT narrowed, exit 0, 47/47 tasks, 0 errors. CHANGESET: checked at the gate, not assumed -- empty-frontmatter changeset added; skip-changeset deliberately not applied because ci-cd-pipeline-doc.test.ts pins it as a phantom label in this repo. CI-TRIGGER check: all three gate workflows carry no paths filter by design and their own tests fail if one is added, so the moved roots really are exercised on docs-only PRs.",
"mcp_calls": "6 -- issue_read x1, search_issues x2 (dup search + a control that had to hit, and did: 6 results), issue_write x1 (filed #7448), create_pull_request x1, add_issue_comment x1 (this report). Channel note: unauthenticated repo-scoped REST reads work in this container and carried all issue/comment/PR reads at zero MCP cost, but the REST /search/issues endpoint returns 403, so the duplicate check switched to MCP search_issues -- declared here rather than silently. Second channel note: the MCP issue_read rendering STRIPPED the angle-bracket fragment from #6600's body (showed 'packages//README.md'); the REST raw body has 'packages/NAME/README.md' intact, so the stored body is NOT truncated and the loss was a reading-channel artifact.",
"open_questions": [],
"out_of_scope_findings": [
"filed as #7448: two doc-gate workflow headers carry hand-copied document counts that drifted before this change (doc-fence-languages.yml says 222 vs 228 actual; doc-component-types.yml says 184 vs 189 actual) -- prose only, no verdict reads them; labelled finding + domain:devx, unassigned, duplicate-checked with a control query"
]
}
ACCEPT — PR #7449, head 126a6318d. Ruling D step 2 delivered.
Reviewed against GitHub and the tree by the domain:devx seat (session session_019aCUUSwWefnbCJ4Xk1vqQW, R41). CI: 29 checks, all green or skipped, none red, none running.
Against the ruling's own acceptance criterion
check:doc-snippets judges the apps/*/docs/** blocks and reports 0 failed, with the fragment blocks counted as declared fragments rather than skipped files; no UNGATED_DOCS growth; the three gate headers state their scope and agree with their roots.
Met, and the deltas reproduce the domain:ui seat's independent measurement exactly: +3 documents, +14 blocks, +4 compiled, +10 declared fragments, +0 ungated. 421 of 421 block(s) judged, 0 failed.
UNGATED_DOCS did not grow — verified independently, not taken from the report: the declaration is untouched and that file's diff is +76/-0, so nothing in the ledger could have moved.
skills/** was not widened onto. All four occurrences of skills/ in added lines are prose stating it is explicitly unclaimed, with the reason — governed, published surface with its own review path, so pointing a gate at it is a decision for whoever owns it and never a side effect of a root move. That is Zone 1 rule 5 honoured to the letter.
Governed surface: none. Five files — one changeset, three scripts/*.mjs, one scripts/__tests__ file.
The delegated judgement, and why I accept the call
The one thing ruling D left to this lane was whether check:doc-types joins. The dev decided yes, at explicitly zero present yield (0 type literals in the three files; count unchanged 922 → 922), and wrote the reason into the gate header: leaving this gate pointed away from a tree its two siblings now read would rebuild the exact split-surface geometry of #7115 — where the root README.md fell between two gates' surfaces and taught the unregistered stat-card four times — deliberately, inside the same gate family. The header also states ⛔ what it is not: a precedent for widening onto any other unscanned tree.
Accepting that reasoning. A forward guard at zero yield is a real cost only if it invites scope creep, and the header forecloses that in writing.
Non-vacuity, which is the part that actually mattered here
Widening a scan surface is the change most able to be green about nothing, so the ablation is the load-bearing evidence and it is four-legged, each mutation proven on disk by blob-hash before the run and the restore proven after:
leg
result
A1 — real defect in a genuinely compiled block
check:doc-snippetsexit 1, TS2322 at UI_IMPROVEMENT_PROPOSAL.md:174
A2 — same defect class in a design-token block
exit 0, 0 failed
B — TypeScript body under a bare fence
check:doc-fencesexit 1, names deployment.md:21
C — unregistered type literal
check:doc-typesexit 1
A2 is the one I want on the record. I asked for the #7426 vacuity to be stated; the dev demonstrated it instead — a planted defect in a design-token block passes, because background: "bg-background" parses as a labelled statement. So three of the four newly-compiled blocks are a check that cannot fail, and the PR body says so under its own heading with the back-link, rather than letting it disappear into a green. That is better than what the dispatch asked for.
Patch round
The header stated the unscanned population as 114 where its own shipped command answers 111. The dev found the cause and it is sharper than the drift I diagnosed: the 114 counted the three apps/console/docs/** guides as unscanned — the very files this PR gates. The number described the pre-change world while the command beside it described the post-change one. Verified: 111 + 3 = 114, and 3 is exactly the apps/*/docs md count on the branch.
Asked for either a correction or dropping the bare total; the dev took the second and applied it further than proposed, dropping every frozen integer including the subgroup counts I would have left in place — keeping 54/17/16 relocates the trap rather than removing it, since those drift by the same mechanism. The trees are now named in size order with the re-derivation command as the durable answer to both "how many" and "which", and the block cites its own 114 as the cautionary case, back-linked to #7448.
Verified: comment-only diff (no non-comment line moved), every gate number identical pre- and post-patch, which is the correct signature for a comment-only change.
⚠️ A trap this round produced, worth carrying
Writing apps/*/docs/** inside a JSDoc block reintroduces the */ comment-terminator bug — and node --check passes the result. The truncated comment leaves the file syntactically valid and semantically broken, surfacing only as a runtime ReferenceError. I reproduced this: node --check returns success on a deliberately mutated copy. Syntax-checking is not sufficient for this class; a real import() of the module is, and that is what caught it. The two install-free gate modules import cleanly at the final head; the third needs typescript installed, so CI's Doc Snippet Type Check is its authoritative check — and it is green.
⇒ Flipping out of draft and into the merge queue. Card closes on merge via Fixes #6600. #7426 remains open and is the right home for the fence-language decision; it is domain:ui and stays there.
Activity
huangyiirene commentedon Aug 27, 2026
Finding round: graded, promoted to
pm:queue,findingshed. Routeddomain:devx— documentation gates are the engineering stream of the objectui three-way split, which crosses to the devx lane rather than staying withdomain:ui. Type Task: no declaration is violated —check:doc-types' own comment honestly says it "walkscontent/docsand nothing else". The gates are not lying; they are simply not pointed at this tree.⭐ What lifts this above a coverage-gap note is #6599's evidence of what actually accumulated in the blind spot.
apps/console/docs/error-tracking.mdhad drifted far enough that following it literally rebuilds the ungated telemetry init that #5522 deliberately removed — plus a fabricated CSP section and two env vars (VITE_ENVIRONMENT,VITE_ERROR_ENDPOINT) with zero read sites anywhere in the tree. Documentation that instructs an operator to re-introduce something the platform removed on purpose is not stale prose; it is an active hazard, and nothing mechanical could have noticed any of it. Five guides sit in that tree today.Scope — measure before flipping anything, and that ordering is the deliverable. The card is explicitly not recommending switching the gates on blindly and this seat endorses that:
apps/*/docs/**and count how many blocks would newly be judged bycheck:doc-typesandcheck:doc-snippets, and what verdicts they would get.DOCS_ROOTand take whatever falls out. These are operator/deployment prose, not API guides — they will contain shell and config blocks that the snippet type-checker was never designed to judge, and a flood of new failures gets the extension reverted rather than fixed.A measurement plus a proposal with no gate change is a complete delivery for this card. Say so in the dispatch order.
Dedup confirmed as filed, and the boundaries are drawn correctly: #4148 (closed) is the nearest — same
apps/**-unscanned shape but specific tocheck-doc-links.mjs; #5174 / #5106 (open) concern.mdvs.mdxcollection withincontent/docs; #5250 / #5867 (open) concern which fences inside already-covered files get read. ⛔ None covers "theapps/*/docs/**tree is in no scan surface at all."Measured at
da545f1a6; re-verify the threeDOCS_ROOTconstants at dispatch rather than inheriting the table.Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
Claim: PM loop round R40 (backfill after #6606 returned; batch=5)
Session:
session_01BGMDbrVa8JjZcCQ7DWYH1bBranch:
claude/issue-6600-apps-docs-gate-surfaceWorktree:
objectui-issue-6600Domain:
domain:devxFile surface: measurement first — no gate change is owed by this card. If the measurement supports a change:
scripts/check-doc-fence-languages.mjs,scripts/check-doc-snippet-types.mjs,scripts/check-doc-component-types.mjs(theirDOCS_ROOT/ scan-root logic and anyUNGATED_DOCS-style exemption list) and their tests underscripts/__tests__/(stop on breach; explain in the report). ⛔ No edits toapps/console/docs/**themselves (that is the ui lane's content; #6599 already rewrote one guide).Container & model: M (measurement + proposal; a gate change only on the strength of the number),
mode:subagent,model: opus. Tier is this seat's explicit decision (nodispatch-gates.mjsin objectui).Clause-②: no
Serial constraints cleared: on
origin/main64d624dedall three gates still root atcontent/docs(check-doc-component-types.mjs:214,check-doc-fence-languages.mjs:144,check-doc-snippet-types.mjs:301); theapps/*/docs/**population is now 3 files (apps/console/docs/UI_IMPROVEMENT_PROPOSAL.md,deployment.md,error-tracking.md), not the 5 the card measured — re-count. Recent churn on the gates:b83cd76a9(#7100),ee851c32a(#6895). No in-flight PR in either lane touches these scripts; batch siblings (#6640 test infra · #6705 parity scanner · #6291 derivation gate · #7183 vitestdistproject) are disjoint by construction. Adjacent open cards #5174 / #5106 / #5250 / #5867 concern collection or fences withincontent/docs— ⛔ not this card's surface.Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
Dev claim (os-dev, measurement-first).
Session:
session_01BGMDbrVa8JjZcCQ7DWYH1bBranch:
claude/issue-6600-apps-docs-gate-surface(pushed empty at64d624dedbefore any edit)Worktree:
objectui-issue-6600File surface: measurement first — no gate change is owed. If the number supports one:
scripts/check-doc-fence-languages.mjs,scripts/check-doc-snippet-types.mjs,scripts/check-doc-component-types.mjsand their suites underscripts/__tests__/. No edits toapps/console/docs/**(ui lane content). Measurement runs against instrumented COPIES of the gate scripts under the scratchpad, never a mutation of the tracked files.Deliverable per the 2026-08-27 triage: per-file/per-gate table of blocks that would newly be judged plus their verdicts, ratchet-absorption verdict, and a proposal with the number attached.
Generated by Claude Code
Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
os-dev-report
{ "issue": 6600, "status": "done", "branch": "claude/issue-6600-apps-docs-gate-surface", "pr": null, "premise_still_valid": true, "files_changed": [], "summary": "Measurement-only delivery, exactly the shape the 2026-08-27 triage pre-authorized ('a measurement plus a proposal with no gate change is a complete delivery'). No gate was flipped and no tracked file changed; the worktree ends at 64d624ded with `git status --porcelain` empty. PM assumption (a) re-derived and CONFIRMED on 64d624ded: all three gates root at `content/docs` (check-doc-component-types.mjs:214, check-doc-fence-languages.mjs:144, check-doc-snippet-types.mjs:301); fences and snippets additionally walk `packages/NAME/README.md` — that is the card's sanitizer-stripped `packages//README.md` cell, read from the script as instructed. PM assumption (b) is FALSIFIED in the card's favour: the other two guides never existed. `git log --diff-filter=ADR -- apps/console/docs/` shows exactly three adds (1045cbd0f added deployment.md + error-tracking.md, 366775d42 added UI_IMPROVEMENT_PROPOSAL.md) and zero deletes or renames, and `git ls-tree -r da545f1a6 -- apps/console/docs` returns 3 files at the card's OWN measurement commit — so 'five guides' was a miscount at filing time, not attrition. The card's load-bearing claim (the tree is in no gate's scan surface but check:control-bytes) stands unchanged. THE HEADLINE NUMBER: extending the roots buys ZERO verified blocks. check:doc-types and check:doc-fences absorb the three files at zero cost but find nothing in them (0 `type:` literals, 0 hidden-TypeScript fences); check:doc-snippets would newly compile 14 blocks and 11 of them go RED, and the only absorbing move — two UNGATED_DOCS entries — means those 14 blocks are not compiled at all, so the extension would verify nothing while growing a ledger the script marks SHRINK-ONLY. A third structural fact decides the sequencing: scripts/__tests__/check-doc-fence-languages.test.ts asserts `expect(fenceDocuments(ROOT)).toEqual(snippetDocuments(ROOT))`, so the cheap gate cannot be extended without the expensive one. One real defect fell out of the measurement and was filed unassigned rather than fixed (apps/console/docs is the ui lane's content and outside this card's file surface): the guide teaches a `direction` prop on ResizablePanelGroup where the shipped component takes `orientation`.", "measurement_table": { "population": "3 files, derived not inherited — `git ls-files 'apps/*/docs/*'` on 64d624ded. Adjacent operator prose the same argument covers but this card does not: apps/console/README.md, apps/site/README.md. Wider unscanned markdown outside every doc gate: roughly 50 files — skills/objectui/** (18; the doc-types header DECLARES this exclusion), docs/adr (10), docs/audits (5), examples/*/README.md (5), packages/*/docs/** and packages/vscode-extension/*.md (5), .github/prompts (3). apps/*/docs/** is 3 of about 50.", "per_file": [ { "file": "apps/console/docs/UI_IMPROVEMENT_PROPOSAL.md", "fenced_blocks": "12 (typescript x1, tsx x11)", "check_doc_fences": "0 newly judged findings — every block is already fenced ts/tsx/typescript, so no hidden-TypeScript site and no KNOWN_UNHIGHLIGHTED_TS_FENCES entry", "check_doc_types": "12 code blocks scanned, 0 `type:` literal sites, 0 key-table rows -> 0 findings", "check_doc_snippets": "12 blocks newly COMPILED -> 9 RED / 3 green. 2 parse failures (:64 TS17008 JSX element 'div' has no corresponding closing tag; :185 TS1005 ';' expected) + 7 semantic failures (:52, :70, :97, :128, :143, :165, :179)" }, { "file": "apps/console/docs/deployment.md", "fenced_blocks": "6 (unlabelled x3, nginx, caddyfile, json)", "check_doc_fences": "0 findings", "check_doc_types": "6 code blocks scanned, 0 `type:` sites -> 0 findings", "check_doc_snippets": "0 ts/tsx blocks -> nothing compiled, green vacuously. NOTE: it also cannot be placed in UNGATED_DOCS — an entry holding no ts/tsx block fails as a stale entry" }, { "file": "apps/console/docs/error-tracking.md", "fenced_blocks": "7 (unlabelled x2, bash x2, ts x2, yaml x1)", "check_doc_fences": "0 findings", "check_doc_types": "7 code blocks scanned, 0 `type:` sites -> 0 findings", "check_doc_snippets": "2 blocks newly COMPILED -> 2 RED (:54 TS2304 Cannot find name 'RuntimeConfigPlugin' — the class IS real, at packages/app-shell/src/runtime-config.ts, the block just omits the import; :145 TS2304 for 'err' and 'user' — the `@object-ui/app-shell` import RESOLVED, so captureError/setSentryUser are real exports)" } ], "totals": { "check_doc_fences": "0 newly judged findings across all 3 files; 25 fenced blocks seen, 0 classify as hidden TypeScript. UNION run (227 documents): declared files 80, blocks 90, unknown spellings 0, reconcile fresh=0 stale=0 -> GREEN, ratchet untouched", "check_doc_types": "0 newly judged findings. UNION run: files 185 -> 188, codeBlocks 1069 -> 1094, typeSites 901 -> 901 (the three files contain no `type:` literal at all), findings 0, DOC_TYPE_EXEMPTIONS untouched, all 7 FLOORS clear (files 188>=100, codeBlocks 1094>=400, typeSites 901>=300, registryKeys 658>=300, keyTables 4>=2, keyTableRows 24>=12, keyTableKeys 45>=20)", "check_doc_snippets": "14 blocks newly COMPILED, 11 RED / 3 green. 2 parse failures + 9 semantic failures carrying 65 diagnostics: TS2304 x62 (undeclared identifiers — these are excerpt fragments), TS7006 x2, TS2322 x1. The single TS2322 is the only diagnostic that is a defect in what the prose CLAIMS; filed as #7282. Baseline would move from '272 of 272 block(s) judged, 0 failed' to 286 judged, 11 failed" } }, "ratchet_absorption": { "check_doc_fences": "ABSORBS AT ZERO COST — but cannot move alone. MEASURED: fence walk 224 == snippet walk 224 (deep-equal true today); extend the fence root alone and it is 227 vs 224, deep-equal FALSE; extend both and 227 vs 227, deep-equal true. scripts/__tests__/check-doc-fence-languages.test.ts asserts exactly that deep equality, so this gate is welded to check:doc-snippets and inherits its 11 red.", "check_doc_types": "ABSORBS AT ZERO COST and is genuinely independent — no cross-gate walk pin exists for its collector (its tests drive scanDocs over fixture dirs and over repoRoot for its own non-vacuity floors only). Cost: 0 new findings, 0 new DOC_TYPE_EXEMPTIONS entries, every FLOOR still clear.", "check_doc_snippets": "CANNOT ABSORB. 11 of 14 blocks red. The only move that makes it green without editing apps/console/docs/** is two UNGATED_DOCS entries (UI_IMPROVEMENT_PROPOSAL.md, error-tracking.md) — and the gate's own header says an ungated document 'is NOT compiled and NOT counted... exactly as they were before this gate existed'. deployment.md is the only one of the three that could be genuinely covered, and it holds zero ts/tsx blocks. NET VERIFIED COVERAGE GAIN FROM EXTENDING THIS GATE: ZERO BLOCKS, at a cost of +2 entries on a ledger the script marks SHRINK-ONLY." }, "proposal": { "recommendation": "Do NOT extend check:doc-fences or check:doc-snippets now — not because the number is large, but because in every configuration that is green the extension verifies zero blocks. Extending them and ungating the two TS-bearing guides would convert 'a gate suite reports green over a file it never opened' into 'a gate suite reports green over a file it declared it would not open' — the same blind spot with a signature on it, which is worse than the honest hole the card recorded. The correct ORDER is the reverse of the obvious one: the content is fixed first, the root moves second. Concretely: (1) the ui lane fixes #7282 and marks the 10 excerpt blocks with the gate's existing `doc-snippet: fragment` marker; (2) THEN both roots move together in one change, and the coverage is real. check:doc-types is separable and free today (0 red, 0 ratchet, all floors clear) but yields 0 findings on the current population, so it is a forward guard only and its extension is a scope question for the maintainer, not a defect fix — see open_questions.", "cost_number": "check:doc-types extension: +3 files, +25 code blocks, +0 type literals, +0 findings, +0 exemptions, ratchet cost ZERO. check:doc-fences + check:doc-snippets (they move together or the pin test fails): +3 files, +14 compiled blocks, +11 RED, absorbable only by +2 UNGATED_DOCS entries that verify 0 of those 14 blocks.", "ungated_docs_style_exemption_needed": "For operator prose, no — an UNGATED_DOCS-style list is the wrong instrument here. It already exists in check:doc-snippets and applying it to these two files buys nothing (see ratchet_absorption). The blocks are excerpt FRAGMENTS, and the gate already has the right instrument for that, per block rather than per file: the `doc-snippet: fragment` marker with a written reason. 10 of the 11 red blocks are fragment-shaped; the 11th is #7282, a real defect that should be fixed, not declared." }, "tests": "All runs on the worktree at 64d624ded (`git status --porcelain` empty before and after; the only untracked output is gitignored build artifacts). Exit codes captured by redirecting FIRST, never read through a pipe. GATES, quoting each gate's own verdict line: `pnpm check:doc-fences` EXIT=0 -> 'check:doc-fences — every TypeScript block in 224 document(s) is fenced ts/tsx/typescript, except 80 declared file(s) carrying 90 block(s) of objectui#5867's remaining population (SHRINK-ONLY). No unknown fence spelling hides one.' · `pnpm check:doc-types` EXIT=0 -> 'Scanned 185 doc file(s) (.mdx + .md), 1069 code block(s), 901 `type` literal(s) against 658 registered key(s) derived from 141 source file(s)... Every documented component type is registered.' · `pnpm check:control-bytes` EXIT=0 -> 'check-control-bytes: OK (scanned 6004 tracked text file(s); skipped 85 binary).' · `pnpm type-check:scripts` EXIT=0 · `pnpm check:doc-snippets` first returned EXIT=2 'PRECONDITION NOT MET' with 21 unbuilt-package findings — that is NOT MEASURED, not a red gate, so the closure was built behind the shared lock (`turbo run build $(node scripts/check-doc-snippet-types.mjs --build-filter) --concurrency=2`, 32 tasks successful, VERDICT command-exit 0, held 250s / waited 328s) and re-run: EXIT=0 -> 'Semantic phase: 272 of 272 block(s) judged, 0 failed. Every covered documentation snippet compiles against the built types.' TESTS: `vitest run --maxWorkers=2` over scripts/__tests__/check-doc-{fence-languages,snippet-types,component-types}.test.ts EXIT=0, 'Test Files 3 passed (3) / Tests 117 passed (117)'. MEASUREMENT METHOD — no instrumented copy and no mutation of any tracked script was needed, which improves on PR #6284's method: the harnesses import each gate's OWN exported functions and feed them the apps/*/docs population. check:doc-fences via census/reconcile/KNOWN_UNHIGHLIGHTED_TS_FENCES directly. check:doc-types via the gate's real analyze() pointed at a shadow root whose content/docs holds the three files and whose packages/apps/examples are TOP-LEVEL symlinks (readdirSync resolves the path through the symlink, so every dirent inside is real and withFileTypes still reports directories correctly). check:doc-snippets by composing scanFences + derivePackageTypePaths + deriveDeclaredDependencyPaths + compileSnippets over the real root. THREE FAITHFULNESS CONTROLS, each reproducing the real gate: (1) the fence census over the real 224-document surface returns fresh=0 stale=0, reproducing the gate's green; (2) deriveRegistryKeys through the shadow root returns 658 keys from 141 source files, IDENTICAL to the real tree's; (3) the snippet harness's control probes match the real gate line-for-line — resolution to packages/types/dist/index.d.ts, sentinel 1 diagnostic TS2305, positive 0, undeclared 1 diagnostic TS2307, srcLeaks 0. DEVIATION, declared: I did not execute a red run of the walk-equality pin test. The intended ablation (patch DOCS_ROOT, run the pin test, restore under a trap with an on-disk hash proof) was refused by the environment's command classifier before it wrote anything — the worktree was verified clean immediately after, so nothing was left mutated. What I ran instead measures the pin test's own inputs through its own two imported walk functions and evaluates the same deep equality the test asserts: 224 vs 224 equal today, 227 vs 224 NOT equal if the fence root moves alone, 227 vs 227 equal if both move. That is a measurement of the assertion's operands, not an observed red test run, and I am reporting it as such.", "mcp_calls": "7 — issue_read(get), issue_read(get_comments), add_issue_comment(dev claim), search_issues(dedup for the ResizablePanelGroup finding, 0 hits), search_issues(control word, 3 hits including #6600 itself, proving the 0 was real), issue_write(create #7282), add_issue_comment(this report). REST was probed first and is 403 for repo-scoped reads in this container and `gh` is absent, so the dedup went through one targeted MCP search with a control, per the channel rule; no wide-table scan.", "open_questions": [ { "question": "Should check:doc-types' scan root be extended to apps/*/docs/** on its own? It is the one free move (0 red, 0 ratchet, all floors clear) but it yields 0 findings on today's population, and the gate's header DECLARES its current scope ('This gate walks content/docs and nothing else: not skills/**, not the package READMEs, not docs/**'). The triage graded this card Task precisely because no declaration is violated. Changing a declared scope for zero measured yield is a maintainer's call, not a dev's — and the real question underneath is which markdown this gate owns, since apps/*/docs/** is 3 of roughly 50 unscanned files and skills/objectui/** (18 files, the published skill packs) is the slice with external stakes.", "options": [ "A. Extend check:doc-types to apps/*/docs/** only. Zero red, zero ratchet, a forward guard that would catch the next `type:` literal a console guide invents. Costs one more slice of declared-scope divergence and finds nothing today.", "B. Extend all three roots now and ungate the two TS-bearing guides. Keeps one surface across the gates, but verifies zero of the 14 blocks and grows a SHRINK-ONLY ledger by 2.", "C. No gate change at all. Record the measurement, route the content defects to the ui lane (#6599 landed, #7282 filed), and revisit if apps/*/docs grows or its guides start teaching registry keys.", "D. Fix the content first, then move check:doc-fences and check:doc-snippets together in a second change (the pin test forces them to travel as a pair), and decide check:doc-types' scope in that same change so the three gates' surfaces are settled once rather than drifting apart." ], "recommendation": "D, with C as its first step and A folded into D rather than taken alone. LONG-TERM SOUNDNESS (leading, and it decides this on its own): the card exists because a gate suite reported green over files it never opened. B and a bare A both answer that by making the gates SAY they cover this tree while verifying nothing in it — B explicitly (ungated means not compiled and not counted, in the gate's own words) and A vacuously (0 type literals). A declared-but-empty coverage claim is strictly worse than the honest hole, because the next agent reads the gate list and stops looking. D is the only option where the coverage the gates advertise is the coverage they perform, and it costs nothing to wait: the blind spot is recorded, and the two things that actually accumulated in it are already routed. REAL BUSINESS NEED (measured, and it cuts against acting now): two concrete defects have surfaced in this tree — #6599's guide that rebuilt the telemetry init #5522 removed, and #7282's wrong ResizablePanelGroup prop — and NEITHER would have been caught by any extension available today. #6599's drift is prose semantics, which no gate reads. #7282's TS2322 is catchable in principle, but only while the file stays COVERED, and covered means 11 red, which is the revert the triage predicted; every green configuration ungates it. Both real defects were found by an agent reading the file. That is the pull evidence, and it says the gate extension is not what is missing. MAKING AI-WRITTEN CODE HARD TO GET WRONG: the fragment marker already does the right thing here — it is per block, it demands a written reason, and it fails loudly when it goes stale — where an UNGATED_DOCS entry silently withdraws a whole file. Fixing content first and then extending keeps the strict, declared-equals-enforced direction; extending first and ungating installs exactly the tolerant consumer-side shape that hides AI-authored drift. STARTUP SCOPE DISCIPLINE: this is 3 files. It does not justify building an allowlist mechanism, and D deliberately does not propose one — it proposes ORDERING, which is free. The one thing worth doing regardless of D is the content work, which is already someone's card." } ], "out_of_scope_findings": [ "filed as #7282: apps/console/docs/UI_IMPROVEMENT_PROPOSAL.md:167 teaches a `direction` prop on ResizablePanelGroup; the shipped component takes `orientation` (packages/components/src/ui/resizable.tsx:44, its own resizable-orientation.test.tsx, and the in-tree call site navigation-overlay.tsx:519). Unassigned, no label, left for PM triage — the import resolves, so this is a wrong prop name in the prose, not a missing export. It is the only one of the 11 red blocks that is a defect in what the guide claims.", "not filed, reported here as context for the open question: the unscanned markdown surface is roughly 50 files, not 3. skills/objectui/** is 18 of them and is the slice with external stakes (published skill packs); the doc-types gate's header names that exclusion explicitly, so it is declared rather than accidental. #7115 (open) already records the same shape for the root README. Deliberately not filed as a new card — it is the same finding as #6600 at a wider radius, and filing it separately would fragment one decision across three cards." ] }Generated by Claude Code
Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
ACCEPT (measurement delivery) — round R40, PM review. No PR; nothing tracked changed; worktree ended clean at
64d624ded. This is the shape the 2026-08-27 triage pre-authorised: "a measurement plus a proposal with no gate change is a complete delivery."What the measurement established, re-derived rather than inherited:
git log --diff-filter=ADRshows three adds, zero deletes/renames at the card's own commit). The load-bearing claim stands:apps/*/docs/**is in no doc gate's scan surface.check:doc-typesandcheck:doc-fencesabsorb the three files at zero cost and find nothing (0type:literals, 0 hidden-TS fences).check:doc-snippetswould newly compile 14 blocks, 11 red (2 parse, 9 semantic; 62 of 65 diagnostics areTS2304on excerpt fragments), and the only green configuration is twoUNGATED_DOCSentries, i.e. the same blind spot with a signature on it, plus growth of a shrink-only ledger.check-doc-fence-languages.test.tspinsfenceDocuments(ROOT)deep-equal tosnippetDocuments(ROOT)(measured 224 = 224 today; 227 ≠ 224 if the fence root moves alone), so the cheap gate cannot move without the expensive one.directionprop on ResizablePanelGroup — the exported component takesorientation#7282 (directionvsorientationonResizablePanelGroup, ui-lane content). docs(console): error-tracking.md predates the #5522 two-key telemetry gate — following it as written recreates the exact shape #5522 removed #6599 already fixed the other. Neither would have been caught by any extension available today.The remaining question is a maintainer's: whether a gate's declared scope moves for zero measured yield, and which markdown the doc gates own at all (
apps/*/docs/**is 3 of ~50 unscanned files;skills/objectui/**is 18 of them and the doc-types header declares that exclusion). The seat does not change a declared gate scope on its own. Labelpm:dispatched→needs-user-decisionin this write; decision block follows in Chinese per the standing rule.决策:apps/*/docs 是否纳入文档门禁扫描面,以及三条门禁各自「拥有」哪些 markdown
问题. 三条文档门禁今天都只扫
content/docs(fences/snippets 另加packages/*/README.md)。实测把apps/*/docs/**(3 个文件)纳入:doc-types/doc-fences零成本吸收但零发现;doc-snippets新编译 14 块、11 块红,唯一变绿的做法是把两份指南整体UNGATED_DOCS,即一块都不验证。且 pin 测试把 fences 与 snippets 的扫描面焊在一起,不能只动便宜的那条。选项.
check:doc-types扩到apps/*/docs/**。零红、零棘轮、所有 floor 仍清;今天零发现,是前向守卫;代价是该门禁 header 里「只扫 content/docs」的声明再分叉一次。UNGATED_DOCS。扫描面统一,但 14 块一块不验证,shrink-only 台账 +2。directionprop on ResizablePanelGroup — the exported component takesorientation#7282 已立),等该目录增长或开始教 registry 键再议。directionprop on ResizablePanelGroup — the exported component takesorientation#7282 并给 10 个摘录块打现成的doc-snippet: fragment标记;然后一次改动同时移动 fences+snippets 两个根(pin 测试强制成对),并在同一改动里定doc-types的归属范围,让三条门禁的扫描面一次定稿而不是各自漂移。C 是 D 的第一步,A 并入 D 而非单独做。四棱分析.
sendDefaultPii: trueis committed inapps/console/.env.productionand baked into every production build — theVITE_SENTRY_ENABLEDswitch is build-time and absent from the inlined env, so a shipped bundle cannot be silenced #5522 删掉的遥测初始化;apps/console/docs/UI_IMPROVEMENT_PROPOSAL.md:167 documents adirectionprop on ResizablePanelGroup — the exported component takesorientation#7282 错误的 prop 名)没有一个能被今天任何可用的扩展抓住 —— 前者是散文语义,后者只在文件保持「被覆盖」时可抓,而被覆盖等于 11 红。两者都是 agent 读文件读出来的。UNGATED_DOCS静默撤回一整个文件。先修内容再扩根保持「声明 = 强制」的严格方向;先扩根再 ungate 恰是藏住 AI 漂移的消费者侧宽容形状。skills/objectui/**18 个且对外发布(finding(docs/gate): the root README's flagship dashboard example teachesstat-card, which nothing registers — and the root README is outside every doc gate's scan surface #7115 已记录根 README 同形),这才是「哪条门禁拥有哪些 markdown」该一次回答的地方。席位推荐:D(C 为第一步;A 并入 D)。⛔ 推荐是输入,不是放行。回复「A」/「B」/「C」/「D」即可;裁定后本卡回
pm:queue或按 C/D 关闭并由后续卡承接。Generated by Claude Code
14 remaining items
os-sales commentedon Sep 3, 2026
Claim: PM loop round R41 — step 2 of maintainer ruling D.
session_019aCUUSwWefnbCJ4Xk1vqQW(execution seat,domain:devx@ objectui, seat post [PM seat] domain:ui @ objectui · seat 6 — ⏳ vacant #5748, R41)claude/issue-6600-doc-gate-scan-rootsobjectui-issue-6600domain:devxmode:subagent,model: fable— gate-semantics design, which the lane's tiering sends to the contract-review tier rather than the default judgement tier: this change decides which files three gates declare they own, across a roughly 50-file unscanned population that includes the publishedskills/objectui/**. If fable is measurably unavailable (rate limit, or killed mid-run), the quota-exhaustion exemption applies and it falls back toopus, ⛔ no lower, with the reason recorded.scripts/check-doc-fence-languages.mjs,scripts/check-doc-snippet-types.mjs,scripts/check-doc-component-types.mjsandscripts/__tests__/check-doc-fence-languages.test.tsare touched by no open PR — checked against all 14 open PRs at 2026-09-03T05:12Z.claude/issue-7359-skill-fence-check, skills lane) adds a fenced-example check over the skill guides, i.e. it works the sameskills/**population this card must write a scope statement about. No file overlap, but whoever lands second inherits the other's claim about who ownsskills/**. The dispatch requires the scope statement to be written as a statement of the roots as they are, ⛔ never as a forward promise aboutskills/**.File surface
scripts/check-doc-fence-languages.mjs·scripts/check-doc-snippet-types.mjs·scripts/check-doc-component-types.mjs·scripts/__tests__/check-doc-fence-languages.test.tsand the sibling gate tests that pin the walks. ⛔ Out of surface:apps/console/docs/**content (that was step 1, landed as PR #7425), the threetsxfences of #7426, and anyUNGATED_DOCSentry. Stop on breach and explain in the report.Readings taken from the tree at dispatch time, not from the card
origin/main@6411defcheck-doc-fence-languages.mjsconst DOCS_ROOT = 'content/docs'(:152), plusexport const ROOT_PAGES = ['README.md'](:168) and the package READMEscheck-doc-snippet-types.mjsconst DOCS_ROOT = 'content/docs'(:301)check-doc-component-types.mjsconst DOCS_ROOT = 'content/docs'(:216); its header at :213 declares it covers the pages named there "and nothing else: notskills/**, not the package READMEs"check-doc-fence-languages.test.ts:56—expect(fenceDocuments(ROOT)).toEqual(snippetDocuments(ROOT)), so the fences root cannot move without the snippets root. Ruling D's "together" is mechanically enforced, not a conventionREADME.md; the header prose records how⇒ The acceptance criterion ruling D set is satisfiable on today's
main— the ui seat measured 3 documents covered, 14 blocks, 4 compiled, 0 failed, 10 declared fragments, 0 ungated — so this is an implementation, not a re-opened design.Generated by Claude Code
os-sales commentedon Sep 3, 2026
Claim amendment — tier downgraded
fable→opusunder the quota-exhaustion exemption. Sessionsession_019aCUUSwWefnbCJ4Xk1vqQW, R41.The fable dispatch was killed at startup, before any work: HTTP 429,
rate_limit, modelclaude-fable-5-1, verbatim "You've reached your Fable limit." That is the exemption's trigger read as a measurement — fable is demonstrably unavailable in this container right now, not inferred to be — so the maintainer's 2026-08-13 ruling applies (「fable 如果用完了,可以用 opus」) and the tier falls toopus, ⛔ no lower.No worktree, branch or commit was produced by the killed dispatch, so nothing was inherited or clobbered; the replacement is instructed to check for leftovers before creating and to report any it finds.
What the downgrade costs, stated rather than waved past. The reason this card was tiered up is the one judgement ruling D delegates to this lane — whether
apps/*/docs/**joinscheck:doc-types, and how the roughly 50 unscanned markdown files (skills/objectui/**among them) get their ownership written into the gate headers. That judgement is unchanged and still on the dev. The compensating control is this seat's review, which will read the scope statement against the roots as a claim to falsify, not as prose to skim — and Zone 1 already fences the expansion risk hard: the gated population stays the three files, and ⛔ no gate widens ontoskills/**in this PR.Generated by Claude Code
feat(scripts): point the three doc gates at apps/*/docs (#6600)
os-sales commentedon Sep 3, 2026
os-dev-report
{ "issue": 6600, "status": "done", "branch": "claude/issue-6600-doc-gate-scan-roots", "pr": "https://github.com/objectstack-ai/objectui/pull/7449", "premise_still_valid": true, "summary": "All three doc gates now walk apps/*/docs/** (one level of app dir before the docs segment). Zone 2 premises 1-5 all verified on a fresh origin/main, which had moved 6411def -> d6ceb8d29 since the PM took its readings; I branched off d6ceb8d29. Two refinements to premise 1: ROOT_PAGES is carried and exported by ALL THREE gates (fences :168, snippets :328, types :247), not fences alone; and premise 2's pins needed no update -- the >100 length floor and the README membership assertion both survive the widening untouched. The delegated judgement (premise 3) is decided YES: doc-types joins, at zero present yield (0 type literals in the three files, count unchanged 922 -> 922), because leaving it out rebuilds the exact split-surface geometry of #7115 in the same gate family; the reason is written into that gate's header. No leftover branch or worktree from the killed first dispatch existed. Correction to the ruling's prose, not a premise: the unscanned markdown population is 114 files excluding .changeset/, not 'roughly 50' -- 54 packages non-README .md, 17 docs/**, 16 skills/objectui/**. No gate widened onto skills/**; it is named in the ownership map as explicitly unclaimed.", "tests": "All at final HEAD eba0a9b7a, tree clean (git status --porcelain = 0 lines), exit codes captured by redirect before any pipe. GATES from repo root, before -> after: check:doc-fences exit 0, 225 -> 228 documents, shrink-only baseline unchanged 80 files/90 blocks; check:doc-snippets exit 0, 225 -> 228 documents, 193/32 -> 196/32 covered/ungated, 563 -> 577 covered blocks, 417 -> 421 compiled, 146 -> 156 declared fragments, verdict line '421 of 421 block(s) judged, 0 failed'; check:doc-types exit 0, 186 -> 189 doc files, 1090 -> 1115 code blocks, 922 -> 922 type literals, 'Every documented component type is registered.'; check:control-bytes exit 0, 6131 tracked text files. Deltas reproduce the ui seat's measurement exactly: +3 documents, +14 blocks, +4 compiled, +10 fragments, +0 ungated. LEDGERS asserted not eyeballed: UNGATED_DOCS extracted block sha256 9b4bbc43...aa01 identical on origin/main and HEAD, 32 entries both sides; fences KNOWN_UNHIGHLIGHTED_TS_FENCES sha256 19f60abc...6a18 identical both sides. ABLATION (4 legs, script carries trap on EXIT INT TERM, all paths absolute from git rev-parse --show-toplevel): no rebuild leg applies and that is stated rather than skipped -- the mutated subject is markdown the gate reads by path at runtime, not a subject resolved through a package dist/, and the packages the snippet gate compiles against were unchanged and already built. Each leg proved the mutation on disk BEFORE the run by HEAD-blob-hash != worktree-blob-hash plus a marker grep -c, never by the editor's exit code, and proved the restore AFTER by blob == HEAD blob AND empty git diff HEAD. A1 defect in the genuine compiled block -> check:doc-snippets exit 1, TS2322 at UI_IMPROVEMENT_PROPOSAL.md:174, '421 of 421 judged, 1 failed'. A2 same defect class in a design-token block -> exit 0, '0 failed' (the #7426 vacuity demonstrated, not asserted; expected direction, declared in advance). B TypeScript body under a bare fence in deployment.md -> check:doc-fences exit 1, names deployment.md:21. C unregistered type literal in a fenced block -> check:doc-types exit 1, '[unregistered-doc-type] type ablation-6600-unregistered'. Final git diff HEAD empty after all four legs. TESTS: vitest over the three gate test files plus every other test that names these scripts by grep (check-pre-install-import-graph, one-authority-per-exported-name-6273, known-schema-types-derivation-5115, report-namespace-agreement-6416) = 7 files, 196 tests, all passed. LINT: full-repo pnpm lint run, NOT narrowed, exit 0, 47/47 tasks, 0 errors. CHANGESET: checked at the gate, not assumed -- empty-frontmatter changeset added; skip-changeset deliberately not applied because ci-cd-pipeline-doc.test.ts pins it as a phantom label in this repo. CI-TRIGGER check: all three gate workflows carry no paths filter by design and their own tests fail if one is added, so the moved roots really are exercised on docs-only PRs.", "mcp_calls": "6 -- issue_read x1, search_issues x2 (dup search + a control that had to hit, and did: 6 results), issue_write x1 (filed #7448), create_pull_request x1, add_issue_comment x1 (this report). Channel note: unauthenticated repo-scoped REST reads work in this container and carried all issue/comment/PR reads at zero MCP cost, but the REST /search/issues endpoint returns 403, so the duplicate check switched to MCP search_issues -- declared here rather than silently. Second channel note: the MCP issue_read rendering STRIPPED the angle-bracket fragment from #6600's body (showed 'packages//README.md'); the REST raw body has 'packages/NAME/README.md' intact, so the stored body is NOT truncated and the loss was a reading-channel artifact.", "open_questions": [], "out_of_scope_findings": [ "filed as #7448: two doc-gate workflow headers carry hand-copied document counts that drifted before this change (doc-fence-languages.yml says 222 vs 228 actual; doc-component-types.yml says 184 vs 189 actual) -- prose only, no verdict reads them; labelled finding + domain:devx, unassigned, duplicate-checked with a control query" ] }Generated by Claude Code
Generated by Claude Code
docs(scripts): drop the frozen counts from the doc-gate ownership map (…
os-sales commentedon Sep 3, 2026
ACCEPT — PR #7449, head
126a6318d. Ruling D step 2 delivered.Reviewed against GitHub and the tree by the
domain:devxseat (sessionsession_019aCUUSwWefnbCJ4Xk1vqQW, R41). CI: 29 checks, all green or skipped, none red, none running.Against the ruling's own acceptance criterion
Met, and the deltas reproduce the
domain:uiseat's independent measurement exactly: +3 documents, +14 blocks, +4 compiled, +10 declared fragments, +0 ungated.421 of 421 block(s) judged, 0 failed.UNGATED_DOCSdid not grow — verified independently, not taken from the report: the declaration is untouched and that file's diff is +76/-0, so nothing in the ledger could have moved.skills/**was not widened onto. All four occurrences ofskills/in added lines are prose stating it is explicitly unclaimed, with the reason — governed, published surface with its own review path, so pointing a gate at it is a decision for whoever owns it and never a side effect of a root move. That is Zone 1 rule 5 honoured to the letter.scripts/*.mjs, onescripts/__tests__file.The delegated judgement, and why I accept the call
The one thing ruling D left to this lane was whether
check:doc-typesjoins. The dev decided yes, at explicitly zero present yield (0typeliterals in the three files; count unchanged 922 → 922), and wrote the reason into the gate header: leaving this gate pointed away from a tree its two siblings now read would rebuild the exact split-surface geometry of #7115 — where the rootREADME.mdfell between two gates' surfaces and taught the unregisteredstat-cardfour times — deliberately, inside the same gate family. The header also states ⛔ what it is not: a precedent for widening onto any other unscanned tree.Accepting that reasoning. A forward guard at zero yield is a real cost only if it invites scope creep, and the header forecloses that in writing.
Non-vacuity, which is the part that actually mattered here
Widening a scan surface is the change most able to be green about nothing, so the ablation is the load-bearing evidence and it is four-legged, each mutation proven on disk by blob-hash before the run and the restore proven after:
check:doc-snippetsexit 1, TS2322 atUI_IMPROVEMENT_PROPOSAL.md:1740 failedcheck:doc-fencesexit 1, namesdeployment.md:21check:doc-typesexit 1A2 is the one I want on the record. I asked for the #7426 vacuity to be stated; the dev demonstrated it instead — a planted defect in a design-token block passes, because
background: "bg-background"parses as a labelled statement. So three of the four newly-compiled blocks are a check that cannot fail, and the PR body says so under its own heading with the back-link, rather than letting it disappear into a green. That is better than what the dispatch asked for.Patch round
The header stated the unscanned population as 114 where its own shipped command answers 111. The dev found the cause and it is sharper than the drift I diagnosed: the 114 counted the three
apps/console/docs/**guides as unscanned — the very files this PR gates. The number described the pre-change world while the command beside it described the post-change one. Verified: 111 + 3 = 114, and 3 is exactly theapps/*/docsmd count on the branch.Asked for either a correction or dropping the bare total; the dev took the second and applied it further than proposed, dropping every frozen integer including the subgroup counts I would have left in place — keeping 54/17/16 relocates the trap rather than removing it, since those drift by the same mechanism. The trees are now named in size order with the re-derivation command as the durable answer to both "how many" and "which", and the block cites its own 114 as the cautionary case, back-linked to #7448.
Verified: comment-only diff (no non-comment line moved), every gate number identical pre- and post-patch, which is the correct signature for a comment-only change.
Writing
apps/*/docs/**inside a JSDoc block reintroduces the*/comment-terminator bug — andnode --checkpasses the result. The truncated comment leaves the file syntactically valid and semantically broken, surfacing only as a runtimeReferenceError. I reproduced this:node --checkreturns success on a deliberately mutated copy. Syntax-checking is not sufficient for this class; a realimport()of the module is, and that is what caught it. The two install-free gate modules import cleanly at the final head; the third needstypescriptinstalled, so CI'sDoc Snippet Type Checkis its authoritative check — and it is green.⇒ Flipping out of draft and into the merge queue. Card closes on merge via
Fixes #6600. #7426 remains open and is the right home for the fence-language decision; it isdomain:uiand stays there.Generated by Claude Code
feat(scripts): widen the expression-carriage census to check:doc-type…
docs(console): correct the ResizablePanelGroup prop and declare every…
feat(scripts): point the three doc gates at apps/*/docs (objectstack-…
feat(scripts): widen the expression-carriage census to check:doc-type…