Skip to content

readme derivation: a prose interval no longer opens a link, and pin the generator - #6

Merged
plaidfinch merged 4 commits into
mainfrom
fix/readme-derivation
Jul 29, 2026
Merged

readme derivation: a prose interval no longer opens a link, and pin the generator#6
plaidfinch merged 4 commits into
mainfrom
fix/readme-derivation

Conversation

@plaidfinch

Copy link
Copy Markdown
Collaborator

Main has been red since 2026-07-22; every failure is readme-check reporting crates/before/README.md out of date. Two defects stack up.

The corruption. The intra-doc link stripper in tools/readme matched [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). In befores 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:

-`Party::seed`, is `{ 0, 1) }`; a [`fork` splits an interval
+`Party::seed`, is `{ [0, 1) }`; a `fork` splits an interval

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 regenerated crates/before/README.md is byte-identical to its pre-corruption blob (674dfbc8).

The exposure. CI installed cargo-rdme at 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-test pins the forms rewritten and the forms preserved, both shapes of this collision included, and readme-check leads 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-test and readme-check pass under both cargo-rdme 1.5.1 and 2.1.0.
  • fmt-check, doclint, testdoc clean.
  • No Rust changes, and no crate pulls a README into its docs via include_str!, so the compile and doctest tiers are untouched; this PRs own just ci run is the full sweep.

@plaidfinch

Copy link
Copy Markdown
Collaborator Author

Second defect, found once the sweep could get past readme-check: the trybuild suite (before::compile_fail) failed 3 of 7 cases.

Three snapshots quote std source — core’s panic! expansion in the zero-length-split cases, BitOr::bitor / Into::into in the use-after-move case — and rustc prints those lines only when rust-src is installed. The CI toolchain requested clippy, rustfmt alone, so it had never rendered them; the quotations collapsed to a bare $RUST path or a = note: line.

Disentangled from the compiler version rather than assumed: on one 1.97.1 toolchain against one tree, the suite fails 3 of 7 without rust-src and passes 7 of 7 with it. So the component is the cause, the committed snapshots are correct as they stand, and they are byte-identical across 1.96.1 and 1.97.1 once the sources are present. No re-blessing, no toolchain pin.

The trap that closes: TRYBUILD=overwrite on a machine that cannot see std would turn CI green by trading these diagnostics for weaker ones, and would then fail on every machine that can. Both the module doc and the AGENTS.md setup list now name the requirement so the next mismatch routes to the component instead of to a blessing.

Also verified under CI’s exact 1.97.1: clippy -D warnings, cargo doc -D warnings, and the trybuild suite all clean.

Residual risk, unrelated to this PR

tree::mirror::streaming::remote::proxy::tests::failures::transport_failures_are_exact_and_fail_fast can fail on freshly generated input (has_expected_surface(error, operation), failures.rs:237). It reproduces under both 1.96.1 and 1.97.1, is independent of everything here, and is under separate investigation — so test-all may still go red probabilistically until that is resolved. No seed for it is committed here.

…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.
@plaidfinch
plaidfinch force-pushed the fix/readme-derivation branch from 59f9076 to 7e7d673 Compare July 29, 2026 16:15
…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.
@plaidfinch

Copy link
Copy Markdown
Collaborator Author

Third defect, reached once the sweep cleared test-all, doctest, and bench-build (19m of bench compile): fuzz-build failed.

cargo-fuzz defaults --target to the triple it was itself built for, not the host’s. taiki-e/install-action ships a statically linked prebuilt, so CI aimed the sanitizer build at x86_64-unknown-linux-musl and failed twice over — sanitizer is incompatible with statically linked libc, and can't find crate for core because that target’s std was never installed. A source-built cargo-fuzz hides this completely, its own triple being the host’s, which is why the tier passed on my machine.

Both fuzz recipes now name the host triple explicitly, so they are indifferent to how cargo-fuzz arrived. Verified locally with a full fuzz-build and a one-second smoke of each target.

Worth noting what this cost: three defects, each invisible until the one before it was fixed. readme-check sat fourth in the sweep, so nothing behind it had run on main since CI was added on 2026-06-19 — this repo’s CI has never once been green.

@plaidfinch
plaidfinch merged commit 1489395 into main Jul 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant