docs: record F11-1 closed — boundedness needs a resolved Client

Design v3.7 §6.1.1 gains the round-13 box (the rule, the ordering that is
load-bearing in both directions, and why bridging deliberately still uses the
full union); the phase-5 results file records the close with the measurement
the deferral was waiting for; the impl plan's phase-6 gate note drops F11-1.

pixelpass c78eb2d is the implementation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 04:46:25 -04:00
co-authored by Claude Opus 5
parent bf908adbf0
commit 692ad677d2
3 changed files with 62 additions and 20 deletions
@@ -4,8 +4,8 @@
eligible half of every row is non-empty. O5 re-measured on the fixed graph and
stays closed.** One new defect was found and fixed during the run (F13-1); three
findings are recorded as non-blocking, and three rows carry recorded
substitutions. Phase 6 is unblocked **by this file**, but see "What still blocks
phase 6" — F11-1 is a separate gate and is still open.
substitutions. Phase 6 is unblocked **by this file**, and F11-1 — the other gate —
was closed with this data on 2026-07-26 (see "What still blocks phase 6").
- **Run date:** 2026-07-26 (run 1: 2026-07-25, gate FAILED — see history below)
- **Host:** `cazen` — PipeWire 1.6.8, WirePlumber 0.5.15, CachyOS
@@ -332,24 +332,41 @@ lesson: the row could not have been asserted from any previous build's output.
## What still blocks phase 6
This file passing removes **one** of the two gates. Still outstanding:
This file passing removes **one** of the two gates. F11-1, the other, is now
closed. Still outstanding:
1. **🔴 F11-1 — the owner-key union can *reduce* taint.** Unchanged and still
open; it was to be decided *with* this matrix data. The data now exists: the
suppression path is live and correct (F13-1 fixed), and rows 2/9 show key 4
doing real work, which means the interaction F11-1 describes is reachable in
principle. The rule to implement is written in `owner_is_bounded`'s doc in
pixelpass `src/host/taint/owner.rs`, sharpened by Codex round 12: "resolved"
must mean **an unambiguous Client yielding `Some(pipewire.sec.pid)` before
pipewire-pulse suppression**. A five-case Client matrix (absent · ambiguous ·
unique-but-pid-less · resolved-native · resolved-to-pipewire-pulse) is owed.
2. **Hardware playback-to-capture paths ("Stereo Mix")** defeat `session_device`
1. **Hardware playback-to-capture paths ("Stereo Mix")** defeat `session_device`
and are a real echo path — needs ALSA control inspection; user design call owed.
3. **Phases 0b / 0c / 0d** are untouched and all precede phase 6.
4. **The readiness budget calibration argument** (above).
5. **Owed samples:** a real third-party forwarder (row 1b), EasyEffects (row 8),
2. **Phases 0b / 0c / 0d** are untouched and all precede phase 6.
3. **The readiness budget calibration argument** (above).
4. **Owed samples:** a real third-party forwarder (row 1b), EasyEffects (row 8),
a real `Audio/Duplex` device (row 13).
### ✅ F11-1 — closed 2026-07-26, with this matrix's data
The rule now implemented (pixelpass `c78eb2d`, §6.1.2's round-13 box): **key 4 bounds an
owner only when the node's Client resolves** — an unambiguous Client yielding
`Some(pipewire.sec.pid)`, read *before* pipewire-pulse suppression — so a node can no
longer bound itself, and escape `propagate_unresolved_owner`'s sweep, with an
`application.process.id` it invented. Bridging still uses the full union.
Codex's round-12 sharpening was the decisive part: "resolved" must mean a `sec_pid`, not
"a unique Client object exists", and the **unique-but-pid-less** row is the only one that
tells the two apart. All five Client cases are unit tests (absent · ambiguous ·
unique-but-pid-less · resolved-native · resolved-to-pipewire-pulse), plus the recorded
three-step leak path end to end. Mutation-verified: dropping the provenance test fails
four of the six rows and leaves the two no-over-exclusion rows green.
**The cost question the deferral was waiting on, measured on this host:** the before- and
after-binaries audited the *same* live graph simultaneously (both are read-only observers)
— tagged producer into the default sink, `parec` on its monitor as a live tainted reader
so the sweep was genuinely armed, Firefox + `aplay` + `pacat` as bystanders. **181 records
each, the same 14 distinct decision states, none exclusive to either side, no
`unresolved-owner` on either, eligible half non-empty throughout.** O5 unmoved (identical
p50 15 µs and busy fraction 0.0012). Every real app here is native or Pulse-emulated and
**both resolve**; sweeping all 18 live nodes, the only unresolved-Client ones were
`Dummy-Driver` and `Freewheel-Driver`, which carry no pid key to lose.
---
## Reproducing this run