Production platform: deployment architecture, nightly eval canary, capacity review - #332
Conversation
…ry, capacity review - docs/deployment-architecture.md: decided topology — single warm Next.js container co-located with Supabase ap-southeast-2; containerized worker (recommended over completing the edge-agent migration, with reasoning); claim_ingestion_jobs durability semantics (no heartbeat, 45-min stale reclaim, attempts consumed at claim = implicit dead-letter); secrets matrix; dedicated staging Supabase project. - Dockerfile (app): Node 24 multi-stage, engine-strict respected, runs the repo's own npm run build in the build stage; non-root runtime, /api/health HEALTHCHECK. Verified: image builds green and boots serving 200s. - Dockerfile.worker: Node 24 + tsx + Tesseract + Python venv (PyMuPDF, Pillow, pytesseract). Verified: OCR imports and tesseract run in-image. - docs/observability-slos.md: SLOs + alert thresholds for answer p95 by route mode, source-gap rate, unsupported rate, hybrid_rpc_errors rate, degraded-answer rate, with measurement SQL over rag_queries metadata. - .github/workflows/eval-canary.yml: nightly scheduled + workflow_dispatch canary running eval:retrieval:quality and an eval:quality --rag-only subset against production with repo secrets; preflights secrets, guards project identity, opens/updates a GitHub issue on scheduled failures. - docs/capacity-review.md: 30-clinician ward-round load model vs the auth 10-connection cap, PostgREST pooling, ~6-RPC answer fan-out, OpenAI limits, and coalescing; first bottleneck = auth connection cap (hard), Postgres CPU under hybrid-RPC concurrency (soft). - scripts/soak-test.ts: staging-only ward-round soak driver (guards refuse production markers and require --confirm-staging); exercised end-to-end against a local container. No src/lib retrieval/answer code touched. verify:cheap green (1143 tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Uh oh!
There was an error while loading. Please reload this page.
BigSimmo
commented
Jul 6, 2026
Concretely:
|
BigSimmo
commented
Jul 8, 2026
✅ Post-merge canary dispatch test done — run 28919595072. Confirms the workflow wiring end-to-end. Every step up to the eval passed — secret preflight, Node setup, This is the expected outcome given the stale secret: |
BigSimmo
commented
Jul 8, 2026
🔑 Secrets update confirmed working. Re-dispatched the canary after the 07-08 secret refresh — run 28939769131. The The run still exits 1, but now on a different, non-secret cause: |
Summary
Three production-platform workstreams, per the branch brief. No
src/libretrieval/answer code touched (parallel chats own those files); no live Supabase settings touched.1. Deployment topology (
docs/deployment-architecture.md+ Docker images)sjrfecxgysukkwxsowpy(ap-southeast-2, confirmed via read-only project lookup). Fly.iosydrecommended; serverless explicitly rejected (in-memory answer coalescing/caches are load-bearing, fire-and-forget post-response work, 30 s strong-route requests, auth 10-conn amplification).Dockerfile.worker) rather than completing the edge-agent migration — PyMuPDF/Tesseract are native binaries that cannot run in Deno isolates, jobs run multi-minute against edge ceilings, andclaim_ingestion_jobsis already multi-instance-safe.indexing-v3-agentstays as the completion/repair gate.claim_ingestion_jobssemantics — no heartbeat;locked_atset once at claim; 45-min stale reclaim; attempts consumed at claim, so crash-looping jobs exhaustmax_attemptsinto terminalfailed(implicit dead letter, recovered viarecover:ingestionunder the rollback fence). Rule: stale window must exceed p100 job runtime; heartbeat-on-progress-update flagged as backlog.check:supabase-projectwill need env-aware expected-project config when staging is provisioned — deliberate speed bump, documented).Verified:
docker build .→npm run buildcompiled successfully inside the container (gate) ✅/api/health200 (status: ok),/200, ready in 563 ms ✅tesseract 5.3.0,import fitz, pytesseract, PILOK, tsx on Node 24.18.0 ✅2. Observability + eval canary (
docs/observability-slos.md,.github/workflows/eval-canary.yml)routing_mode, source-gap rate, unsupported rate,hybrid_rpc_errorsrate (near-zero tolerance — this is the silent-degradation guard), degraded/source-only rate. Measurement SQL overrag_queries.metadataincluded.workflow_dispatch: secret preflight →check:supabase-project→eval:retrieval:quality --fail-on-threshold→eval:quality --rag-only --limit 8 --fail-on-threshold. On scheduled failure it opens/updates a GitHub issue labeledeval-canary. This makes the golden eval (which PR CI can never run) a standing nightly guard.SUPABASE_SERVICE_ROLE_KEY,OPENAI_API_KEY,E2E_USER_EMAIL), andcheck:supabase-projectpasses with exactly the env the workflow sets.workflow_dispatchcannot be tested pre-merge — GitHub returns 404 for workflows absent from the default branch (attempted:gh workflow run eval-canary.yml --ref claude/production-platform). First post-merge step:gh workflow run eval-canary.ymland confirm green before trusting the schedule. This is called out in the workflow header and the SLO doc.3. Capacity review (
docs/capacity-review.md,scripts/soak-test.ts)scripts/soak-test.ts: staging-only ward-round load driver. Guards verified: refuses without--target, refuses without--confirm-staging, refuses hosts matching the production project ref. Full loop exercised end-to-end against a local container (fixture queries loaded, 75/25 search/answer mix, percentile summary, 5% failure gate). Not run against production.Gates
verify:cheap✅ (lint, typecheck, sitemap, 1143/1143 unit tests)npm run build) ✅; container boot smoke ✅format:check: new files clean; the only warning is pre-existing local CRLF noise onCLAUDE.md(byte-identical to main)Post-merge checklist
gh workflow run eval-canary.yml→ confirm green before trusting the nightly schedule.🤖 Generated with Claude Code