Skip to content

fix(scripts): give a blockquoted doc snippet a reachable fragment marker (objectui#7099) - #7950

Merged
baozhoutao merged 2 commits into
mainfrom
claude/issue-7099-blockquote-fragment-marker
Sep 6, 2026
Merged

fix(scripts): give a blockquoted doc snippet a reachable fragment marker (objectui#7099)#7950
baozhoutao merged 2 commits into
mainfrom
claude/issue-7099-blockquote-fragment-marker

Conversation

@claude

@claude claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #7099

objectui#7086 brought a fence opened inside a Markdown blockquote under this gate's contract. That contract has two halves — a collected block must compile, or it must carry a fragment marker declaring why it cannot — and only the first half reached blockquotes. A quoted block that legitimately cannot compile was collected, failed, and had no declared way to say so; the author's only outs were to unindent the callout or to grow UNGATED_DOCS, a list that is meant only to shrink.

Two anchors in scanFences were blockquote-unaware:

  • FRAGMENT_MARKER was anchored ^[ \t]*, so > {/* doc-snippet: fragment ... */} did not register as a marker at all;
  • the attachment walk wants the nearest non-blank line above the fence, and '>'.trim() is '>', not the empty string — so even a marker that did register could not cross the bare > spacer that separates a callout's prose from its fence.

What changed

Both mechanisms move together, because widening the marker anchor alone would pass in tests and fail on the callout shape real pages use.

  • The marker is matched against the line with its blockquote prefix stripped (reusing stripQuotePrefix), and keeps the depth it was written at.
  • The attachment walk judges blankness at the fence's depth (isBlankAtDepth), so it crosses a callout's bare > spacer.
  • A marker declares only a fence at its own depth: a depth-0 marker above a quoted fence sits outside the callout the block lives in, and a quoted marker above an unquoted fence sits inside one the block is not in. Neither attaches, and an unattached marker is reported as stale-fragment-marker rather than silently dropped — previously a quoted marker was invisible to that check.
  • A failing collected block at depth > 0 now also names the depth its declaration must be written at, so a marker that did not attach is explained instead of guessed at.

Depth 0 keeps the identity path, so every unquoted fence scans exactly as before. What the gate accepts is unchanged: a fragment still requires its written reason, the marker grammar is untouched, and UNGATED_DOCS is not touched.

Population, and why the pins carry the proof

The reachable population is 0 today and stays 0, so this behaviour proves itself in the pins, not in the corpus. Read on the merged tree, before and after, through the gate's own document list:

reading before after
blockquoted fragment markers (the population) 0 0
control: plain fence openers 2978 2978
control: plain fragment markers 158 158
control: blockquoted fence openers 2 2

The gate's verdict lines are byte-identical before and after, measured on the same merged corpus by reverting these two files to 58153d9c7 and re-running:

Scanned 227 document(s): 203 covered (101 of them hold a ts/tsx block), 24 ungated — declared in this script, NOT verified by it.
Covered blocks: 635 — 477 to compile, 158 declared fragment(s).
Syntax phase:   every block parsed, so every one of them reached the semantic phase.
Root bound:     no block imports a specifier that resolves only through this repository's ROOT manifest.
Semantic phase: 477 of 477 block(s) judged, 0 failed.

No page gains or loses coverage. (Covered blocks moved from 625 to 635 between the branch point and now — that is #7929 batch 13 shrinking UNGATED_DOCS by one page, merged into this branch, not this change.)

Pins, and the ablation that makes them non-vacuous

Five new pins in scripts/__tests__/check-doc-snippet-types.test.ts, all red before the fix and green after (full file: 88 passed):

  1. a blockquoted marker directly above a blockquoted fence — attaches;
  2. the callout shape — marker, bare > spacer, then the fence — attaches;
  3. a marker at a different depth than its fence — does not attach, in both directions;
  4. the unquoted path unchanged — a depth-0 marker still attaches across blank lines;
  5. an unattached blockquoted marker is reported rather than never seen.

Each ablation leg was run against the committed implementation, mutated on disk with the mutation proved by occurrence counts, and restored with git checkout HEAD -- <path> verified by blob hash equal to HEAD's and an empty git diff HEAD:

  • revert the marker anchor alone → pins 1, 2, 3 and 5 fail (4 failed | 11 passed);
  • revert the blank-line walk alone → only pin 2, the callout case, fails (1 failed | 14 passed), while pin 1, the adjacent case, still passes.

That asymmetry is the half-fix the card warned about, reproduced deliberately: widening the anchor alone works in tests and fails on the shape real pages use.

Verification

Run at f6b860f2d:

  • pnpm check:doc-snippets — exit 0, verdict lines above
  • pnpm exec vitest run scripts/__tests__ — 107 files, 3225 tests passed
  • pnpm type-check:scripts — exit 0
  • pnpm lint:root — exit 0 (32 pre-existing warnings, none in these two files)
  • pnpm check:control-bytes — OK, 6410 tracked text files scanned
  • node scripts/check-changeset-presence.mjs — no changeset owed (no published source or contract changed)
  • node scripts/check-governed-queue-guard.mjs --test <the two paths> — NOT GOVERNED

Generated by Claude Code

…ker (objectui#7099)

objectui#7086 brought a fence opened inside a blockquote under this gate's
contract, but that contract has two halves — a collected block must compile,
OR it must carry a fragment marker declaring why it cannot. Only the first
half reached blockquotes: `FRAGMENT_MARKER` was anchored `^[ \t]*`, so
`> {/* doc-snippet: fragment ... */}` did not register as a marker at all, and
the attachment walk wanted the nearest non-blank line above the fence while
`'>'.trim()` is `'>'`, not the empty string. A quoted block that legitimately
cannot compile was collected, failed, and had no declared way to say so; the
author's only outs were to unindent the callout or to grow `UNGATED_DOCS`.

Both mechanisms move together, because widening the anchor alone would pass in
tests and fail on the callout shape real pages use:

- the marker is matched against the line with its blockquote prefix stripped,
  and keeps the depth it was written at;
- the attachment walk judges blankness AT the fence's depth, so it crosses a
  callout's bare `>` spacer;
- a marker declares only a fence at its own depth — a depth-0 marker above a
  quoted fence sits outside the callout the block lives in, and a quoted marker
  above an unquoted fence sits inside one the block is not in.

Depth 0 keeps the identity path, so every unquoted fence scans exactly as
before: the corpus verdict lines are unchanged by this commit (227 documents,
625 covered blocks, 467 to compile, 158 declared fragments, 0 failed).

A failing collected block at depth > 0 now also names the depth its declaration
must be written at, so a marker that did not attach is explained rather than
guessed at.

The population this reaches is 0 today and stays 0 (0 blockquoted fragment
markers over the gate's own 227-document scan set, with the controls holding in
the same query: 2978 plain fence openers, 158 plain fragment markers), so the
behaviour proves itself in the pins rather than in the corpus.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(gate): a blockquoted doc snippet has no reachable fragment-marker escape hatch — population 0 today

2 participants