The consumer half of phase 1 (plan §5.1, impl plan §3). The engine's tag root becomes a union: `peerspeak.owned` truthy OR `node.name` starting with `peerspeak_owned_`. Round 8 added the second carrier because a node property is invisible to the registry `global` event and recoverable only by binding the node — which is exactly how the phase-5 gate failed — while `node.name` is announced directly. The union lives in `local_root_reason`, not in the adapter. Folding both into the one `peerspeak_owned` bool at the observation boundary would make each carrier untestable alone, which is the phase-3r lesson: a gate asserting a value two sources can satisfy gates neither. The existing `peerspeak_tagged_nodes_…` fixture now carries both carriers, so it would keep passing if either were deleted; two new tests pin them individually, and a third pins that the prefix matches only at the start of a name. Both literals are now named constants — they are a cross-repo wire contract with peerspeak, not local naming — and asserted against tests/fixtures/ownership-tag-contract.txt, committed byte-identical in both repos. That test also runs the fixture's own worked example name through the engine, so the shared file cannot document a value this side does not actually exclude. Five mutations verified: drop either carrier, loosen `starts_with` to `contains`, or rename either constant, and exactly the intended test fails. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
35 lines
1.7 KiB
Plaintext
35 lines
1.7 KiB
Plaintext
# Screenshare audio exclusion — ownership tagging wire contract.
|
|
#
|
|
# peerspeak PRODUCES these carriers on every audio node it owns; pixelpass
|
|
# CONSUMES them as the primary taint root of the exclusion engine. Neither
|
|
# repo depends on the other, so this file is the contract: it is committed
|
|
# byte-identical in both, and each repo has a test that asserts its own named
|
|
# constants (and, on the producer side, the environment a real child Command
|
|
# would carry) match these values exactly.
|
|
#
|
|
# peerspeak/tests/fixtures/ownership-tag-contract.txt
|
|
# pixelpass/tests/fixtures/ownership-tag-contract.txt
|
|
#
|
|
# Pinned by peerspeak docs/screenshare-audio-exclusion-impl-plan.md §3 and
|
|
# docs/screenshare-audio-exclusion-plan.md §5.1 (v3.5). Changing a value here
|
|
# is a cross-repo breaking change: both repos must land in the same session,
|
|
# and the phase 5 matrix must be re-run.
|
|
#
|
|
# Two carriers, matched as a UNION — a node is peerspeak-owned if EITHER
|
|
# matches. Round 8 added the second because a property is invisible to the
|
|
# PipeWire registry `global` event and readable only via a node bind, so the
|
|
# primary taint root must not rest on one observation mechanism alone.
|
|
|
|
# Carrier 1 — a node property. The consumer treats any value other than
|
|
# "false"/"0" as truthy, which is the fail-closed direction; the producer
|
|
# always emits exactly this value.
|
|
prop_key=peerspeak.owned
|
|
prop_value=1
|
|
|
|
# Carrier 2 — a `node.name` prefix, announced by the registry without a bind.
|
|
# `node.description` is deliberately NOT touched, so mixers still show "mpv".
|
|
# Only the prefix is matched; the rest of the name is for diagnostics.
|
|
node_name_prefix=peerspeak_owned_
|
|
node_name_format=peerspeak_owned_<role>_<pid>
|
|
node_name_example=peerspeak_owned_mpv_31284
|