Five ways a yes goes wrong
Each one below runs the real guard, not a mock-up. Pick one and watch the phone.
The recipient changes
You approved Alice. A bug or an attacker points the send at Bob. Swan compares the destination at send time.
The photo changes
The bytes leaving are not the bytes you reviewed. Swan compares them, byte for byte.
The glasses disconnect
Your yes came from a live camera session. When the session ends, the yes ends with it.
The photo goes stale
An approval covers a fresh capture. Past the capture window (5 seconds by default) the picture no longer counts.
The yes gets reused
An approval works once. The first send uses it up, so a second attempt has nothing to stand on.
And when nothing changed, it just sends.
One call between approval and send.
Your app shows the request and records the yes. Swan makes the send, and refuses anything the yes does not cover.
# Your app shows the exact request.
proposal = guard.propose(frame, payload, alice)
approval = guard.approve(proposal)
# Swan checks again before anything leaves.
result = guard.dispatch(
approval, proposal, payload, alice
)
# blocked | accepted | delivery_unknown
result["status"]
A changed picture, recipient, or camera session stops the send.