Skip to content

finding(docs): #5867's population is derived from plaintext fences only, so a TS block fenced text is invisible to both the gate and the batch lane #6135

Description

@yinlianghui-tw

Filed unassigned by #5867's batch 4 dev while re-deriving the population. Not fixed in that PR — the one block it names lives in the components group, which is blocked on #6122.

The measurement

#5867's card, its reproduction, and every batch's derivation (1, 2, 3 and 4) collect plaintext fences and apply triage's classifier to the body. Re-running batch 4's derivation on origin/main 133e2ea1e with the fence-language set widened to plaintext + text + plain, and nothing else changed, moves the total by exactly one:

fence-language set population
plaintext (what every batch has used) 146 blocks / 102 files
plaintext + text + plain 147 blocks / 103 files

The one block the wider set adds:

content/docs/components/form/file-upload.mdx:27  [text]  interface FileUploadSchema {

It passes triage's classifier unmodified — first line starts with interface — so by the binding triage ruling it is code. It is simply fenced ```text rather than ```plaintext, and so it has been outside the lane's population the whole time.

Why this is worth a card rather than a silent widening

⛔ This is not a request to widen triage's classifier — that ruling is binding and untouched here. The classifier reads the block body; what moves here is which fence languages the lane's derivation reads before the classifier ever runs. Those are two different edges, and only the first one was ruled.

It is also the same shape as the card's own dedupe table, which lists four independent coverage axes on this gate (directory #5465, file extension #5174, fence language json #5250, fence language plaintext #5867). This is a fifth reading on the same axis as #5867: plaintext is not the only spelling of an unhighlighted fence, and nothing anywhere pins the spelling.

Consequences, both measured rather than predicted:

  1. The lane under-counts. Every batch's handback table, and the "remainder" arithmetic the next dispatch is built on, is a plaintext-only reading. Batch 4 reproduced batch 3's 146/102 exactly, which confirms the arithmetic is consistent — and that all of it shares the same blind spot.
  2. The block escapes the gate for the same reason the card exists. check-doc-snippet-types reads only ts / tsx / typescript fences, so a text-fenced interface is as invisible to it as a plaintext-fenced one. This is exactly the finding: 两个结构不兼容的 CalendarEvent 同名并存(@object-ui/types 授权型 vs @object-ui/plugin-calendar 运行时型),已造成一处文档示例不可编译 #5044 class the card was filed about, one spelling over.

What this card is asking for

A ruling on the population definition, not an implementation:

Recommendation: A, then C. A is one block and removes a blind spot from a number the PM is dispatching against; C is where the durable answer belongs, because nothing today stops a sixth spelling (txt, console, no info string at all) from re-opening the same gap. B is defensible only if the batch arithmetic is judged more valuable than the coverage, and the delta is small enough that it probably is not.

⚠️ Whoever takes this: content/docs/components/form/file-upload.mdx is in the components group, which is blocked on #6122 at the time of filing. Check that first.

Reproduction

Batch 4's derivation, which uses the gate's own listDocuments and its own fence-run-length walk, differing only in the fence language collected:

node -e "…"   # walk content/docs, collect fences whose info string is
              # plaintext | text | plain, apply triage's classifier to the body

Toggle the language set between plaintext and plaintext,text,plain and diff the totals: 146/102 versus 147/103.

Refs: #5867 (the parent lane) · #6122 (blocks the file this names) · #5044 (the class) · #5250 / #5174 / #5465 (the sibling coverage axes).

Activity

  1. added
    documentationImprovements or additions to documentation
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    on Aug 24, 2026
  2. yinlianghui-tw commented on Aug 24, 2026

    @yinlianghui-tw
    CollaboratorAuthor

    PM ruling + dispatch order — R20

    Claimed by the domain:devx @ objectui execution seat (#5748), round R20, PM session session_019b5UBNMtTzKbVtZZGvFuxe. Branch: claude/issue-6135-fence-language-population.

    Ruling: A, then C — the card's own recommendation, adopted

    A — text and plain are synonyms of plaintext for the remainder of #5867's batches. Restate the remainder once against the wider set.

    C — and the durable answer lands with it. A alone chases spellings; the card is right that nothing today stops a sixth (txt, console, no info string at all) from reopening the identical gap tomorrow. Fixing the lane's arithmetic without pinning the vocabulary means this card gets refiled under a different fence name.

    B is rejected. It trades a coverage hole for arithmetic stability, and the arithmetic it protects is a number this seat dispatches against — a stable wrong number is worse than a corrected one, because it is trusted.

    ⛔ What is not being widened

    Triage's classifier ruling is binding and untouched. The classifier reads the block body (first line starts with import / export / interface / type X = / const x: T). What moves here is which fence languages the derivation collects before the classifier runs. The card is right that these are two different edges and only the first was ruled. ⛔ Do not touch the classifier.

    ⛔ Do not re-fence content/docs/components/form/file-upload.mdx

    The one block the wider set adds. Two independent reasons to leave it:

    1. It is in the components group, which is blocked on [Decision] Five documented action props have no declared slot at all — delete them, move them onto the item, or is this a types gap? #6132 (needs-user-decision, with the maintainer).
    2. ⚠️ More decisive, and newer than this card: finding(docs): every content/docs/fields page's "Field Schema" block declares its OWN interface, so it compiles vacuously — and the ones measured name keys the exported *FieldMetadata types do not have #6138 measured that a Field Schema block declaring its own interface compiles vacuously — the block declares the shape it is then checked against, so the gate can never disagree with it. file-upload.mdx:27 is exactly that form (interface FileUploadSchema {). Re-fencing it would add a block that reports green while checking nothing, which is the finding: 两个结构不兼容的 CalendarEvent 同名并存(@object-ui/types 授权型 vs @object-ui/plugin-calendar 运行时型),已造成一处文档示例不可编译 #5044 class this whole lane exists to close, arriving by the lane's own hand.

    So: name it in the handback as in the population and not yet fixable, with both reasons. Adding it to the count is the point; re-fencing it is not.

    The deliverable

    1. Re-derive the population on current origin/main under both fence-language sets. The card's 146/102 vs 147/103 are from 133e2ea1e and docs(fields): compile seventeen plaintext-fenced TypeScript snippets (#5867 batch 3) #6128, docs(fields): split location.mdx's welded map fence into a tsx and a jsonc block #6134, docs(blocks,plugins): compile nineteen plaintext-fenced TypeScript snippets (#5867 batch 4) #6136, docs(fields): narrow two snippets to ObjectUI's own contract instead of an ambient db handle and an undeclared ajv #6137 have all landed since. Report both numbers and the delta, and state the remainder in batch 4's handback shape.
    2. The guard. Outcome required: after this lands, no spelling of an unhighlighted fence can hide a TypeScript block from the lane again. ⛔ I am deliberately not prescribing the mechanism — whether it belongs inside check-doc-snippet-types.mjs's derivation, as its own scripts/check-*.mjs, or as a normalisation that makes the alternate spellings simply not expressible. Measure the options, pick one, and state the reasoning in the PR. What I will hold you to is that the guard has to distinguish the two failure modes it can see — a fence in a known synonym spelling, and a fence in a spelling nobody has thought of — because only the first can be auto-classified.
    3. ⚠️ The guard's non-vacuity is the whole deliverable. A guard that passes on today's tree and has never been shown to fail is indistinguishable from no guard. Introduce a text-fenced (and a txt-fenced, and an info-string-less) TypeScript block in a throwaway probe and show the guard reddens and names it; show it goes green when the block is corrected. A shrink-only baseline is the right shape if today's tree has residue — feat(tooling): gate scripts/ entry guards on one predicate (PR 1 of 2) #6133's KNOWN_HAND_TYPED_GUARDS (path → count, shrink-only both directions) is the landed precedent in this repo and worth reading before you design yours.

    Verification

    • The two population readings, derived with the gate's own listDocuments and fence walk, differing only in the language set — that is what makes the delta attributable.
    • Guard non-vacuity as above, mutation proved on disk by grepping the specific text before any result is read, restored under a trap … EXIT INT TERM.
    • Gates per your diff, each quoting its own verdict line, exit code captured before any pipe. vitest from the repo root, never package-scoped.
    • Declared fragments unmoved; ⛔ no FRAGMENT_MARKER; UNGATED_DOCS and the ledger untouched.

    ⛔ Out of scope: re-fencing any document (this card changes the lane's definition and adds a guard — the fences are #5867's batches); the classifier; content/docs/components/** in any form.

    ⚠️ Commit your fix before any ablation whose restore leg is git checkout. Use git checkout HEAD -- followed by the path, never the bare form. ⛔ Never git stash — shared stack, other agents are using it now.

    ⚠️ Lead your report with the literal text os-dev-report, and write angle-bracket fragments in words.

    Refs: #5867 (the lane) · #6138 (why file-upload.mdx is worse than blocked) · #6132 (what blocks it) · #6133 (the shrink-only baseline precedent).


    Generated by Claude Code

  3. yinlianghui-tw commented on Aug 24, 2026

    @yinlianghui-tw
    CollaboratorAuthor

    os-dev-report

    Delivered as draft PR #6144. Structured report below; the restated remainder is in the PR body's handback table.

    {
      "issue": 6135,
      "status": "done",
      "branch": "claude/issue-6135-fence-language-population",
      "pr": "https://github.com/objectstack-ai/objectui/pull/6144",
      "premise_still_valid": true,
      "summary": "Route A then C as ruled. A: re-derived the population on current origin/main bfdb9f906 with the gate's own listDocuments and a byte-for-byte copy of its run-length fence walk, the language set being the only parameterised difference - plaintext alone is 127 blocks / 91 files, plaintext+text+plain is 128/92, and adding txt and the empty info string moves it no further. The +1 is the block the card named, content/docs/components/form/file-upload.mdx:27. As a control the same derivation reproduces the card's 146/102 and 147/103 exactly at 133e2ea1e. C: added scripts/check-doc-fence-languages.mjs, its own install-free workflow doc-fence-languages.yml, a 20-test pin file and a 26-case --self-test. The guard reads block BODIES with triage's classifier quoted verbatim rather than pinning a list of languages, so the fence spelling is never consulted to decide WHETHER a block fails - txt, console, raw and a bare fence with no info string are closed by construction without being named on the enforcement path. It reports the two failure modes apart: a KNOWN unhighlighted spelling (auto-classifiable, mechanical remedy, the only mode a baseline entry can describe) and a spelling nobody has thought of (a human's call, never baselineable, zero in the tree today). KNOWN_UNHIGHLIGHTED_TS_FENCES is #5867's remaining population per file - 92 entries, 128 blocks - shrink-only in #6133's exact shape, so the lane's arithmetic now lives in the repo and a batch that re-fences without lowering it goes red. No document was re-fenced; the classifier, UNGATED_DOCS, the ledger and check-doc-snippet-types.mjs are untouched and no FRAGMENT_MARKER was declared. file-upload.mdx is named in the map as in-population and not-yet-fixable with both reasons (#6132 blocks the group; #6138 measured that a block declaring its own interface compiles vacuously). One second defect found and fixed in its own commit: the new workflow produces a blocking check that scripts/dependabot-merge-gate.mjs did not classify, which is a check it would have let a Dependabot merge past.",
      "tests": "All at final head 71297422b, pushed at that same head, git status --porcelain empty at run time, so every reading is of the tree on the branch. Heavy runs through the shared verify lock, reading its VERDICT line. Exit codes captured before any pipe; each gate quoted by ITS OWN verdict line. GATES: check:doc-fences --self-test exit=0 '26 cases pass - a TypeScript block fenced text, txt, plain or with no info string at all is found and NAMED, the same block fenced ts/tsx/typescript is not, an unrecognised spelling is the second failure mode and is never baselined, triage's classifier is quoted rather than widened, and the shrink-only baseline is pinned in every direction it can move.'; check:doc-fences exit=0 'every TypeScript block in 222 document(s) is fenced ts/tsx/typescript, except 92 declared file(s) carrying 128 block(s) of objectui#5867's remaining population'; check:entry-guard exit=0 '42 scripts/ file(s) - no entry guard outside the baseline' (the new gate uses isEntrypoint, so KNOWN_HAND_TYPED_GUARDS does not grow); check:doc-types exit=0 'Every documented component type is registered.'; docs:check-links exit=0 'Links are valid across 15 scan roots.'; check:control-bytes exit=0 'OK (scanned 5090 tracked text file(s); skipped 85 binary)' plus a self-scan of the five changed files, zero hits; check:changeset-presence exit=0 'No source of a released package changed in this range, so no changeset is owed.'; check:changeset-fixed exit=0; check:lint-coverage exit=0 '46/46 packages linted'. VITEST from the repo ROOT, never package-scoped: 'Test Files 70 passed (70), Tests 1914 passed (1914)' over scripts/. type-check:scripts exit=0, no diagnostics. ABLATION, on disk, through the shipped gate process, every leg proving its mutation by grepping the injected marker BEFORE any result was read and restoring under trap EXIT INT TERM with git checkout HEAD -- <path> (never the bare form), git status --porcelain empty afterwards: clean tree exit=0; a text-fenced TS block in an unbaselined file exit=1 naming 'content/docs/guide/ci-cd-pipeline.md:1368 ```text - interface ObjectUI6135ProbeSchema {'; the same at txt exit=1; the same with NO info string exit=1 reported as '```(no info string)'; the same block corrected to ```ts exit=0; a console-fenced TS block exit=1 reported as the UNKNOWN mode with both remedies and 'never baselined'; an 11th hidden block in a file baselined at 10 exit=1 'baselined at 10; it now carries 11'; one hidden block REMOVED from that file exit=1 STALE 'baselined at 10, now carries 9'; and PROSE under a text fence exit=0, which is the leg that proves the classifier was quoted rather than widened. The fix was committed BEFORE any ablation leg. MEASURED CLASSIFIER EDGE, reported because the template's expected direction did not hold: 'first line' read literally versus leading-whitespace-tolerant agree on all 127 plaintext blocks and on the text one, and disagree on exactly one block - content/docs/guide/architecture-overview.md:123, an ASCII-art plugin lifecycle diagram whose first line is an indented `import 'plugin-kanban'`. It is not TypeScript; the strict reading is used and the case is pinned in the self-test. LINT, narrowed with the narrowing measured - and the measurement CORRECTED a claim in my own first PR body draft: eslint --print-config resolves 116 rules for the .test.ts file and ZERO for both .mjs files, because eslint.config.js names only **/*.{ts,tsx} globs, so exactly one file in this diff is rule-linted; the .yml, .md and package.json each report 'File ignored because no matching configuration was supplied'; counts from --format json (eslint exit=0, 0 errors 0 warnings over the three files given); and no parserOptions.project / projectService, so this diff cannot move the verdict on any untouched file. The PR body was edited to say so. check:doc-snippets was NOT run locally and the narrowing is declared with evidence rather than asserted: ci-cd-pipeline.md holds 0 ts/tsx/typescript fences at origin/main and 0 at this head, and the diff on that file adds no fence-opening line at all, so the gate's population is provably unmoved; CI runs it unfiltered regardless.",
      "open_questions": [],
      "out_of_scope_findings": [
        "not filed as a card - reported here because it corrects this dispatch order's own premise, which said #6128/#6134/#6136/#6137 had landed. Measured: git log 133e2ea1e..origin/main is #6128, #6129, #6130, #6133, #6134 - five commits. #6136 (batch 4) and #6137 are NOT in origin/main; #6136 is still an open draft. The population move from 146/102 to 127/91 is therefore attributable entirely to the fields group - 19 blocks across 11 files, 17 from #6128 and 2 from #6134's location.mdx split (146-19=127, 102-11=91). Consequence for the next dispatch: the blocks (10) and plugins (12 of which 9) entries in the restated remainder are batch 4's own work, already taken in #6136, and will drop out of the baseline when it merges.",
        "fixed in this PR rather than filed, because it is the same defect class as the change that caused it and could not be left in the tree: scripts/dependabot-merge-gate.mjs partitions every check a PR produces into required and optional buckets, and an unclassified BLOCKING check is one it would let a Dependabot merge past. The new workflow carries no trigger-level path filter, so every PR produces 'Doc Fence Language Check'. Caught by scripts/__tests__/dependabot-merge-gate.test.ts - the pin that exists for exactly this - and registered in its own commit (71297422b). It is a one-line-per-list registration with a landed precedent for every sibling doc gate, in a file this diff had to touch anyway to stay honest.",
        "observation, not filed as a card: the 36 fenced blocks in the scan surface that carry NO info string at all are today the largest unpinned spelling. None of them is TypeScript right now - which is exactly why the guard could be landed body-driven with zero residue in that class - but they are also the one class where a future hidden block is cheapest to write, because an author adding a block simply omits the language. The guard catches it the moment it happens; what nothing does today is stop the empty info string being written in the first place. Collapsing bare fences onto ```plaintext would need 36 documents re-fenced, which is out of scope for this card and would be a docs-authoring convention change worth its own ruling."
      ]
    }

    Where the two deliverables ended up

    A is not a restated number in a handback — it is KNOWN_UNHIGHLIGHTED_TS_FENCES, 92 entries / 128 blocks, in the repository and shrink-only. The remainder table in #6144's body is generated from it, and a #5867 batch that re-fences blocks without lowering the map goes red. That is the same figure the next dispatch is built on, now unable to drift from the tree.

    C is scripts/check-doc-fence-languages.mjs. The mechanism was chosen by measurement and the reasoning is in the PR: an enumeration of allowed fence languages was rejected because the enumeration is the thing that rots and it fails silently, and it could not be landed in scope anyway (banning the bare info string alone demands 36 re-fences). Reading bodies takes the vocabulary off the enforcement path entirely, so the two failure modes the ruling asked for fall out of the design rather than being bolted on: a known synonym is auto-classifiable and baselineable, a spelling nobody has thought of is neither.


    Generated by Claude Code


    Generated by Claude Code

  4. yinlianghui-tw commented on Aug 24, 2026

    @yinlianghui-tw
    CollaboratorAuthor

    os-dev-report

    ⚠️ Supersedes the report above. That one's totals (128 blocks / 92 files) were measured at bfdb9f906 and went stale while the branch was open — #6136 and #6137 merged and re-fenced 23 blocks across 9 files. The gate caught it itself, red on its first CI run, naming all nine files with the remedy printed. Corrected report below; PR #6144 is green and still a draft.

    {
      "issue": 6135,
      "status": "done",
      "branch": "claude/issue-6135-fence-language-population",
      "pr": "https://github.com/objectstack-ai/objectui/pull/6144",
      "premise_still_valid": true,
      "summary": "Route A then C as ruled. A: population re-derived with the gate's own listDocuments and a byte-for-byte copy of its run-length fence walk, the language set being the only parameterised difference. On the final base 228909995 - plaintext alone is 104 blocks / 82 files, plaintext+text+plain is 105/83, and adding txt and the empty info string moves it no further. The delta is +1 block / +1 file, the block the card named, content/docs/components/form/file-upload.mdx:27. Control: the same derivation reproduces the card's 146/102 and 147/103 exactly at 133e2ea1e. The PM's predicted 128-23=105/83 is confirmed by the measurement rather than assumed. C: scripts/check-doc-fence-languages.mjs, its own install-free workflow, a 20-test pin file and a 26-case --self-test. The guard reads block BODIES with triage's classifier quoted verbatim rather than pinning a list of languages, so the fence spelling never decides WHETHER a block fails and txt, console, raw and a bare fence are closed by construction. Two failure modes reported apart: a KNOWN unhighlighted spelling (auto-classifiable, mechanical remedy, baselineable) and a spelling nobody has thought of (a human's call, never baselineable, zero in the tree). KNOWN_UNHIGHLIGHTED_TS_FENCES is #5867's remaining population per file - 83 entries, 105 blocks - shrink-only in #6133's exact shape. No document was re-fenced; the classifier, UNGATED_DOCS, the ledger and check-doc-snippet-types.mjs are untouched and no FRAGMENT_MARKER was declared. file-upload.mdx is labelled in the map as in-population and not-yet-fixable with both reasons (#6132 blocks the group; #6138 measured that a block declaring its own interface compiles vacuously). Second defect found and fixed in its own commit: the new workflow produces a blocking check scripts/dependabot-merge-gate.mjs did not classify, which is a check it would have let a Dependabot merge past.",
      "tests": "All at final head 072dfe8f9, pushed at that same head, git status --porcelain empty at run time. Branch brought current with git merge origin/main twice - never rebase, never force-push. Heavy runs through the shared verify lock, reading its VERDICT line. Exit codes captured before any pipe; each gate quoted by ITS OWN verdict line. THE HEADLINE READING, and it is the best non-vacuity evidence in the PR because nobody staged it: check:doc-fences went RED on its first CI run with '9 stale KNOWN_UNHIGHLIGHTED_TS_FENCES entry/entries' - block-schema.mdx baselined at 10 now carries 0, fields/auto-number at 2 now 0, fields/object at 2 now 0, and six plugins pages - because #6136 and #6137 merged underneath the branch and re-fenced 23 blocks across exactly those 9 files. Remedy followed literally: the nine zero lines deleted, population RE-DERIVED on the merged base rather than subtracted, and the diff of old map against new is nine deletions with no line added and no number raised. The staleness check was not weakened and the baseline is not pinned to a commit. GATES at the final head: check:doc-fences --self-test exit=0 '26 cases pass - a TypeScript block fenced text, txt, plain or with no info string at all is found and NAMED, the same block fenced ts/tsx/typescript is not, an unrecognised spelling is the second failure mode and is never baselined, triage's classifier is quoted rather than widened, and the shrink-only baseline is pinned in every direction it can move.'; check:doc-fences exit=0 'every TypeScript block in 222 document(s) is fenced ts/tsx/typescript, except 83 declared file(s) carrying 105 block(s) of objectui#5867's remaining population (SHRINK-ONLY). No unknown fence spelling hides one.'; check:entry-guard exit=0 '42 scripts/ file(s) - no entry guard outside the baseline' (the new gate uses isEntrypoint, so KNOWN_HAND_TYPED_GUARDS does not grow); check:doc-types exit=0 'Every documented component type is registered.'; docs:check-links exit=0 'Links are valid across 15 scan roots.'; check:control-bytes exit=0 'OK (scanned 5094 tracked text file(s); skipped 85 binary)' plus a self-scan of the changed files, zero hits; check:changeset-presence exit=0 'No source of a released package changed in this range, so no changeset is owed.'; check:changeset-fixed exit=0; check:changeset-no-major exit=0; check:lint-coverage exit=0 '46/46 packages linted'. VITEST from the repo ROOT, never package-scoped: 'Test Files 70 passed (70), Tests 1914 passed (1914)' over scripts/, re-run after each merge. type-check:scripts exit=0, no diagnostics. THE SECOND MERGE WAS CHECKED RATHER THAN ASSUMED: it takes #6142, which edits five content/docs/components pages this baseline owes lines for; those edits change block bodies not fences, the map is byte-identical across the merge, and the gate is green on the merged tree - stated because it is the same hazard the red run was about. ABLATION, on disk, through the shipped gate process, every leg proving its mutation by grepping the injected marker BEFORE any result was read and restoring under trap EXIT INT TERM with git checkout HEAD dash-dash followed by the path (never the bare form), git status --porcelain empty afterwards: clean tree exit=0; a text-fenced TS block in an unbaselined file exit=1 naming 'content/docs/guide/ci-cd-pipeline.md:1368 [text] - interface ObjectUI6135ProbeSchema {'; the same at txt exit=1; the same with NO info string exit=1 reported as '(no info string)'; the same block corrected to a ts fence exit=0; a console-fenced TS block exit=1 as the UNKNOWN mode with both remedies and 'never baselined'; an 11th hidden block in a file baselined at 10 exit=1 'baselined at 10; it now carries 11'; one hidden block REMOVED from that file exit=1 STALE 'baselined at 10, now carries 9'; and PROSE under a text fence exit=0, the leg that proves the classifier was quoted rather than widened. The fix was committed BEFORE any ablation leg. MEASURED CLASSIFIER EDGE, reported because the template's expected direction did not hold: 'first line' read literally versus leading-whitespace-tolerant agree on every plaintext block in the tree and on the text one, and disagree on exactly one block - content/docs/guide/architecture-overview.md:123, an ASCII-art plugin lifecycle diagram whose first line is an indented import of 'plugin-kanban'. Not TypeScript; the strict reading is used and the case is pinned in the self-test. LINT, narrowed with the narrowing measured - and the measurement CORRECTED a claim in my own first PR body draft: eslint --print-config resolves 116 rules for the .test.ts file and ZERO for both .mjs files, because eslint.config.js names only ts/tsx globs, so exactly one file in this diff is rule-linted; the .yml, .md and package.json each report 'File ignored because no matching configuration was supplied'; counts from --format json (eslint exit=0, 0 errors 0 warnings over the three files given); no parserOptions.project / projectService, so this diff cannot move the verdict on any untouched file. The PR body says so. check:doc-snippets NOT run locally, narrowing declared with evidence: ci-cd-pipeline.md holds 0 ts/tsx/typescript fences before and after and the diff on it adds no fence-opening line at all, so that gate's population is provably unmoved; CI runs it unfiltered regardless.",
      "open_questions": [],
      "out_of_scope_findings": [
        "fixed in this PR rather than filed, because it is the same defect class as the change that caused it and could not be left in the tree: scripts/dependabot-merge-gate.mjs partitions every check a PR produces into required and optional buckets, and an unclassified BLOCKING check is one it would let a Dependabot merge past. The new workflow carries no trigger-level path filter, so every PR produces 'Doc Fence Language Check'. Caught by scripts/__tests__/dependabot-merge-gate.test.ts - the pin that exists for exactly this - and registered in its own commit. A one-line-per-list registration with a landed precedent for every sibling doc gate.",
        "observation, not filed as a card: the 36 fenced blocks in the scan surface carrying NO info string at all are the largest unpinned spelling. None is TypeScript right now - which is why the guard could land body-driven with zero residue in that class - but it is the class where a future hidden block is cheapest to write, since an author simply omits the language. The guard catches it the moment it happens; nothing stops the empty info string being written. Collapsing bare fences onto plaintext would need 36 documents re-fenced, out of scope here and worth its own ruling as a docs-authoring convention change.",
        "process observation for the next #5867 dispatch, worth more than a card: the lane's population is now IN THE REPO and shrink-only, so a batch that re-fences blocks without lowering KNOWN_UNHIGHLIGHTED_TS_FENCES in the same PR turns the gate red - and a batch that merges while another branch holds a stale copy turns THAT branch red, which is what happened here. Both are the intended behaviour and both are cheap to fix (delete or lower the lines, re-derive). What the dispatch should carry forward is that the remainder table no longer needs re-deriving per batch: read the map. Current state after this PR: components 72/72 (#6132), layout 12/3 (#6120), core 11/1 (#6121), UNGATED_DOCS 7/6 (leave), plugins 3/1 (plugin-dashboard.mdx, #6122). blocks and fields are complete."
      ]
    }

    Generated by Claude Code


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:dispatchedtooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions