readme derivation: a prose interval no longer opens a link, and pin the generator - #6
Conversation
|
Second defect, found once the sweep could get past Three snapshots quote std source — core’s Disentangled from the compiler version rather than assumed: on one 1.97.1 toolchain against one tree, the suite fails 3 of 7 without The trap that closes: Also verified under CI’s exact 1.97.1: Residual risk, unrelated to this PR
|
…tripper self-tests
The intra-doc link stripper matched `[text](Rust::path)` with a text run that
admitted `[`, so a half-open interval in the surrounding prose could serve as
the opening bracket for a link further on. In `before`'s conceptual sketch the
run began at `{ [0, 1) }`, swallowed the prose up to the `]` of a real link two
lines later, and substituted its text for the whole span: the interval lost its
bracket and the link kept its own. Excluding `[` from the text resettles every
match onto the true opening bracket, since an inline link always brings one.
Newlines stay legal, as rustdoc wraps prose across lines.
`tools/readme self-test` pins the forms rewritten and the forms preserved,
including both shapes of this collision, and `readme-check` leads with it: a
stripping bug now names itself as a tool failure instead of arriving as
unexplained drift, or as corruption a regeneration quietly commits.
`crates/before/README.md` returns to its pre-corruption bytes exactly.
CI installed cargo-rdme at whatever version was newest. The derived READMEs are
compared byte for byte against what it emits, so 2.1.0's arrival redefined the
expected bytes and the sweep went red on trees nobody had touched; the version
is now pinned. With the stripper fixed, 1.5.1 and 2.1.0 render both READMEs
identically, so the pin buys reproducibility rather than a required upgrade.
Three compile-fail snapshots quote std source: core's `panic!` expansion in the zero-length-split cases, and `BitOr::bitor` / `Into::into` in the use-after-move case. rustc prints those lines only when the sources are installed, so on a toolchain without rust-src the quotations collapse to a bare `$RUST` path or a `= note:` line and `clock_into_empty_array`, `party_into_empty_array`, and `clock_use_after_move` mismatch. The CI toolchain asked for clippy and rustfmt alone, so it had never rendered them. The component is the cause, not the compiler version: on one 1.97.1 toolchain and one tree, the suite fails 3 of 7 without rust-src and passes 7 of 7 with it. The committed snapshots are correct as they stand, and hold byte-identical across 1.96.1 and 1.97.1 once the sources are present. The trap this closes is the blessing: `TRYBUILD=overwrite` on a machine that cannot see std would turn the sweep green by trading these diagnostics for weaker ones, and would then fail on every machine that can. The test's module doc and the setup list in AGENTS.md both name the requirement so the next mismatch routes to the component instead.
…rminal Sampling the suite while diagnosing the sweep turned up a counterexample distinct from the pinned one: a two-sided fan where the left supply fails on a Read 74 operations in, chunked at 2. It exercised the same terminal-ordering defect and passes under the current rule, so it rides along as an independent witness — the pinned pair now covers an Accept-time failure with a long delay train and a Read-time failure deep into a byte-chunked stream.
59f9076 to
7e7d673
Compare
…al std cargo-fuzz defaults `--target` to the triple it was itself built for rather than the host's. A statically linked prebuilt — what the CI installer ships — therefore aimed the build at `x86_64-unknown-linux-musl`, and it failed twice over: the sanitizer rejects a statically linked libc outright, and that target's std was never installed, so `core` was missing. A source-built cargo-fuzz hides this entirely, its own triple being the host's. Both recipes now name the host, leaving them indifferent to how cargo-fuzz arrived. Verified with a build and a one-second smoke of each target.
|
Third defect, reached once the sweep cleared cargo-fuzz defaults Both fuzz recipes now name the host triple explicitly, so they are indifferent to how cargo-fuzz arrived. Verified locally with a full Worth noting what this cost: three defects, each invisible until the one before it was fixed. |
…ument naming
Prose/structure only; zero behavior change; zero meter movement (full
suite 775 green, board 2014/2014 green, worst-case pin clean at both
scales). Per the five syntheses plus the narration-delta relay block.
Vocabulary minting (the campaign's dominant friction genre), applied on
prescan.rs's italicized-first-use model:
- *plateau* minted in skyline.rs where the step function is introduced
(tick F3; overlay.rs's layer-local definition stands).
- *left-full site* minted in fill.rs's module doc beside the arms, with
the narration's full-child ground-truth sentence (relay 5); memo.rs
keeps a back-reference (tick F3).
- *min-into-max* minted at watermark.rs's first use with the
merge_into_wider gloss (integral F6, tick F3).
- *priced by* minted once in overlay.rs's Cost section (foundations
vocabulary finding) and made reachable from watermark.rs's cost
bullet (relay 3 — the tick reader's independent stall).
- *range*/*frame* reconciled by a dual mint at watermark.rs's first use
(a range is the client's bracket; the web holds one frame per open
range). Deviation from the charter's "pick one": the narration delta's
C2 repackage-don't-rewrite constraint and the relay-8 guard protect
praised sentences spelled in both words; the dual mint reaches the
same goal (no reader wonders whether they differ) without rewriting
them.
- height-split components B/P/L and F/L named in query.rs's split
section (integral F1); "both width currencies" named as touch and
limb (integral F4); judge.rs's ladder axes fixed as sampling scale x
size and used consistently (integral F9), with the sparse-lumpy
errs-red direction stated at trend (integral F10).
Thread and aim repairs:
- integral.rs P-bullet re-cut with the forward link to the promotion
ledger and Integrator::frozen (integral F2); ledger-settle bullet
split into funded sub-bullets (integral F3); Complexity address
re-aimed at Version::{rank,distance,lag} with rename-protected links
(integral F5).
- query.rs min_ticks bullet redeems the closes-count koan with the
web-submodule pointer (relay 4).
- grow.rs +k compounding names fill's raising mechanism (streams F1).
- text.rs merge doc gains the frame-free identity lift =
floor(right) - floor(left) (streams F3); the parse bullet glosses
*top*, splits the pin sentence, and states the schoolbook twin's role
plainly (streams F2).
- walk.rs's claim scoped to the single-stream leaf passes with
two-way cross-links to overlay's LeafCursor; no structural
unification (foundations #1). walk added to the root doc's machinery
tour; literal/walk mod declarations gain one-line comments
(foundations #3).
- masked.rs roster states what step's code shows — mask slots free,
A/B relative order the one committed-reading freedom, order
arbitrary-but-pinned (foundations #6, transcription form per relay
10).
- watermark.rs gains # The arming paths (three entry points,
preconditions, first-arm capability — tick F4) and emit_offset's
five-path map with the deliberate non-restore named (tick F5);
followers get the purpose/deferral sentence (relay 9) and the
anchor-relative story its park() pointer (relay 7). All praised
sentences preserved verbatim (relay 8 guard; C2).
- place.rs module doc states the probe-is-every-pair's-a orientation up
front (relay 2); walk's doc states the flatten drop/finish agreement
obligation and all three flatten callers carry their per-verdict
argument (relay 1 — the delta's top latent finding).
- fill.rs IdNode::Empty arm upgraded to the reachability + mechanism +
keep-rationale model (relay 6).
Cursor-set unification (verdicts seed-dispute): filter.rs's
MemberCursors/SpanCursors now own their walk state (probe/endpoint
cursors, live flags, sides) exactly as place.rs's Cursors — the borrow
checker allowed it without contortion; the read loops reach the sides
through the fields. masked/place shapes untouched (the delta's C4:
their difference is principled). Write sequences unchanged; placement
identity rows and the full board byte-green.
Instrument naming (tick #1, F1): the two lower-bound genres are named
apart file-wide in tests/meter.rs — derived *liveness floors* (trip =
the mechanism's irreducible work left the metered representation:
investigate) vs measured-x0.75 *improvement tripwires* (trip = the
reading dropped >25% below the pin: attribute and re-pin). The file
doc mints both; HIFLOOR_TOUCH_FLOOR -> HIFLOOR_TOUCH_TRIPWIRE,
reveal_comb's inline bound -> REVEAL_COMB_TOUCH_TRIPWIRE, envelope
column docs and every trip message re-denominated to their genre.
PURE_COMB_TOUCH_FLOOR and ASCEND_CLIFF_TOUCH_FLOOR keep the liveness
name they already earn.
memo_resolution_cost::tick_run floor (tick #2/F2): re-derived
premise-first to the reveal module's per-limb structure — one touch
per 64-bit limb of every consumed code's magnitude, with the family
premise stated (folded payload at least an eighth of the packed
input). Constant old -> new: one-per-input-byte -> one-per-eight-
input-bytes (the old x1 was a per-delta derivation asserted per byte,
subsidized by narrow-delta families). Readings unmoved; the floor is a
liveness check, not a tightness contest.
Owner counterweight (dissolve/link/mint, per term — binding ruling applied retroactively to the T2 lexicon): - min-into-max: DISSOLVED — every site now names suanpan's merge_into_wider plainly (the narrower buffer folds into the wider), linked once at the close bullet. - range/frame: resolved by DELETING "frame" from watermark.rs — the web's word is now "range" everywhere (prose, field docs, assert messages); "range" keeps its one definition (the client's bracket, never interpreted by the web). fill.rs's one "watermark frame" phrase re-denominated. - plateau: LINKED — overlay.rs's tiling vocabulary keeps the one mint; skyline.rs carries a plain gloss naming overlay as the minting site (a public->private intra-doc link cannot resolve on the public build). - "both width currencies": DISSOLVED into "both the touch and limb counters". - B/P/L and F/L component names: LINKED — named plainly in query.rs with the pointer to integral.rs's existing mints, no re-mint. - priced/paid-by, left-full site, settled (filter.rs), liveness-floor/improvement-tripwire: MINTED (each spent widely enough that per-use restatement costs more; the first two per the owner's own examples). - full child: LINKED to IdNode::Full (the API's own name). Polish implemented (by synthesis numbering): - foundations #5 (walk.rs/overlay.rs internal Panics sections adopt the precise truncation/malformation-vs-silent contract, pointing at causal_cmp's canonical statement), #7 (Extremum reset-policy comparison + provenance contract, grounded in the pool's clear-on-retire), #8 (CursorSet absent-slot lemma written out; priority's commutative-sums freedom stated), #9 (GAMMA_SMALL_MAG_BOUND named with its derivation, both twins), #10 (root-doc micro-frictions: first sentence, zigzag letter d vs code-shape k, gamma-covers-zero clause, codec-cursor reference), #11 (Step vs Signed distinction), #12 (block-scan honesty leads the skip docs), #13 (overlay layer-map sentence split), #14 (numeric flip<=depth restatement), #15 (IdLeafCursor pop-flip survival comment + idbits packed-coding pointer), #16 (advance's unexhausted precondition), #17 (sweep early-exit Break-carries-V reworded); delta latent items: the advance dual-channel why (callback = order, return = crossings), masked.rs Directions::relation link. - verdicts #6 (admit.rs "placement walk's idiom" misattribution dropped at both sites — restated-not-reused, fallibility argument kept), #7 (masked height integrators fold plainly via fold_signed_int; the Side::A polarity pun and its rescue comments gone), #9 (settled minted at Pair::live), #11 (end-first arbitrariness stated), #12 (trichotomy glossed as the comparison trichotomy), #13 (/* negative: */ argument comments at the literal seeding sites, uniformly), #14 (validate.rs first-leaf zero_delta defense), #15 (admit.rs rewrap), #16 (subsumption's pointwise no-block-skipping premise), #17 (filter.rs Cost names the per-interval bookkeeping scans); delta: Demand::After/Before inclusivity reminders at both downstream re-check sites. - streams F5 (grow Phase 2 absolute-code case), F6 (emit sticky-tie seed comments + placeholder note), F7 (build absorb-pop lens comment), P1 (re-anchor gloss), P2 (delta_code takes Option<&Step>), P3 (merge per-step comments). - integral P1 (one's why-a-field), P3 (pair_fold unwrap_or(1) declared unreachable-but-total), P4 (feeds garden path resolved in the Cost list), P5 (rank Cost paragraph as a charge list + the four-structure map sentence), F7 (top-index domination appositive), F8 (forward/ reverse dual names dropped for plain statements), F11 (jump-pair family named at the jump-comb parenthetical), F12 (carry-cliff and comb-teeth glosses), F13 (resolve_latent's caller obligation stated abstractly). - tick F6 (one-web-range-per-Frames-entry comment at the single close), F7 (FillWalk/PreScan field stack -> web, matching query/web.rs), F8 (Relation::Min <-> REL_FOLLOWER invariant on the type), F9 (FOLLOWER_SLOTS pub(super) + const assert binding the slot roster across files), F14 covered by the propagate doc's existing narration (loop-invariant comment deferred: see report), F15 (level-vs-depth caution at the twin declaration), F16 (level-0 keeper exemption), F17 (recorder invariant block), F18 (replay_max why-not-park), F19 (the twelve-line measurement roster reduced to claim + pointer), F20 (close() doc: fill discards the outcome entirely; min-ticks dispatches all four arms) [in close()'s payload sentence], F21 (emit_offset's constant-true note_match as a debug-asserted match), F22 (Out::leaf # Panics heading), F23 (copy_subtree regime map), F24 (compact()'s two-digits-cover-a-u64 derivation); tick polish: the two precondition-shaped assert messages restated as invariants, materialize's sign() collapse idiom matched to the explained spelling, walk()'s derived-depth comment, emit_step's deliberately- unread step comment, RouteProbe's Cost::MAX-as-don't-care and id_span fallback notes, the watermark representation paragraph as a list with the derivation sentence standing alone (relay-8 guard honored), the undercut bullet as sub-bullets, the cost essay's first-read gate, new()/compacting() pointing at their committed families, ascend-cliff floor's created/penetrated split, both derived floors scoped to their mechanism with the floor-premise escape stated. Zero meter movement: full suite 775 green, board 2014/2014 green, worst-case pin clean (172 rows, both scales), clippy clean on default and --all-features. validate_bits gated to test/meter (its production consumer is gone), keeping the default build warning-free.
…ument naming
Prose/structure only; zero behavior change; zero meter movement (full
suite 775 green, board 2014/2014 green, worst-case pin clean at both
scales). Per the five syntheses plus the narration-delta relay block.
Vocabulary minting (the campaign's dominant friction genre), applied on
prescan.rs's italicized-first-use model:
- *plateau* minted in skyline.rs where the step function is introduced
(tick F3; overlay.rs's layer-local definition stands).
- *left-full site* minted in fill.rs's module doc beside the arms, with
the narration's full-child ground-truth sentence (relay 5); memo.rs
keeps a back-reference (tick F3).
- *min-into-max* minted at watermark.rs's first use with the
merge_into_wider gloss (integral F6, tick F3).
- *priced by* minted once in overlay.rs's Cost section (foundations
vocabulary finding) and made reachable from watermark.rs's cost
bullet (relay 3 — the tick reader's independent stall).
- *range*/*frame* reconciled by a dual mint at watermark.rs's first use
(a range is the client's bracket; the web holds one frame per open
range). Deviation from the charter's "pick one": the narration delta's
C2 repackage-don't-rewrite constraint and the relay-8 guard protect
praised sentences spelled in both words; the dual mint reaches the
same goal (no reader wonders whether they differ) without rewriting
them.
- height-split components B/P/L and F/L named in query.rs's split
section (integral F1); "both width currencies" named as touch and
limb (integral F4); judge.rs's ladder axes fixed as sampling scale x
size and used consistently (integral F9), with the sparse-lumpy
errs-red direction stated at trend (integral F10).
Thread and aim repairs:
- integral.rs P-bullet re-cut with the forward link to the promotion
ledger and Integrator::frozen (integral F2); ledger-settle bullet
split into funded sub-bullets (integral F3); Complexity address
re-aimed at Version::{rank,distance,lag} with rename-protected links
(integral F5).
- query.rs min_ticks bullet redeems the closes-count koan with the
web-submodule pointer (relay 4).
- grow.rs +k compounding names fill's raising mechanism (streams F1).
- text.rs merge doc gains the frame-free identity lift =
floor(right) - floor(left) (streams F3); the parse bullet glosses
*top*, splits the pin sentence, and states the schoolbook twin's role
plainly (streams F2).
- walk.rs's claim scoped to the single-stream leaf passes with
two-way cross-links to overlay's LeafCursor; no structural
unification (foundations #1). walk added to the root doc's machinery
tour; literal/walk mod declarations gain one-line comments
(foundations #3).
- masked.rs roster states what step's code shows — mask slots free,
A/B relative order the one committed-reading freedom, order
arbitrary-but-pinned (foundations #6, transcription form per relay
10).
- watermark.rs gains # The arming paths (three entry points,
preconditions, first-arm capability — tick F4) and emit_offset's
five-path map with the deliberate non-restore named (tick F5);
followers get the purpose/deferral sentence (relay 9) and the
anchor-relative story its park() pointer (relay 7). All praised
sentences preserved verbatim (relay 8 guard; C2).
- place.rs module doc states the probe-is-every-pair's-a orientation up
front (relay 2); walk's doc states the flatten drop/finish agreement
obligation and all three flatten callers carry their per-verdict
argument (relay 1 — the delta's top latent finding).
- fill.rs IdNode::Empty arm upgraded to the reachability + mechanism +
keep-rationale model (relay 6).
Cursor-set unification (verdicts seed-dispute): filter.rs's
MemberCursors/SpanCursors now own their walk state (probe/endpoint
cursors, live flags, sides) exactly as place.rs's Cursors — the borrow
checker allowed it without contortion; the read loops reach the sides
through the fields. masked/place shapes untouched (the delta's C4:
their difference is principled). Write sequences unchanged; placement
identity rows and the full board byte-green.
Instrument naming (tick #1, F1): the two lower-bound genres are named
apart file-wide in tests/meter.rs — derived *liveness floors* (trip =
the mechanism's irreducible work left the metered representation:
investigate) vs measured-x0.75 *improvement tripwires* (trip = the
reading dropped >25% below the pin: attribute and re-pin). The file
doc mints both; HIFLOOR_TOUCH_FLOOR -> HIFLOOR_TOUCH_TRIPWIRE,
reveal_comb's inline bound -> REVEAL_COMB_TOUCH_TRIPWIRE, envelope
column docs and every trip message re-denominated to their genre.
PURE_COMB_TOUCH_FLOOR and ASCEND_CLIFF_TOUCH_FLOOR keep the liveness
name they already earn.
memo_resolution_cost::tick_run floor (tick #2/F2): re-derived
premise-first to the reveal module's per-limb structure — one touch
per 64-bit limb of every consumed code's magnitude, with the family
premise stated (folded payload at least an eighth of the packed
input). Constant old -> new: one-per-input-byte -> one-per-eight-
input-bytes (the old x1 was a per-delta derivation asserted per byte,
subsidized by narrow-delta families). Readings unmoved; the floor is a
liveness check, not a tightness contest.
Owner counterweight (dissolve/link/mint, per term — binding ruling applied retroactively to the T2 lexicon): - min-into-max: DISSOLVED — every site now names suanpan's merge_into_wider plainly (the narrower buffer folds into the wider), linked once at the close bullet. - range/frame: resolved by DELETING "frame" from watermark.rs — the web's word is now "range" everywhere (prose, field docs, assert messages); "range" keeps its one definition (the client's bracket, never interpreted by the web). fill.rs's one "watermark frame" phrase re-denominated. - plateau: LINKED — overlay.rs's tiling vocabulary keeps the one mint; skyline.rs carries a plain gloss naming overlay as the minting site (a public->private intra-doc link cannot resolve on the public build). - "both width currencies": DISSOLVED into "both the touch and limb counters". - B/P/L and F/L component names: LINKED — named plainly in query.rs with the pointer to integral.rs's existing mints, no re-mint. - priced/paid-by, left-full site, settled (filter.rs), liveness-floor/improvement-tripwire: MINTED (each spent widely enough that per-use restatement costs more; the first two per the owner's own examples). - full child: LINKED to IdNode::Full (the API's own name). Polish implemented (by synthesis numbering): - foundations #5 (walk.rs/overlay.rs internal Panics sections adopt the precise truncation/malformation-vs-silent contract, pointing at causal_cmp's canonical statement), #7 (Extremum reset-policy comparison + provenance contract, grounded in the pool's clear-on-retire), #8 (CursorSet absent-slot lemma written out; priority's commutative-sums freedom stated), #9 (GAMMA_SMALL_MAG_BOUND named with its derivation, both twins), #10 (root-doc micro-frictions: first sentence, zigzag letter d vs code-shape k, gamma-covers-zero clause, codec-cursor reference), #11 (Step vs Signed distinction), #12 (block-scan honesty leads the skip docs), #13 (overlay layer-map sentence split), #14 (numeric flip<=depth restatement), #15 (IdLeafCursor pop-flip survival comment + idbits packed-coding pointer), #16 (advance's unexhausted precondition), #17 (sweep early-exit Break-carries-V reworded); delta latent items: the advance dual-channel why (callback = order, return = crossings), masked.rs Directions::relation link. - verdicts #6 (admit.rs "placement walk's idiom" misattribution dropped at both sites — restated-not-reused, fallibility argument kept), #7 (masked height integrators fold plainly via fold_signed_int; the Side::A polarity pun and its rescue comments gone), #9 (settled minted at Pair::live), #11 (end-first arbitrariness stated), #12 (trichotomy glossed as the comparison trichotomy), #13 (/* negative: */ argument comments at the literal seeding sites, uniformly), #14 (validate.rs first-leaf zero_delta defense), #15 (admit.rs rewrap), #16 (subsumption's pointwise no-block-skipping premise), #17 (filter.rs Cost names the per-interval bookkeeping scans); delta: Demand::After/Before inclusivity reminders at both downstream re-check sites. - streams F5 (grow Phase 2 absolute-code case), F6 (emit sticky-tie seed comments + placeholder note), F7 (build absorb-pop lens comment), P1 (re-anchor gloss), P2 (delta_code takes Option<&Step>), P3 (merge per-step comments). - integral P1 (one's why-a-field), P3 (pair_fold unwrap_or(1) declared unreachable-but-total), P4 (feeds garden path resolved in the Cost list), P5 (rank Cost paragraph as a charge list + the four-structure map sentence), F7 (top-index domination appositive), F8 (forward/ reverse dual names dropped for plain statements), F11 (jump-pair family named at the jump-comb parenthetical), F12 (carry-cliff and comb-teeth glosses), F13 (resolve_latent's caller obligation stated abstractly). - tick F6 (one-web-range-per-Frames-entry comment at the single close), F7 (FillWalk/PreScan field stack -> web, matching query/web.rs), F8 (Relation::Min <-> REL_FOLLOWER invariant on the type), F9 (FOLLOWER_SLOTS pub(super) + const assert binding the slot roster across files), F14 covered by the propagate doc's existing narration (loop-invariant comment deferred: see report), F15 (level-vs-depth caution at the twin declaration), F16 (level-0 keeper exemption), F17 (recorder invariant block), F18 (replay_max why-not-park), F19 (the twelve-line measurement roster reduced to claim + pointer), F20 (close() doc: fill discards the outcome entirely; min-ticks dispatches all four arms) [in close()'s payload sentence], F21 (emit_offset's constant-true note_match as a debug-asserted match), F22 (Out::leaf # Panics heading), F23 (copy_subtree regime map), F24 (compact()'s two-digits-cover-a-u64 derivation); tick polish: the two precondition-shaped assert messages restated as invariants, materialize's sign() collapse idiom matched to the explained spelling, walk()'s derived-depth comment, emit_step's deliberately- unread step comment, RouteProbe's Cost::MAX-as-don't-care and id_span fallback notes, the watermark representation paragraph as a list with the derivation sentence standing alone (relay-8 guard honored), the undercut bullet as sub-bullets, the cost essay's first-read gate, new()/compacting() pointing at their committed families, ascend-cliff floor's created/penetrated split, both derived floors scoped to their mechanism with the floor-premise escape stated. Zero meter movement: full suite 775 green, board 2014/2014 green, worst-case pin clean (172 rows, both scales), clippy clean on default and --all-features. validate_bits gated to test/meter (its production consumer is gone), keeping the default build warning-free.
Main has been red since 2026-07-22; every failure is
readme-checkreportingcrates/before/README.mdout of date. Two defects stack up.The corruption. The intra-doc link stripper in
tools/readmematched[text](Rust::path)with a text run admitting[, so a half-open interval in the prose could open a link that closed at a later](path). Inbefores conceptual sketch the run began at{ [0, 1) }and ran to the]of a real link two lines on; substituting the text for that span ate the intervals bracket and left the links:Excluding
[from the text resettles every match onto the true opening bracket, since an inline link always brings its own. Newlines stay legal, as rustdoc wraps prose. The regeneratedcrates/before/README.mdis byte-identical to its pre-corruption blob (674dfbc8).The exposure. CI installed
cargo-rdmeat whatever version was newest, and the READMEs are compared byte for byte against what it emits. 2.1.0 resolves the[fork](Party::fork)form itself, so those links stopped reaching the buggy regex and the expected bytes changed with no commit in the repo. The version is now pinned; with the stripper fixed, 1.5.1 and 2.1.0 render both READMEs identically, so the pin buys reproducibility rather than forcing a local upgrade.Ratchet.
tools/readme self-testpins the forms rewritten and the forms preserved, both shapes of this collision included, andreadme-checkleads with it so a stripping bug names itself instead of arriving as drift or as corruption a regeneration commits. Verified as a tripwire: it reads red against the old character class, failing on exactly the two corrupted cases, and green with the fix.Verification
tools/readme self-testandreadme-checkpass under both cargo-rdme 1.5.1 and 2.1.0.fmt-check,doclint,testdocclean.include_str!, so the compile and doctest tiers are untouched; this PRs ownjust cirun is the full sweep.