Neither ownership carrier is a security boundary — both are strings any
unprivileged process can put on its own node — so an unrestricted taint
root is a denial of the whole feature. An unlinked Stream/Input/Audio
named `peerspeak_owned_rogue` is a tainted *reader* (receivers includes
nodes by role, no link required) and an unbounded one, so
propagate_unresolved_owner fails every candidate on the machine closed.
Measured before this change: BASELINE eligible=1 excluded=[] became
WITH IMPOSTOR eligible=0 excluded=[firefox -> unresolved-owner].
Restricting the root to Stream/Output/Audio costs nothing real —
peerspeak only ever tags playback streams — and the AEC's virtual
sink/source is untouched, since it roots on module id, not on this tag.
A tag that is ignored is not silent: misplaced_ownership_tags feeds a
new `ignored_ownership_tags` audit field (omitted when empty), because
the fix *removes* an exclusion, and the two causes of a dropped tag —
a peerspeak tagging bug, or an impersonation attempt — both want seeing.
Codex phase-1 review F2, reproduced live. Round 10, R10-1.
5 new rows, mutation-verified: dropping the role restriction kills both
engine rows, and stubbing the diagnostic kills the third.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>