From the poka-yoke audit of 2026-09-04. Lens: motion-step. Today: rung 3. Device reaches: rung 1 (Control). Silent.
The mistake available
Restore a backup with a different secret.key, or rotate the key.
internal/db/hooks.go:58:
if plain, err := box.Open(sealed); err == nil {
h.Secret = plain
}
// err != nil: the row loads with an empty secret
internal/hooks/dispatch.go:602 then signs with nothing, and the POST goes out
unsigned.
What happens
The receiver cannot distinguish an unsigned delivery from a forgery. The signing
secret is the only thing that made the webhook trustworthy, and its absence is
indistinguishable, at the far end, from a hook that never had one.
internal/db/platforms.go:52 handles the identical situation the other way and
fails loud — so the two halves of the same decision disagree.
Today
Rung 3, weakly: hasSecret:false appears on a list nobody polls.
Device → rung 1, Control
Keep the row, set SecretUnreadable — exactly as Destination.KeyUnreadable
already does for stream keys — and have the dispatcher refuse to deliver a
hook whose secret is unreadable, raising an alert.
That makes "unsigned delivery" unreachable rather than merely visible. The
precedent is in the same package and the field naming already exists.
From the poka-yoke audit of 2026-09-04. Lens: motion-step. Today: rung 3. Device reaches: rung 1 (Control). Silent.
The mistake available
Restore a backup with a different
secret.key, or rotate the key.internal/db/hooks.go:58:internal/hooks/dispatch.go:602then signs with nothing, and the POST goes outunsigned.
What happens
The receiver cannot distinguish an unsigned delivery from a forgery. The signing
secret is the only thing that made the webhook trustworthy, and its absence is
indistinguishable, at the far end, from a hook that never had one.
internal/db/platforms.go:52handles the identical situation the other way andfails loud — so the two halves of the same decision disagree.
Today
Rung 3, weakly:
hasSecret:falseappears on a list nobody polls.Device → rung 1, Control
Keep the row, set
SecretUnreadable— exactly asDestination.KeyUnreadablealready does for stream keys — and have the dispatcher refuse to deliver a
hook whose secret is unreadable, raising an alert.
That makes "unsigned delivery" unreachable rather than merely visible. The
precedent is in the same package and the field naming already exists.