Uh oh!
There was an error while loading. Please reload this page.
fix(scripts): collect TypeScript fences opened inside a blockquote - #7100
Merged
Conversation
`scanFences` anchored a fence opener on leading spaces and tabs only, so a fence opened inside a Markdown blockquote carried a `> ` prefix the anchor never matched. The block was never collected and the gate compiled nothing for it, with no diagnostic: an uncollected block appears in no count and its page still reports as covered. The opener now tolerates a blockquote prefix and carries the opener's quote depth through the rest of the walk — the search for the closing fence reads candidates at that same depth, and body lines are stripped of that many markers before reaching the compiler. Depth 0 takes an identity path that returns the line unchanged byte for byte, so every unquoted fence in the corpus scans exactly as before. Measured over the gate's own 224-document population: 773 -> 774 collected blocks, nothing dropped. The one newly-visible block compiles. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012wwHa4aaFybxXrfmfHioDM
os-warren
marked this pull request as ready for review
September 1, 2026 00:13
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#7086
check-doc-snippet-typescollects blocks withscanFences, whose fence-opening anchor accepted a run of leading spaces and tabs and nothing else. A fence opened inside a Markdown blockquote carries a>prefix, so the anchor never matched, the block was never collected, and the gate compiled nothing for it. There was no diagnostic — an uncollected block appears in no count, and its page still reports as covered. A callout is a natural home for an import example, which is exactly the snippet class that rots when an export is renamed: the one class this gate exists to catch.Took option (a) of the three the card left open, per the dispatching PM's ruling. This is gate strengthening — restoring declared-equals-enforced on a gate that claimed to compile the docs' TypeScript and silently did not.
What changed
The opener now tolerates a blockquote prefix and carries the opener's quote depth through the rest of the walk:
stripQuotePrefixconsumes at most one space after each marker, per CommonMark, so indentation belonging to the snippet survives.Depth 0 takes an identity path that returns the line unchanged byte for byte. That is what keeps the other 773 collected blocks in the corpus scanning exactly as before, and it is pinned.
Carrying the depth to the closing fence is what makes this safe in both directions. Without it, a blockquoted fence would find no close and swallow the rest of the file; and a plain fence would be closed early by any quoted backtick line sitting inside it as prose. Both directions have a test.
The ledger movement, measured
The card warned that widening the anchor "may pull previously-invisible blocks into the compiled population, which is a ledger movement rather than a one-line edit". It is, and it is exactly one block:
Newly collected: 1 — the import callout at
content/docs/api/schema-reference.mdline 12. Its disposition: compiles clean. No longer collected: 0; nothing left the population. Block identity was compared by document, fence line, language and a hash of the body, so a block whose body merely changed shape would have shown as one removal plus one addition rather than silently matching.The card's sharpest handle reproduces and flips: importing the gate's own exported
scanFencesand running it over that page returned 2 collected blocks against 3 typescript fences before, and returns 3 now.Verification
Re-derived against
main@2c3cd1bbefore editing — every line number and count in the card still held:TS_FENCE_LANGUAGESat:317, the anchor at:587, acted on at:600; 224 documents; exactly 1 blockquoted ts/tsx/typescript fence, on the page the card named. The card's three controls all reproduce.Gate and tests, run on the final commit
e463ae1:eslinton both changed files: exit 0. All four changeset gates: exit 0.check-changeset-presenceverdict, quoted:✅ No source or published contract of a released package changed in this range, so no changeset is owed.— so the changeset here is the empty-frontmatter form, not apatchbump that would falsely claim a released package moved.Ablation. With the fix reverted to the
2c3cd1bblob (mutation confirmed on disk by hash and bystripQuotePrefixdropping to 0 occurrences), 3 of the 4 new pins fail and the gate's covered count falls back to 383/271. The fourth — the depth-0 identity guard — passes in both trees, which is correct: it pins pre-existing behaviour that this change must not move. Restore was proved byte-identical to theHEADblob, with a cleangit diff HEAD. No rebuild leg is owed here: the gate runs asnode scripts/check-doc-snippet-types.mjsand the test imports'../check-doc-snippet-types.mjs', both source paths, neither resolved through a packagedist.Scope
Confined to the collector's anchor and its prefix-stripping; the gate is not refactored. One bounded gap is deliberately left alone and filed separately as #7099:
FRAGMENT_MARKERand the marker-attachment walk are still blockquote-unaware, so a blockquoted block that legitimately cannot compile has no reachable escape hatch. Population there is 0 today (measured, with controls at 2900 plain openers and 112 plain markers), and a correct fix needs a second mechanism — the blank-line walk — which was outside this card's dispatched scope.Generated by Claude Code
Generated by Claude Code