Merge pull request #218 from levineuwirth/docs-absorption-217

docs: retire the tree and macOS-CI arcs, and file two unrecorded reds
This commit is contained in:
Levi Neuwirth 2026-08-06 09:59:04 +00:00 committed by GitHub
commit da56becb3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 352 additions and 254 deletions

View File

@ -111,8 +111,10 @@ lesson, §1 for the two framings).
are identical on every machine. Remote names are otherwise
machine-local: `origin` may name this canonical URL, a release mirror,
or something else, and therefore has no authority by name alone.
- Canonical base at this snapshot: **`githubsucks/main` @ `12f2970`** —
the macOS CI signal-integrity registry **#215**, atop `f186253`:
- Canonical base at this snapshot: **`githubsucks/main` @ `db1bbe9`** —
the tree primitive **#217**, atop `2657568` the macOS CI
signal-integrity **Stage 2 #216** (which retired R2 and R4), atop
`12f2970` its Stage 1 registry **#215**, atop `f186253`:
bottom-panel Stage 3 **#213**, which completes Arc 7, atop the
post-release accuracy pass **#212**, Distribution Stage 1 **#211**
(released as **v1.1.0**, the first release with prebuilt binaries),
@ -125,8 +127,9 @@ lesson, §1 for the two framings).
`Hello` still advertises v20** — two different facts, and #184 landed
only the first.
**The recovery floor advances with the base**, so the check below
now requires `12f2970` or newer; a tree at `f186253` no longer
passes. That is deliberate — a check accepting an older commit than
now requires `db1bbe9` or newer; a tree at `12f2970` no longer
passes — it would lack #216 and #217, both of which this file
describes as complete. That is deliberate — a check accepting an older commit than
the declared base passes on a tree the rest of this file does not
describe.
**Lanes below that name an older base have not been re-based; derive
@ -164,103 +167,96 @@ git worktree list
git status --short --branch
```
The `git log` command must expose `12f2970` — the base named above — or a
The `git log` command must expose `db1bbe9` — the base named above — or a
newer intentional main. Keep this threshold and the canonical-base line in
step: a recovery check that accepts an older commit than the base it
declares canonical will pass on a tree the rest of this file does not
describe.
If it does not, stop and repair the remote/fetch configuration.
**This path was exercised, not asserted, at this snapshot** — ahead of a
machine move. From an empty directory: `git clone` the canonical URL,
add the `githubsucks` alias, `git fetch githubsucks --prune`, confirm
`f186253` is an ancestor of `githubsucks/main`, and recover a lane with
the three-argument `git worktree add <path> -b <local> githubsucks/<branch>`
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.
**This path was exercised, not asserted, at this snapshot** — re-run
from an empty directory on 2026-08-06 when the base advanced to
`db1bbe9`, rather than having its SHA swapped. `git clone` the
canonical URL, add the `githubsucks` alias, `git fetch githubsucks
--prune`, confirm `db1bbe9` is an ancestor of `githubsucks/main`, and
recover a lane with the three-argument `git worktree add <path> -b
<local> githubsucks/<branch>` form. All four steps ran clean.
## Tree primitive (P5) — PR #217 OPEN, awaiting review
**Correction, found by re-running it.** This file claimed the
two-argument form fails for a remote-only branch with `fatal: invalid
reference`. **It does not fail.** On git 2.55.0 it *succeeds* and
leaves a **detached HEAD** — no branch, no upstream, `git status`
reporting `## HEAD (no branch)`.
**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.
Still use `-b`, but for the opposite reason to the one recorded: the
danger is not an error that stops you, it is that nothing stops you.
Work committed in that worktree sits on no branch, is not pushed by a
bare `git push`, and is exactly the "uncommitted work does not travel"
hazard in a shape that looks committed. **A documented error message
that never appears is worse than no documentation**, because the reader
waits for a signal that is not coming.
- **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.
## Docs absorption after #217 — PR #218 OPEN
### What it ships
**PR #218** — https://github.com/levineuwirth/pmacs/pull/218. **This
block was written with the lane's first commit, before the PR
existed**, so the row above was filled in rather than invented. That is the standing correction from #171 (153 commits of
drift while invisible here) and #215 (no lane until review caught it):
this file requires a lane for every open PR, and the way that stops
recurring is writing it now rather than after someone asks.
`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
```
- **Branch `docs-absorption-217`**, base `githubsucks/main` @ `db1bbe9`
(the #217 merge). `githubsucks/docs-absorption-217` is the
authoritative tip — any edit to this block advances past whatever SHA
it records, so the ref is the thing to trust. Recover with `git fetch
githubsucks && git checkout docs-absorption-217`.
- **Docs only.** No `src/`, no crate, no manifest, no test changes.
Gates run are fmt, `git diff --check`, `--lib`, and
`listview_acceptance`; the full suite is not re-run for a change that
cannot reach it, and that is stated rather than left as a gap.
- **Scope:** retire the tree and macOS-CI arcs per rule 4, re-home
their residue first, file R5 and R6, and carry four durable lessons
into the handoff.
### 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.
Diagnosing R5 or R6, or auditing the three readiness helpers — those
are the lanes this one creates, not work it does. Retiring the
CI-CRDT, Distribution, or reap-ledger lanes: each still owns undone
work and rule 4 does not apply to them.
## Tree primitive (P5) — MERGED as #217; adoption is the open work
**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.
What review found is worth carrying forward, since all four were
invisible to a passing suite:
- **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.
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 +297,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 +585,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

@ -1,11 +1,19 @@
# Agent handoff — cross-machine continuity
**Last updated: 2026-08-05.** The live CI-triage rule in §5 now points
at `docs/ci-red-signatures.md` (**PR #215, merged as `main` @
`12f2970`**; its Stage 2 hardening is in flight — see
`docs/active-work.md`), which keys on
signature rather than test name; the hazards list this file used to
carry is retired, and its two unevidenced entries are audit notes there.
**Last updated: 2026-08-06.** `main` is **`db1bbe9`** — the tree
primitive **#217**, atop **#216**, which completed the macOS CI
signal-integrity arc by retiring R2 and R4 with discriminating
witnesses, atop **#215**, which built the registry. **That arc is
retired**; its live residue (R1, R3, and the newer R5 and R6) is
re-homed to the async-runtime, reap-ledger, and readiness-helper-audit
lanes in `docs/active-work.md`.
The live CI-triage rule in §5 points at `docs/ci-red-signatures.md`,
which keys on **signature, not test name** — and, since 2026-08-06,
on **signature plus date**: a red matching a retired row is a
recurrence only if it *postdates* the retirement, and an earlier one
corroborates instead. The hazards list this file used to carry is
retired, and its two unevidenced entries are audit notes there.
Previously **2026-08-04, as bottom-panel Stage 3 #213 — the adopter
default flip, which COMPLETES ARC 7: omitting `display` now means the
panel, and the workbench's panel half is done on both frontends. Beneath
@ -75,9 +83,16 @@ reads it the way you just did.
For volatile branches, checkpoints, verification, and recovery
commands, read `docs/active-work.md` immediately after this file.
## 1. Where the project stands (2026-08-01)
## 1. Where the project stands (2026-08-06)
- **`main` @ `f186253`.** Bottom-panel Stage 3 **#213** completes Arc 7,
- **`main` @ `db1bbe9`.** The **tree primitive #217**`listview` rows
take optional `depth`/`id`, collapse is primitive-owned, folding is
**local projection state and not a refresh protocol**, and the LSP
outline is the sole adopter (`COHERENCE.md` §14 ◐; §20 says adoption,
not construction). Atop `2657568` **#216**, which completed the macOS
CI signal-integrity arc, atop `12f2970` **#215**, which built
`docs/ci-red-signatures.md`. Beneath those, `f186253`: bottom-panel
Stage 3 **#213** completes Arc 7,
atop the post-release accuracy pass #212 and `000b6cd` / **v1.1.0**.
Beneath that, Distribution Stage 1 #211
lands atop the docs absorption #210, the CI CRDT coverage lane #209,
@ -137,13 +152,27 @@ commands, read `docs/active-work.md` immediately after this file.
reason the anchor consumer works, because **the outline has no
`on_refresh` at all**. A design requiring the consumer to re-supply
rows on every fold would have fitted no existing consumer.
- **Identity is consumer-supplied and compared by equality; the
primitive never derives one.** `item` is opaque by design. The
outline uses `line:col`, because the `::` parent chain collides on
overloads and same-named siblings — exactly where a stale expansion
would reattach to the wrong node. **Selection is re-seated by id,
not by line**, since a fold inserts or removes rows above the
cursor.
- **Identity is consumer-supplied and the primitive never derives
one**, but it is **not opaque**: `row.id` must be a **string or
number, unique among rows, and not NaN**, enforced by `check_ids`
where rows enter (`open` and `refresh`). Review narrowed this from
"opaque, compared by equality", which was **two contracts wearing
one name** — selection compares with `==`, honouring `__eq`, while
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. Uniqueness and not-NaN came
from the same pass: every lookup resolves to the **first** match,
so a duplicate makes selecting the later row toggle the earlier,
and `0/0` is a `number` Lua refuses as a key. The outline uses
`line:col`, because the `::` parent chain collides on overloads and
same-named siblings — exactly where a stale expansion would
reattach to the wrong node. **Selection is re-seated by id, not by
line**, since a fold inserts or removes rows above the cursor.
- **`item` is optional in the API and was mandatory in practice.**
`line_to_item` is sparse when a row omits it, and `seat_cursor`
took `#` of that map — a display-only tree stranded the cursor on
the header. It counts visible rows explicitly now. Every existing
test supplied `item`, so none could reach it.
- **`has_children` must read the FULL row array, not the rendered
subset.** A collapsed node's children are absent from the rendered
map by construction, so asking the view would answer "no" for every
@ -2236,6 +2265,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

@ -79,18 +79,42 @@ Main-branch greens are **occurrence evidence** and accumulate toward a
rate. They retire nothing by themselves. Retired rows stay in this file
with their disposition, so a recurrence is recognisable.
**A red matching a RETIRED row is a recurrence, and it puts the
retirement in question — it is not a known flake.** The claim a
retirement makes is that the mechanism is gone; the same signature
afterwards falsifies that claim, which is a stronger finding than a live
row, not a weaker one. Reopen the row rather than rerunning.
**A red matching a RETIRED row AND POSTDATING ITS RETIREMENT is a
recurrence, and it puts the retirement in question — it is not a known
flake.** The claim a retirement makes is that the mechanism is gone
*from the retirement forward*; the same signature afterwards falsifies
that claim, which is a stronger finding than a live row, not a weaker
one. Reopen the row rather than rerunning.
**A matching red that PREDATES the retirement corroborates the row
instead.** It is an additional occurrence of the mechanism the fix
removed, so it strengthens the evidence and challenges nothing. Add it
to the row's evidence; do not reopen. This is not a technicality — an
occurrence scan reaches backwards by construction, so most matches it
finds will be of this kind, and treating them as recurrences would
reopen every retired row the first time anyone looked.
**Both halves need the date, which means a row is unmatchable without
one.** R2's second occurrence (`main` run 30710662474, 2026-08-01, four
days before its 2026-08-05 retirement) is the worked example, and it
also shows the flavor field is not part of matching: R2's first
evidence is macOS / lua54 and that one is macOS / luajit.
---
## 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
@ -144,6 +168,64 @@ diagnosis by the process-signal / reap-ledger lanes.
---
### 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.
## Retired rows
**These stay here on purpose.** A retirement is a claim that a mechanism
@ -160,7 +242,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 +268,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