docs: retire two arcs, and file two reds the scan turned up

RULE 4 REMOVES A LANE AFTER MERGE, and two were overdue: the tree
primitive (#217) and macOS CI signal integrity (#215, #216).

The macOS arc could not simply be deleted. It owned R1 and R3, and a
lane removed while it still owns undone work does not close that work,
it hides it. R1 goes to a new async-runtime block; R3 goes to the
reap-ledger lane, which already parks every disposition change pending
exactly its question. Re-homing first is why this did not happen at
merge.

AN OCCURRENCE SCAN (last 25 main runs: 23 green, 2 red) found both reds
unrecorded, and I misattributed both on the first pass — by theme
rather than by required fragment, which is the exact error the registry
exists to prevent.

- Run 30710662474 is NOT R3. Same test, same EPERM, same
  measured_group=unobservable(ESRCH...) — but R3 requires `leader=live`
  and this reads `leader=exited(signal SIGUSR1)`, R2's exact fragment.
  It is a second R2 occurrence, four days BEFORE R2's retirement, so it
  corroborates the row rather than falsifying its disposition. It also
  adds something: macOS luajit where R2's evidence was lua54, so the
  mechanism was never flavor-specific. Filing it as R3 would have
  attached a live possible product defect to an occurrence of a fixed
  test race.
- Run 30555667095 is NOT R1. Different test, different module,
  different assertion; they share only "supersede under a deadline on
  macOS". Sharing a subject is not sharing a signature. Filed as R5,
  undiagnosed.

R6 is the acc28 readiness timeout from #217's CI. Its scope is the
AUDIT, not the call site: three independently written readiness helpers
now exist and they disagree, with bottom_panel_stage1's carrying only
the zero-byte half of #216's hardening. R4's disposition predicted this
recurrence under a new selector. Patching acc28 alone repeats the
mistake this arc already made once, when the empty-file predicate was
fixed in one helper and left in its neighbour.

The registry carries a rate for the first time — a floor, not a
measurement: main only, 25 runs, readable reds only.

Four durable lessons to the handoff, two from the tree review: an
optional field the shape depends on is not optional, and a contract two
mechanisms must honour is only as strong as the weaker one.

Verified: fmt, diff-check, --lib, listview 26/26. Docs-only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Levi Neuwirth 2026-08-06 10:17:46 +02:00
parent db1bbe94a6
commit 2c59fac510
No known key found for this signature in database
3 changed files with 233 additions and 224 deletions

View File

@ -180,87 +180,38 @@ form. All four steps ran clean. **The two-argument form still does not
work** for a remote-only branch (`fatal: invalid reference`), which is
why every lane below spells out the `-b` form.
## Tree primitive (P5) — PR #217 OPEN, awaiting review
## Tree primitive (P5) — MERGED as #217; adoption is the open work
**PR #217** — https://github.com/levineuwirth/pmacs/pull/217. It was
held through four framing rounds plus a review round; the hold is over
and the work is with the user. Full gate suite green at the tip,
including `PMACS_REQUIRE_GPU=1 -p pmacs-gpu` 221/0.
**The lane is gone, not the work.** Rule 4 removes a lane after merge,
and the primitive is merged: `listview` rows take optional `depth` and
`id`, collapse is primitive-owned, selection re-seats by id, and the
LSP outline is the one adopter. `COHERENCE.md` §14 is ◐ and §20 says
adoption rather than construction, which is where the remaining work is
recorded — **not here**, because none of it is in flight.
- **Branch `tree-primitive-framing`**, base `githubsucks/main` @
`12f2970`. **Pushed and in sync** — held means no PR is open, not
that the work is stranded locally, so it is portable per the
handoff's rule. `githubsucks/tree-primitive-framing` is the
authoritative tip; `d92f0ad` was it as of the line above, and any
edit to this lane advances past it, which is why the ref and not a
pinned SHA is the thing to trust. Recover with `git fetch githubsucks
&& git checkout tree-primitive-framing`. Framing
`docs/tree-primitive-framing.md` **revision 5** — approved after four
review rounds, with Q#TR1TR4 decided.
- **The substantive arc** (not an exhaustive log — read `git log
12f2970..githubsucks/tree-primitive-framing` for that): `61b1062`
framing through `5186bfd` rev 4, which carried the `COHERENCE.md` §14
call-site correction; `49a42ec` the primitive; `8f64c3b`
byte-identity coverage plus the verification record; `38e94dc` this
lane, §14's ✗ → ◐ and the handoff facts; `c59de95` the review round —
moving-selection witness, flat-panel TAB delegation, §20's build →
adopt correction.
What review found is worth carrying forward, since all four were
invisible to a passing suite:
### What it ships
- **A selection test that toggled the root proved nothing.** The root
sits on line 1 before and after collapsing, so it passed unchanged
under the line-keyed re-seating that id-keyed re-seating replaced.
A moving-node witness (`tr_4`) was the fix.
- **TAB was bound on every listview**, so flat panels lost their
fall-through to the global binding and the Q#P3 read-only intercept.
Delegation restored it.
- **`item` was effectively required.** `line_to_item` is sparse when a
row omits the optional `item`, and `seat_cursor` took `#` of it — a
display-only tree stranded the cursor on the header. Every existing
test supplied `item`, so none could reach it.
- **"Opaque, compared by equality" was two contracts.** Selection uses
`==`; collapse keys a table, which consults no `__eq`. Narrowed to
string-or-number, and with it uniqueness and not-NaN, all enforced
where rows enter.
`listview` gains **optional** `depth` and `id` on rows; absent, a row
behaves exactly as before, which is what leaves the flat consumers
untouched. Collapse state is **primitive-owned**, keyed by
consumer-supplied id. Selection is re-seated **by id, not by line**.
`TAB` toggles; a leaf reports rather than silently doing nothing.
**The observation that made it cheap:** collapse only ever *hides* rows
and never changes a surviving row's depth, and consumers emit parents
before children, so descendants are a **contiguous run**. Folding is
therefore **local projection state, not a refresh protocol** — the
primitive re-renders from its own array without calling the consumer,
which is why the anchor consumer works at all: **the outline has no
`on_refresh`**.
The LSP outline adopts, supplying `depth` and `id = line:col`; its
`text` stays consumer-rendered per Q#TR4.
### Verification
| gate | result |
|---|---|
| luajit sweep | **3453 / 0** (= `main` 3450 + 3 listview tests) |
| crdt sweep, isolated ×2 | **3722 / 0** (= `main` 3718 + 4 tests) |
| `listview_acceptance` | 22 / 22 |
| `m4_acceptance` | 150 / 150 (basedpyright skipped) |
| `--lib` | 1896 / 0 |
| fmt · diff-check · clippy ±crdt | pass |
Both behavioural claims are **bite-verified**: disabling the ancestor
filter fails the fold test; an unconditional gutter fails the
byte-identity test.
**One unclassified occurrence** — the first crdt sweep reported 7
failures whose signatures were destroyed before being read. It is
recorded in the framing's §6a, **not** as a row in
`docs/ci-red-signatures.md`, because it has no normalized signature to
match. Two non-causal hypotheses are recorded there; neither is testable
now.
### Recovery, once pushed
```sh
git fetch githubsucks
git worktree add ../pmacs-tree \
-b tree-primitive-framing \
githubsucks/tree-primitive-framing
```
### Not in scope
dired's `i` insert-subdirectory (the second consumer, its own stage);
the other four §14 consumers; DAP's variables view; giving the outline a
refresh, which is LSP request-lifecycle work.
The last two are the durable lesson and it is in the handoff: **an
optional field that a data structure's shape depends on is not
optional**, and a contract that two mechanisms must honour is only as
strong as the weaker mechanism.
## Leaked daemons from `gpu_invocation_acceptance` — NEEDS A LANE
@ -301,163 +252,74 @@ reap, or does the daemon fail to exit when its socket disappears? Those
have different fixes, and the second would be a product defect rather
than a test one.
## macOS CI signal integrity — STAGES 1 AND 2 MERGED (#215, #216)
## macOS CI signal integrity — ARC RETIRED (#215, #216); residue re-homed
**This file requires a lane for every open PR** (see the #171/#174 note
above: an open PR is exactly the volatile work this file records, and
#171 drifted 153 commits while invisible here). #215 had none until
review caught it; **Stage 2's lane is written with its first commit**,
which is where the same defect stops recurring.
**Both stages merged and the arc is done**, so rule 4 removes the lane.
Stage 1 built `docs/ci-red-signatures.md` and audited the incumbents;
Stage 2 retired **R2** and **R4** with discriminating witnesses. The
framing `docs/macos-ci-signal-integrity-framing.md` and the registry
both survive the lane — the registry is the durable artifact this arc
existed to produce.
Framing `docs/macos-ci-signal-integrity-framing.md` **revision 3**,
already approved. Stage 1 is acceptance 15; Stage 2 is acceptance 69.
**Retiring it required re-homing the residue first**, which is why this
did not happen at merge. A lane removed while it still owns undone work
does not close that work, it hides it. What it owned:
### Stage 2 — hardening, MERGED as #216
- **R1** (supersede cancellation budget, *measurement design*) → the
**async-runtime lane**, below. Its retirement condition is Q#MCI3:
replace or justify the measurement. Widening the budget would make it
pass and measure nothing more.
- **R3** (live-leader EPERM, **UNRESOLVED — possible product defect**)
→ the **reap-ledger lane**, below, which already parks every
disposition change pending exactly this question.
- **R5** and **R6**, added 2026-08-06 and neither diagnosed → the
async-runtime lane and a **readiness-helper audit** respectively.
- **Branch `ci-signal-hardening`**, worktree `../pmacs-ci-signals`, base
`githubsucks/main` @ `12f2970` (the #215 merge). Opened from an
**isolated worktree** because the shared checkout was on another
lane's branch with clean-but-foreign state; never switch it.
- **PR: <https://github.com/levineuwirth/pmacs/pull/216>, MERGED**
2026-08-05 as `2657568`, all 14 checks green at head `8ab20b5`. This
block was written *with* the work, before the PR existed, so the row
below was filled in rather than invented. **Checkpoints, newest
last**, because a lane that records only one head goes stale on the
next push:
### The rows are the state now, not this block
| head | CI run | result |
|---|---|---|
| `2d9c678` | [31003333581](https://github.com/levineuwirth/pmacs/actions/runs/31003333581) | **14/14 green** — the opening head, and the last one carrying code. Includes **both macOS legs**: R2's job (macOS / lua54) and R4's (macOS / luajit) |
| `668fc72` | [31006160334](https://github.com/levineuwirth/pmacs/actions/runs/31006160334) | **14/14 green** — this ledger block, docs only |
| *(tip)* | — | the checkpoint row for `668fc72`; a table can never carry the head that adds it |
An occurrence scan on 2026-08-06 (last 25 `main` runs: 23 green, 2 red)
turned up two things worth recording as method rather than as trivia.
**The branch tip is authoritative over any row here.** Verify with
`git rev-parse githubsucks/ci-signal-hardening` rather than trusting
the newest line.
- **What it ships — exactly two fixes, both at the readiness
predicate**, plus four witnesses:
- **R4.** `wait_for_file` takes the **expected bytes** and waits while
the file holds a *strict prefix* of them, so a zero-byte or torn
read is no longer a readiness signal. Four callers updated; **the
identical mechanism in `wait_for_published_file`**, one function
away in the same suite, is fixed with it — leaving it would have let
R4 recur under a different selector.
- **R2.** The USR1 fixture publishes a marker **after** `trap '' USR1`
and the test waits for that marker's **content**; `exec` replaces
the forked `sleep`, so the group holds one process and the ignored
disposition survives by POSIX rather than by a shell's
fork-suppression optimization.
- **The witnesses were verified by REVERTING each fix**, not by
reasoning. With the old predicate restored,
`wait_for_file_does_not_return_a_zero_byte_readiness_file` fails
`left: []`, `right: [49]` — **R4's two required fragments, verbatim**
— and with the readiness wait removed,
`usr1_readiness_waits_for_the_trap_not_for_the_spawn` fails
`left: Some("SIGUSR1")`, `right: Some("SIGTERM")`.
- **R1 is NOT touched** — referred to the async-runtime lane (Q#MCI3);
widening its budget would make it pass and measure nothing more.
**R3 is NOT touched** and stays **unresolved**; it belongs to the
process-signal / reap-ledger lanes and nothing here may make it look
otherwise.
- **Repetition sets, not single runs:** the two `--lib` process tests
**15/15**, the whole `vterm_stage2_acceptance` suite (9 tests, default
parallelism) **15/15**.
- **Verification:** fmt, diff-check, clippy with and without `crdt`,
`--lib` 1897, `--lib --features crdt` 2082, vterm Stage 2 9, m4 149,
required GPU 221. Each `--lib` figure is exactly one above #215's
(1896 / 2081): the R2 witness.
- **Full serialized sweep in BOTH feature configurations, baseline
first** — the blindness handoff §5 warns about, and the baseline is
what makes any failure attributable:
**A signature very nearly got misfiled by theme.** `main` run
30710662474 is the same test as R3, with `EPERM` and
`measured_group=unobservable(ESRCH…)` — and R3 requires `leader=live`
where that run reads `leader=exited(signal SIGUSR1)`, which is R2's
exact fragment. Read by test name and shared fragments it looks like
R3; read by required fragment it is R2, four days before R2's
retirement, on the *other* macOS flavor. **Attaching a live unresolved
product-defect row to an occurrence of a retired test race is precisely
the error the exact-fragment rule prevents**, and it was caught by
checking the fragment rather than the resemblance.
| tree | config | suites | passed | failed |
|---|---|---|---|---|
| `main` @ `12f2970` | luajit | 108 | 3691 | 0 |
| `main` @ `12f2970` | luajit,crdt | 108 | 3959 | 0 |
| branch | luajit | 108 | 3695 | 0 |
| branch | luajit,crdt | 108 | 3962 | **1 — see below** |
**A second red matched nothing at all** and became R5, rather than
being folded into R1 because both involve supersede under a deadline on
macOS. Sharing a subject is not sharing a signature.
**Every total is exactly +4 on its baseline** — 3691→3695 and
3959→3963 (3962 passed plus the one failure). Four witnesses, and
nothing else moved.
- **The one branch-`crdt` failure is recorded rather than rerun away.**
`lsp_dispatch_seams_acceptance
acc33_apply_edit_still_handled_with_a_response_subscriber` —
*"the executeCommand response reaches its one-shot, left: 0, right:
1"*. It is a **new incident** by the registry's rules (no row's
fragments match), and it is **not attributable to this branch**, on a
structural argument rather than on the green rerun:
- the only Rust change is inside `#[cfg(test)] mod tests` in
`src/process.rs`, which is compiled **only into the lib test
target** — an integration-test binary links the non-`cfg(test)`
lib, so this suite's artifact is what `main` builds;
- the other change is a different test binary entirely;
- CI's **`Test (crdt)` job passed at this same head**, and it runs
this suite;
- it occurred while a **second full workspace sweep** was running
concurrently in another worktree, against a deadline-based fake-LSP
one-shot;
- the suite then ran **15/15 as a repetition set** — which, per this
project's own rerun rule, establishes **intermittence only** and is
the weakest of these five points, not the argument.
### Async-runtime lane — NOT STARTED, owns R1 and R5
**No registry row is opened**, because the registry judges red **CI**
runs and keys on linked CI occurrences; this is a local observation
under known contention. If it appears in CI, it is a first recorded
occurrence and gets a row then.
- **A SHARED `CARGO_TARGET_DIR` MAKES A LOCAL SWEEP UNATTRIBUTABLE, and
it bit this lane.** The branch `crdt` sweep first reported 7 failures
in three suites while the baseline `crdt` sweep was clean. All three
spawn the **real `pmacs` binary out of the target directory**, and the
failure text named its own cause: *"daemon does not advertise required
capabilities … start the daemon built with the `crdt` feature"*. A
concurrent `cargo test --workspace` in a **different worktree**, with
default (non-`crdt`) features and the same `CARGO_TARGET_DIR`, had
overwritten `target/debug/pmacs` mid-sweep. Confirmed by `pgrep` while
it was happening, and discriminated by re-running the same three
suites from the same tree with a **dedicated** `CARGO_TARGET_DIR`:
41/41 green, then the whole config swept clean the same way. **Give a
sweep its own target directory whenever another worktree is live** —
a feature-flavored binary is a shared mutable file, not a build
artifact private to your invocation.
No branch, no framing. Owns **R1** (Q#MCI3: the 50ms budget starts
before the second dispatch and is consumed by the test's own pump, so
it measures when the test was scheduled) and **R5**
(`stream_supersede_delivers_cancelled_to_on_close`, `async pump
deadline exceeded`, undiagnosed). Filed together because both are the
async runtime under a deadline; they are **not** assumed to share a
cause.
Recovery from a clean checkout:
### Readiness-helper audit — NOT STARTED, owns R6
```sh
git fetch githubsucks
git worktree add ../pmacs-ci-signals \
-b ci-signal-hardening \
githubsucks/ci-signal-hardening
```
No branch, no framing. **Three independently written readiness helpers
now exist**, and they disagree: `vterm_stage2_acceptance`'s waits for
expected content (hardened by #216), `wait_for_published_file` was
fixed with it, and
`tests/bottom_panel_stage1_acceptance.rs:2446` carries only the
zero-byte half. R4's disposition predicted this recurrence under a new
selector, and R6 is it.
### Stage 1 — MERGED as #215
- **Branch `macos-ci-signal-integrity`**, merged to `main` @ `12f2970`
after two review rounds. Docs only. Final CI checkpoint:
| head | CI run | result |
|---|---|---|
| `d33bf4d` | [30950108477](https://github.com/levineuwirth/pmacs/actions/runs/30950108477) | 14/14 green — the reviewed head |
| `f76897c` | [30990816890](https://github.com/levineuwirth/pmacs/actions/runs/30990816890) | review round 1 |
| `2e0617f` | — | review round 2: framing wording, the missing quote, the checkpoint table |
- **What Stage 1 shipped:** `docs/ci-red-signatures.md`, the single
authority for judging a red CI run. Rows key on **signature**
selector + job/flavor + every required fragment, normalized — so **a
test-name match confers nothing**. The rerun rule is replaced: a green
rerun establishes **intermittence only**; the same signature again is
a second occurrence and stays blocking; a different signature is a new
incident. Retirement is **causal**, never a count of green runs.
- **Four incidents, three tests, four signatures.** The process test
produced two — one a test race (R2), one an **unresolved possible
product defect** (R3) that no rerun can clear. Counting by test name
would have hidden the second behind the first.
- **The audit found a third state the framing did not allow**, which is
why the framing is at revision 3: two incumbents have a historical
claim but **no linked occurrence ever**. They are **audit notes A1/A2**,
not rows — unmatchable by construction, so a red in either is a new
incident. The registry is therefore *stricter* than the list it
replaces: nothing is pre-excused.
**Scope is the audit, not the call site**: how many helpers exist,
whether they can be one, what each promises. Patching `acc28` alone
leaves the question open under a fourth selector — which is the same
mistake as fixing `wait_for_file` and leaving
`wait_for_published_file`, already made once in this arc.
## CI CRDT coverage — MERGED (#209); kept for its three follow-ons
@ -678,6 +540,23 @@ them) and why `dired`/`listview` were the correct first two families.
- **Unparked from PR #200's §5.** #200 retired the premise that
justified the ledger's leniency and deliberately changed no
disposition; this lane owns what it refused.
- **Now also owns R3**, re-homed 2026-08-06 when the macOS CI
signal-integrity arc retired. `docs/ci-red-signatures.md` R3 is a
group-directed `kill` returning **EPERM while the leader was observed
live**, with `measured_group` — the one field able to disagree —
unreadable. It is the **same group-target question** #176 and #200
circled and this lane parks every disposition change pending, which
is why it lands here rather than staying with a retired CI lane. Its
registry entry is explicit that it is an **unresolved possible
product defect** and that **a green rerun never retires it**; that
constraint travels with the row, not with whoever inherits it.
Note what it is *not*: R2 is the same test with `leader=exited(signal
SIGUSR1)`, a test race, retired. An occurrence scan on 2026-08-06
nearly filed a second R2 occurrence here as R3 on the strength of the
shared test name and shared `EPERM` fragment. **`leader=live` is the
fragment that separates a product-defect candidate from a fixed
fixture bug**, and it is the whole reason the row lists it.
- **Four sites, not the two #200 named.** In the persistent ledger: a
probe error of any errno drops the entry and cancels escalation; a
failed escalating `SIGKILL` is marked as succeeded, so **no later tick

View File

@ -2236,6 +2236,50 @@ round-trip cannot detect a discriminant shift.
## 5. Hard-won ops lessons
- **An optional field that a data structure's shape depends on is not
optional.** `listview` rows may omit `item`, so
`line_to_item[n] = row.item` leaves that map **sparse** — and
`seat_cursor` took `#` of it, which for an all-display-only tree is
0, stranding the cursor on the header where TAB finds no row. The
whole existing suite missed it because **every test supplied
`item`**: the field was optional in the API and mandatory in
practice, and nothing in a passing run distinguishes those. When a
field is optional, write one test that omits it — the sparse-table
`#` is a Lua-specific trap, but "optional in the signature, required
by the shape" is not.
- **A contract two mechanisms must honour is only as strong as the
weaker mechanism.** `listview` ids were documented "opaque, compared
by equality". Selection compares with `==`, honouring `__eq`; collapse
state stores ids as **table keys**, and Lua indexes tables by raw
identity, consulting no metamethod. A table id satisfied one half and
silently failed the other — a refresh would restore the cursor and
lose the fold, surfacing arbitrarily later with nothing pointing at
the id. **Narrow the contract to what both halves can honour and
enforce it where the data enters**, rather than generalizing the
strong half to match the weak one: equality-aware collapse lookup
would have turned a linear render quadratic to support a key type no
consumer wanted. The same pass found the contract said "identity"
while accepting duplicates (every lookup takes the first match, so
selecting the later row toggles the earlier) and "number" while
accepting NaN (a number Lua refuses as a key). **Enforcement and
documentation drift apart silently; only the enforcement is real.**
- **Match a red by its required fragment, never by test name or
resemblance.** An occurrence scan on 2026-08-06 nearly filed `main`
run 30710662474 as **R3** — same test, same `EPERM`, same
`measured_group=unobservable(ESRCH…)`. R3 requires `leader=live`;
that run reads `leader=exited(signal SIGUSR1)`, which is **R2's**
exact fragment, four days before R2 was retired. The two rows are a
live possible **product defect** and a fixed **test race** in the
same test, and only the fragment separates them. A second red in the
same scan was filed as **R5** rather than folded into R1 for the same
reason: both are supersede under a deadline on macOS, and **sharing a
subject is not sharing a signature**.
- **A retired row's recurrence rule is about time, not just text.** A
red matching a retired row falsifies the retirement **only if it
postdates it**. An earlier occurrence found later corroborates the
row instead — and can still add something: 30710662474 is macOS
*luajit* where R2's evidence was *lua54*, so the mechanism was never
flavor-specific.
- **A gate summary assembled through a pipe can report success over a
failure.** `cmd | tail -2` returns **`tail`'s** exit status, not
`cmd`'s — in `fish` and `bash` alike — so a chain of

View File

@ -89,8 +89,17 @@ row, not a weaker one. Reopen the row rather than rerunning.
## Live rows
**Two of the four evidenced rows are live.** R2 and R4 were retired on
**Four of the six evidenced rows are live.** R2 and R4 were retired on
2026-08-05 and are below, under "Retired rows", with their dispositions.
R5 and R6 were added on 2026-08-06 from an occurrence scan and a live
red; neither is diagnosed.
**Rate, as of 2026-08-06.** Of the last 25 `main` runs, **23 green and
2 red** — the two reds being R2's second occurrence (30710662474) and
R5 (30555667095). R6 has **no** occurrence in that window; it was first
seen on a PR branch. This is the first rate this file has carried, and
it is a floor rather than a measurement: it counts only `main`, only 25
runs, and only reds that were still readable.
### R1 — supersede cancellation budget
@ -152,6 +161,64 @@ as a falsification of that claim rather than as a fresh mystery. Both
were retired **causally** — the mechanism removed, plus a discriminating
witness that fails without the fix — never by a count of green runs.
### R5 — async pump deadline exceeded in the supersede close path
| field | value |
|---|---|
| **selector** | `--lib editor::tests::stream_supersede_delivers_cancelled_to_on_close` |
| **job / flavor** | macOS / lua54 |
| **required fragments** | `async pump deadline exceeded` |
| **causal status** | **UNRESOLVED — no diagnosis** |
| **evidence** | `main` [run 30555667095](https://github.com/levineuwirth/pmacs/actions/runs/30555667095), 2026-07-30 |
| **retirement** | diagnosis by the async-runtime lane, alongside R1's measurement question (Q#MCI3). **Never a green rerun.** |
**Not R1, though it is the nearest thing to it.** R1 is
`async_runtime::tests::supersede_cancels_in_flight_job_within_50ms`
failing `supersede did not cancel within 50ms`; this is a different
test in a different module failing a different assertion. They share a
subject — supersede, under a deadline, on macOS — and sharing a subject
is not sharing a signature. Filed separately so that a fix for one is
not read as a disposition for the other.
What the row does **not** claim: that the pump is slow, that the
deadline is wrong, or that this is the same measurement-design problem
R1 has. Nothing here has been diagnosed. It is recorded because it
happened and had a signature, which is the entire bar for a row.
### R6 — readiness file never published in the panel terminal fixture
| field | value |
|---|---|
| **selector** | `--test bottom_panel_stage1_acceptance acc28_child_input_and_the_c_c_escape_work_unchanged_in_a_panel` |
| **job / flavor** | macOS / lua54 |
| **required fragments** | `timed out waiting for` **and** `/ready` |
| **causal status** | **UNRESOLVED — no diagnosis** |
| **evidence** | #217 [run 31023651701](https://github.com/levineuwirth/pmacs/actions/runs/31023651701), 2026-08-05 |
| **retirement** | the readiness helpers are audited and reconciled, with a witness. **Never a green rerun** — the next push was green and that retires nothing. |
**A THIRD copy of the readiness helper.** R4's disposition already
recorded that the empty-file predicate lived in a second helper
(`wait_for_published_file`) and warned that leaving it would let the
mechanism recur under a different selector as a new incident.
`tests/bottom_panel_stage1_acceptance.rs:2446` is a third,
independently written `wait_for_file` carrying only *half* the
hardening: it rejects a zero-byte file (`!bytes.is_empty()`) but never
waits for the expected content.
So the honest statement is narrow. This red is a **timeout**, not R4's
`left: [] / right: [49]`, and a timeout is what a *correct* predicate
does when the content never arrives — it is not evidence of the R4 bug.
What is established is only that a third copy exists and diverges from
the other two. **Whether this occurrence is a slow runner, a child that
never published, or something in the panel path is not known**, and the
suite passed 5/5 locally on Linux, which reproduces nothing about a
macOS runner and is not evidence about this occurrence.
The scope this row implies is the audit, not the test: how many
readiness helpers exist, whether they can be one, and what each
promises. Patching this call site alone would leave the same question
open under a fourth selector.
### R2 — USR1 delivered before the trap is installed — RETIRED 2026-08-05
| field | value |
@ -160,7 +227,7 @@ witness that fails without the fix — never by a count of green runs.
| **job / flavor** | macOS / lua54 |
| **required fragments** | `leader=exited(signal SIGUSR1)`**one exact fragment, not two loose ones**. Split into `leader=exited(` and `SIGUSR1` it would match a child that exited by some *other* disposition while `SIGUSR1` appeared elsewhere in the output |
| **causal status** | **test race** |
| **evidence** | [#213 run 30927084982 attempt 1](https://github.com/levineuwirth/pmacs/actions/runs/30927084982/attempts/1) |
| **evidence** | [#213 run 30927084982 attempt 1](https://github.com/levineuwirth/pmacs/actions/runs/30927084982/attempts/1); **and `main` [run 30710662474](https://github.com/levineuwirth/pmacs/actions/runs/30710662474), 2026-08-01, macOS / *luajit*** — same exact fragment on the **other flavor**, found by an occurrence scan on 2026-08-06 |
| **retirement condition** | the fixture proves the trap is installed, with a witness that fails without it |
| **disposition** | **met.** The child publishes a readiness marker *after* `trap '' USR1`, the test waits for that marker's **content**, and `process::tests::usr1_readiness_waits_for_the_trap_not_for_the_spawn` is the witness |
@ -186,6 +253,25 @@ Three things the fix and the witness settled that the row did not say:
disposition** — a child that took the USR1 reports
`Signaled { signal: "SIGUSR1" }` — rather than by an absence observed
within a window.
- **The second occurrence is pre-retirement, and that is the whole
question.** `main` run 30710662474 predates the 2026-08-05 retirement
by four days, so it corroborates the row rather than falsifying its
disposition — a red matching a retired row is a recurrence **only if
it postdates the retirement**, and the rule above is about the claim
a retirement makes going forward. It does add something: this row's
evidence was macOS / lua54 and this one is macOS / **luajit**, so the
mechanism was never flavor-specific, which is what the fix already
assumed when it widened the window deliberately rather than hoping a
loaded runner supplied one.
*It was also very nearly filed as R3.* Same test, same `EPERM`, same
`measured_group=unobservable(ESRCH…)` — and R3 explicitly requires
`leader=live`, where this reads `leader=exited(signal SIGUSR1)`.
Matching on the shared fragments and the shared test name would have
attached a live, unresolved possible-product-defect row to an
occurrence of a retired test race. **This is why the rows key on
exact fragments and why R2's says "one exact fragment, not two loose
ones."**
- **The fixture had a second, unnamed dependency.** These signals are
group-directed, so a forked `sleep` would be an *untrapped* member of
the same group. That it survived at all depended on the shell