Transient ZeroGPU per-IP quota/429 is now a HEALTHY busy outcome, not a broken-app 500.
server/health.py: BUSY_RE + classify_exception busy branch (wedge keeps precedence); 'busy' added to STATUSES and treated as healthy in record() (never degrades).
app.py: BUSY_REASON copy; _awaken classifies once and returns HTTP 200 {refused,quota,retry} on busy instead of the generic seance-failed 500.
web/: capture.js retains the photo + normalizes busy (structured or thrown), retryAwaken re-submits the same photo; main.js renders an honest busy panel ('try again' + sign-in link, softens after retries); seance.js busy() state; style.css busy panel styling.
pareidolia: seam fix β geometry-gate provenance rides PipelineOutcome into the awaken record (was dropped at the wiring adapter)