The phase-5 dry-run gate failed on its first live run: the engine built to
v3.4 could not see its own primary taint root (echo, AEC off) while excluding
every stream on the machine (silence). One cause — the PipeWire registry
`global` event carries only a filtered subset of an object's properties, and
eight the design depends on are never announced.
Design doc (v3.4 → v3.5):
- NEW §6.7 — the observation boundary. The global is an index, not a source of
truth: bind every Node and Device, `info` props are the sole source, live
prop tracking, one readiness obligation per unbound node, fail closed.
Four user design calls recorded.
- §5.1 — a second, registry-visible tag carrier (`node.name` prefix) alongside
`peerspeak.owned`, so the primary root does not rest on one mechanism.
- §6.4 — node/device props are not an optimisation to skip, they are
unavailable from the global; the round-6 Link lesson was right and applied
to exactly one object type.
- §6.1.0, §6.1.4 — the two corrections the impl plan owed v3.5: a
time-dependent "hazard is LIVE" claim, and an unreachable nominated test
case (twice over).
- §9.1 measured facts, §12 rig discipline (pw-dump binds; the registry does
not), §14 readiness.
Impl plan:
- NEW phase 3r with a four-part exit gate, the first the direct inverse of the
finding. Ports deliberately not bound in v1, with a revisit trigger.
- Phase 1 pins the second carrier literal as a cross-repo contract.
- Phase 5 marked GATE FAILED; matrix and O5 re-run after 3r and 1.
- Risk register: the over-exclusion row fired and worked; new row for the
observation boundary class.
Architecture is unchanged and vindicated: fed correct properties, the engine
decided correctly in every fixture. The §5.1 exact-partition requirement is
what caught this — every exclusion was defensible and the eligible half was
empty.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>