docs(ci-reds): U16's real mechanism is child inheritance; narrow U17

Five corrections, all mine.

U16 stopped at "the window exists", which misses why restoring the cwd
does not close it. `run_git` calls `run_git_inner(None, ...)`, and that
sets `current_dir` only when `cwd` is `Some` (fetcher.rs:329-330), so
the spawned git INHERITS the parent's temporary cwd. The parent then
restores its own --- which does nothing for a child that already has its
working directory --- and the TempDir drops underneath it. The restore
is not merely too early; it is irrelevant to the child.

U16 also offered a serial guard around `set_current_dir` tests as a
structural control. That does not protect an unguarded test that spawns
a child, because the child outlives the guard. The options that work are
removing the cwd mutation, running that test in a subprocess, or
serializing the whole lib-test binary.

And U16 said 8 green runs showed the window was narrow. They do not.
Non-reproduction establishes intermittence and nothing else; nothing
here has sized this candidate's window.

U17 claimed no PR run can show its failure. A PR run exercises the same
test and could fail identically; what only a main-side run establishes
is that it fails ON MAIN, with no observing branch to suspect. And its
`got ok` does not prove the supersede arrived late --- it proves the
predecessor completed successfully before cancellation took effect,
which a timely supersede whose cancellation lost the race produces
identically.
This commit is contained in:
Levi Neuwirth 2026-08-31 11:36:49 +02:00
parent 4aa3853ebe
commit 088f24e1bb
No known key found for this signature in database
2 changed files with 75 additions and 35 deletions

View File

@ -397,13 +397,18 @@ crdt-gated code does not rediscover it at CI.
- **U16, new** — a `git` invocation in `packages::fetcher` found its - **U16, new** — a `git` invocation in `packages::fetcher` found its
working directory **deleted**. Not a budget: the only row in the working directory **deleted**. Not a budget: the only row in the
registry that arrives with a **named candidate mechanism inside the registry that arrives with a **named candidate mechanism inside the
test suite**. `src/file_io.rs:434` mutates process-global cwd inside a test suite**, and the load-bearing step is **child inheritance**.
parallel test and points it at a `TempDir` that then drops, and `src/file_io.rs:434` mutates process-global cwd; concurrently
libtest runs tests in threads of one process. Candidate, not a `run_git` calls `run_git_inner(None, …)`, which sets `current_dir`
demonstrated chain — 8 full parallel `--lib` runs did not reproduce only when `cwd` is `Some` (`fetcher.rs:329`–`:330`), so the spawned
it. Two controls that would settle it are written into the row and `git` **inherits** the temp cwd. **Restoring the parent's cwd does
**neither is run here**; the structural fix belongs to whoever owns nothing for that child**, and the `TempDir` then drops underneath it.
`file_io`, not to a CRDT invariant lane. Candidate, not a demonstrated chain — 8 full parallel `--lib` runs did
not reproduce it, which establishes **intermittence and nothing
more**. The controls that would settle it are in the row and **none is
run here**; note that a serial guard around `set_current_dir` tests is
*not* among them, since the child outlives the guard. The structural
fix belongs to whoever owns `file_io`, not to a CRDT invariant lane.
- **R6's SECOND occurrence** — 26 days after the first, macOS `lua54`, - **R6's SECOND occurrence** — 26 days after the first, macOS `lua54`,
a **full three-condition match** including both required fragments. a **full three-condition match** including both required fragments.
@ -418,10 +423,13 @@ crdt-gated code does not rediscover it at CI.
- **U17, new** — that same control run **redded `Test (crdt)` on `main` - **U17, new** — that same control run **redded `Test (crdt)` on `main`
at `aae5b35`**: `read_dir_supersede_cancels_in_flight_predecessor`, at `aae5b35`**: `read_dir_supersede_cancels_in_flight_predecessor`,
`first read_dir must be superseded; got ok`. It fails the **opposite** `first read_dir must be superseded; got ok`. It fails the **opposite**
way to R1 and R5 — not a missed deadline, but a predecessor that had way to R1 and R5 — not a missed deadline. What `got ok` proves is
already finished. The job runs `--test-threads=1`, which is the narrow: the predecessor **completed successfully before cancellation
condition **U9's still-unrun control names**. A red on the merge base took effect**, which does not say when the supersede arrived. The job
is invisible to any PR run; it took the dispatch to see it. runs `--test-threads=1`, the condition **U9's still-unrun control
names**. A PR run could show this failure too; what only a `main`-side
run establishes is that it fails **on `main`**, with no observing
branch to suspect.
U14 and U15 are two rows rather than one because the second run's U14 and U15 are two rows rather than one because the second run's
selector set had **rotated**, and this registry matches on the exact selector set had **rotated**, and this registry matches on the exact

View File

