Rendered from docs/obligations/0176-a-blessed-fixture-is-read-by-a-sibling-case-that-runs-while-the-write-truncates-it.md in the Headwater
corpus. Every document on this half of the site is typed by the taxonomy
the descriptor names: corpus.json.
A blessed fixture is read by a sibling case that runs while the write truncates it
Context
Twenty-three test files of this workspace read HEADWATER_BLESS, and each one carries a compare helper of the same shape. Under the variable the helper calls std::fs::write(recorded, actual) and returns. std::fs::write truncates the file and then writes the new bytes, so the recorded path holds zero bytes for the length of the call.
cargo runs the cases of one test target as threads of one process. In engine/crates/conformance/tests/render.rs two cases name one path. the_report_wraps_every_line_to_the_width passes fixtures_dir().join("wrapped.report") to compare, which is the writer. the_recorded_block_is_the_one_this_width_produces calls std::fs::read_to_string on the same path, and it does that whether or not the variable is set. So a blessed run has a reader and a writer of one file in two threads with nothing between them.
The reader panics on what it can see. An empty read reaches .expect("the recorded block has lines") through a max() over no lines. A partial read reaches an assertion that the longest line is over WIDTH - 12, which a truncated block fails.
A scan for the pair found one instance. The shape is a file that reads HEADWATER_BLESS, where one fixture name appears both inside a compare call and inside a read_to_string call. Twenty-three files carry the variable and one carries the pair.
The artifact is not at risk, and this is the part to state precisely. The bytes compare writes are actual, which is the run's own in-memory render, computed before the call and independent of what any other thread does. Eighteen blessed runs across two independent checkouts fired the race zero times, and every artifact they produced was byte-identical. So the failure mode is a flaky panic in a reader, and blessing is not non-deterministic. The condition predates any one branch.
A second instance used a shape that the scan did not match. In engine/crates/query/tests/mcp.rs, the_session_runs_to_the_recorded_transcript writes fixtures/query.mcp under the variable. a_session_writes_nothing_to_the_corpus_it_reads did not call read_to_string on that name. It walked the whole fixture directory and compared every byte before and after a session. So the reader was a directory walk, and a scan for a fixture name did not find it.
This instance was not only a truncation window. When the transcript really changed, the write changed the bytes of query.mcp between the two snapshots, and the case failed. On 2026-09-23, with query.mcp one byte stale before each run, 12 of 20 blessed runs failed and 7 of 20 failed on a second loop. With query.mcp already current, 1 of 90 failed. With no variable, 0 of 30 failed. Issue #1038 moved that case onto a private copy of the fixture tree, and after the change 0 of 20 stale-transcript runs failed. The render.rs pair above is still open.
Obligation
A suite that re-records its own expectations has one shared mutable file and two threads that reach it. Nothing in the helper, the test file or the runner orders them. The cost of the race is a red run. For the render.rs pair, a rerun clears it. For a reader that compares bytes, as mcp.rs did, a real re-record fails most runs. Both teach a reader to rerun rather than to read.
Discharge
The reader stops being a reader. the_recorded_block_is_the_one_this_width_produces asks whether the recorded block was recorded at WIDTH, and the rendered string that the writer holds answers the same question. Folding the width assertions into the case that already renders removes the file from the second thread. The fold must keep each assertion as strict as the reader held it, and a fold that drops a filter weakens the bound.
Where two cases must keep separate names, the pair is discharged by reading the file once at the top of the target. Any order the runner honors does the same. --test-threads=1 under the variable is a third route and the weakest, because it holds the property by a flag a caller can drop.
The wider question is whether any other blessed fixture is read outside its compare. The scan above answers it for the one shape it matched. A scan over a path built by a helper other than fixtures_dir reaches further. A scan must also match a case that walks a fixture directory, because that reader names no fixture file.
#1162 discharged the render.rs pair on 2026-09-28, by the first route above. It removed the_recorded_block_is_the_one_this_width_produces, and it moved the one assertion that the writer did not hold. The writer already asserted both width bounds on the rendered string. But its lower bound counted a line of one word, which the reader did not count, so the writer's bound was the weaker one. The writer now filters those lines as the reader did. HW-OBL-0215 recorded the same pair a second time, and it holds the counts that show the change. With both instances closed, this record discharges. The wider scan is not part of this discharge. It goes to the product owner as one intake line of run 20260927-0443, and a new record holds it if the owner rules it Record.