{
  "schema": "raven-status-policy/1",
  "note": "Static dependency and fail-behavior disclosure — not a live uptime page.",
  "components": {
    "launch_console": "static, Vercel-hosted; no backend, no keys in browser code",
    "hosted_verifier": "Render-hosted backend; /verify depends on its availability",
    "pubkey": "public, no auth; should remain available for receipt verification",
    "healthz": "indicates verifier availability and signer presence",
    "solana_rpc": "server-side only; network/RPC availability can affect checks; callers can never supply rpcUrl (rejected 400)"
  },
  "fail_behavior": {
    "verifier_error": "fail closed — 502/503, never an unsigned or guessed verdict",
    "signer_unavailable": "503; an official verifier that cannot sign does not serve",
    "rate_limited": "429; back off (10/min/key, burst 4; 30/min/IP)",
    "graceful_fallback": [
      "retry later",
      "request access at /request-access.html",
      "use MCP local (npx -y raven-verify-mcp) where applicable"
    ]
  },
  "hard_rules": [
    "rejects user-supplied rpcUrl",
    "rejects user-supplied issuerIdentity",
    "no API keys in browser code",
    "no secret logging — sanitized ledger only",
    "no signatures/private keys/API keys in logs"
  ],
  "resilience": {
    "backoff": "Integrators back off on 429, 5xx, and timeouts; repeated verifier failures should trigger operator escalation, not optimistic retries.",
    "rateLimitsAreSafetyControls": "Per-key rate limits protect Raven and integrators from verification loops, quota exhaustion, and batch abuse - they are safety controls, not just cost controls.",
    "unavailabilityIsBlocked": "Verifier unavailability is a blocked/deferred state for material action; /healthz indicates availability but is not a receipt.",
    "cachedReceipts": "Cached exact receipts may be used only within staleness policy and never for a delayed material action without reverification."
  }
}