{ "feature_id": "CLUB-004", "agent": "security", "stage": "security_gate", "verdict": "APPROVED", "security_check": "security", "summary": "Códigos hasheados con SHA-256, plaintext nunca persiste en DB. Race condition mitigada con FOR UPDATE.", "checks": { "storage": "OK: code_hash = SHA-256(plaintext), code_fingerprint = truncated hash", "race_condition": "OK: consumeRecoveryCode usa FOR UPDATE + COMMIT en la misma transacción", "expiry": "OK: códigos caducan a los 30 días", "single_use": "OK: used_at se marca tras consumo exitoso", "token_storage": "OK: device token hasheado igual que en DEVICE flow" }, "timestamp": "2026-08-26T20:48:10Z" }