Context
Currently passports are either active or permanently revoked. There is no intermediate state for temporary suspension — e.g. when an agent is under investigation or a payment dispute is open. A suspended status lets admins freeze a passport without permanently revoking it.
What to implement
Status addition
Add 'suspended' to the passport status union:
type PassportStatus = 'active' | 'revoked' | 'expired' | 'suspended'
Routes
- POST /api/protocol/passport/[id]/suspend — set status to
suspended; body: { reason: string }
- POST /api/protocol/passport/[id]/unsuspend — set status back to
active; body: { reason: string }
Both require admin auth. Both fire an audit log entry (issue #108) and a webhook event (passport.suspended / passport.unsuspended).
Authorization check
Any endpoint that validates a passport (spending, verification) must treat suspended as a denial — same as revoked, but with a distinct error code passport_suspended.
Acceptance criteria
🎁 Evidencia visual = reward extra
- Si tu PR incluye video demo o capturas de pantalla mostrando la funcionalidad pedida funcionando end-to-end, va a ser considerado para rewards de GrantFox en esta issue. No es obligatorio, pero suma mucho para la evaluación.
Context
Currently passports are either active or permanently revoked. There is no intermediate state for temporary suspension — e.g. when an agent is under investigation or a payment dispute is open. A
suspendedstatus lets admins freeze a passport without permanently revoking it.What to implement
Status addition
Add
'suspended'to the passport status union:Routes
suspended; body:{ reason: string }active; body:{ reason: string }Both require admin auth. Both fire an audit log entry (issue #108) and a webhook event (
passport.suspended/passport.unsuspended).Authorization check
Any endpoint that validates a passport (spending, verification) must treat
suspendedas a denial — same asrevoked, but with a distinct error codepassport_suspended.Acceptance criteria
🎁 Evidencia visual = reward extra