From the poka-yoke audit of 2026-09-04. Lens: motion-step. Today: rung 0. Device reaches: rung 1 (Control). Silent. MEASURED.
The mistake available
Release a port you no longer own. internal/relay/ports.go:57 is
delete(a.held, p) — an integer in, no notion of who held it.
internal/engine/destinations.go:1336 stopBackup deliberately does not
write to d (documented at length at :1324-1330), so after it runs
d.backupPort and d.backupSub still name released resources.
Reachable path: reconcileBackup:1232 calls stopBackup(prev) →
publishDest:1260 refuses (either e.stopped, or e.dests[id] != prev) →
prev stays in the map → StopWithin/teardownDest:1082 calls
stopBackup(prev) a second time.
Measured
HAZARD: after stopBackup the destination still records backupPort=65532
and backupSub="dest:1:backup"
HAZARD: port 63981 is now held by two owners at once; Release() twice
silently un-held B's port
What happens
Two engines are handed the same UDP port, and one programme's destination
receives another programme's stream — the exact failure PortAllocator's own
doc comment says the bind probe exists to prevent.
portFree() masks it only while the first owner's child is actually bound.
During supervisor restart backoff, or in the window between Allocate and
proc.Start(), it is wide open. Silent.
Today
None. The invariant lives in a doc comment.
Device → rung 1, Control
Allocate() (*Lease, error); Lease.Release() guarded by sync.Once; delete
the Release(int) method so a stale integer has no spelling.
Shares one device with the StopWithin leak issue — the same thirteen call
sites change shape for both, and doing them together is the only proposal in
this audit that reaches Control on two findings at once.
Interim → Warning: Release logs at error when !a.held[p].
From the poka-yoke audit of 2026-09-04. Lens: motion-step. Today: rung 0. Device reaches: rung 1 (Control). Silent. MEASURED.
The mistake available
Release a port you no longer own.
internal/relay/ports.go:57isdelete(a.held, p)— an integer in, no notion of who held it.internal/engine/destinations.go:1336stopBackupdeliberately does notwrite to
d(documented at length at:1324-1330), so after it runsd.backupPortandd.backupSubstill name released resources.Reachable path:
reconcileBackup:1232callsstopBackup(prev)→publishDest:1260refuses (eithere.stopped, ore.dests[id] != prev) →prevstays in the map →StopWithin/teardownDest:1082callsstopBackup(prev)a second time.Measured
What happens
Two engines are handed the same UDP port, and one programme's destination
receives another programme's stream — the exact failure
PortAllocator's owndoc comment says the bind probe exists to prevent.
portFree()masks it only while the first owner's child is actually bound.During supervisor restart backoff, or in the window between
Allocateandproc.Start(), it is wide open. Silent.Today
None. The invariant lives in a doc comment.
Device → rung 1, Control
Allocate() (*Lease, error);Lease.Release()guarded bysync.Once; deletethe
Release(int)method so a stale integer has no spelling.Shares one device with the StopWithin leak issue — the same thirteen call
sites change shape for both, and doing them together is the only proposal in
this audit that reaches Control on two findings at once.
Interim → Warning:
Releaselogs at error when!a.held[p].