@ -1427,34 +1427,55 @@ which is why it is worth more than its one occurrence.
| **what is NOT** | that the mechanism below is what happened. It is a candidate with a citation, not a demonstrated chain | | **what is NOT** | that the mechanism below is what happened. It is a candidate with a citation, not a demonstrated chain |
| **the observing tree** | the lane's docs-only commit. It touches `src/packages/` not at all | | **the observing tree** | the lane's docs-only commit. It touches `src/packages/` not at all |
**The candidate mechanism, and it is specific.** **The candidate mechanism, and the load-bearing step is CHILD
`src/file_io.rs:434` — `bare_filename_saves_in_cwd` — calls INHERITANCE.** An earlier version of this row stopped at "the window
`std::env::set_current_dir(dir.path())`, which mutates **process-global** exists", which misses why restoring the cwd does not close it:
state, points it at a `TempDir`, and lets that `TempDir` drop at end of
test. The libtest harness runs tests **in parallel threads within one
process**, so during that window every other test in the binary shares
the mutated cwd, and after the drop that cwd is a **deleted directory**.
`fatal: Unable to read current working directory` is exactly what a
process with a deleted cwd gets from `git`.
The test restores the cwd before its assertions, deliberately and with a 1. `src/file_io.rs:434` — `bare_filename_saves_in_cwd` — calls
comment saying so — **the hazard is not the restore, it is that the `std::env::set_current_dir(dir.path())`, mutating **process-global**
window exists at all**, and no amount of care inside one test closes a state and pointing it at a `TempDir`;
window that is process-wide. 2. concurrently, `cache_survives_across_fetcher_instances` reaches
`f1.fetch(&url)` (`fetcher.rs:929`), which clones via `run_git`
(`:305`). `run_git` calls `run_git_inner(None, …)`, and
`run_git_inner` (`:322`) sets `cmd.current_dir` **only when `cwd` is
`Some`** — `if let Some(d) = cwd { cmd.current_dir(d); }`,
`:329`–`:330`. With `None`, **the spawned `git` INHERITS the
parent's cwd** — the temp directory;
3. the parent then restores its own cwd. **That does nothing for the
child**, which already has its working directory;
4. the `TempDir` drops. `git` is now a live process whose cwd is a
**deleted directory**, and `fatal: Unable to read current working
directory` is exactly what that produces.
So the restore in `bare_filename_saves_in_cwd` is not merely
insufficiently early — it is **irrelevant to the child**, which is why
care inside that one test cannot close this.
**What would settle it**, and neither has been run: **What would settle it**, and neither has been run:
* run the two selectors concurrently in a tight loop until the failure * run the two selectors concurrently in a tight loop until the failure
reproduces, which converts the candidate into a demonstration; reproduces, which converts the candidate into a demonstration;
* or make the hazard structural rather than probabilistic — a serial * or make the hazard structural rather than probabilistic. **A serial
guard around every `set_current_dir` test, or removing the guard around `set_current_dir` tests is NOT one of the options**, and
process-global mutation from `bare_filename_saves_in_cwd` entirely an earlier version of this row offered it: the child outlives the
(`save_atomic` could take the directory rather than inheriting it). guard, so any unguarded test that spawns a process inheriting the cwd
is still exposed. What does work:
* **remove the process-global mutation** — `bare_filename_saves_in_cwd`
exists to check that a bare filename resolves against the cwd, and
`save_atomic` could take the directory rather than inheriting it;
* **run that test in a subprocess**, so its cwd is its own;
* **serialize the whole lib-test binary** (`--test-threads=1`), which
removes the concurrency the race needs — at the cost of the whole
binary's wall clock, and note U17, where that same flag is a
candidate for causing a different failure.
**Reruns: green in three isolated runs of the selector, and in EIGHT **Reruns: green in three isolated runs of the selector, and in EIGHT
full parallel `cargo test --lib` runs** (1990 passed each). Per this full parallel `cargo test --lib` runs** (1990 passed each). Per this
file's rerun rule that establishes **intermittence only** — and here it file's rerun rule that establishes **intermittence, and nothing more**.
also says the window is narrow, not that it is absent. An earlier version added "and here it also says the window is narrow" —
**it does not**. Non-reproduction over eight runs says the failure did
not recur in eight runs. It says nothing about the width of *this
candidate's* window, which no measurement here has sized.
**Not folded into U14 or U15.** Different selector, different fragments, **Not folded into U14 or U15.** Different selector, different fragments,
different step, and a different kind of failure: those are wall-clock different step, and a different kind of failure: those are wall-clock
@ -1466,8 +1487,13 @@ that is a different mechanism.
Surfaced 2026-08-31 by the **merge-base control dispatched for R6's Surfaced 2026-08-31 by the **merge-base control dispatched for R6's
second occurrence** — so it is a red on `main` at `aae5b35`, on no second occurrence** — so it is a red on `main` at `aae5b35`, on no
branch at all. **No PR run can show this**; it took a `workflow_dispatch` branch at all.
on `main` to see it.
**An earlier version said "no PR run can show this." That is wrong**: a
PR run exercises the same test and could fail it identically. What only
a `main`-side run can establish is that it fails **on `main`** — that
there is no observing branch to suspect — and that is the distinction
the dispatch actually bought.
| field | value | | field | value |
|---|---| |---|---|
@ -1483,9 +1509,15 @@ on `main` to see it.
part.** Both of those are **deadline** failures — a cancellation that part.** Both of those are **deadline** failures — a cancellation that
did not arrive in time (`supersede did not cancel within 50ms`, `async did not arrive in time (`supersede did not cancel within 50ms`, `async
pump deadline exceeded`). This one reports `got ok`: the first pump deadline exceeded`). This one reports `got ok`: the first
`read_dir` **completed successfully** instead of being cancelled. The `read_dir` **completed successfully** rather than reporting cancellation.
supersede did not arrive late; it arrived after there was nothing left
to supersede. **What `got ok` proves, precisely:** the predecessor **completed
successfully before the cancellation took effect**. It does **not**
establish when the supersede arrived — an earlier version of this row
said "it arrived after there was nothing left to supersede", which
assumes a late arrival the assertion cannot see. A supersede that
arrived in time and whose cancellation simply did not take effect first
produces the identical message.
**Candidate mechanism, stated as one.** The job runs **Candidate mechanism, stated as one.** The job runs
**`--test-threads=1`**. A test that dispatches a job and then supersedes **`--test-threads=1`**. A test that dispatches a job and then supersedes