Token consolidation:
- docker-compose web service now reads ${CLAUDE_CODE_OAUTH_TOKEN} directly,
drop the W1-F8 CLAUDE_CODE_OAUTH_TOKEN_FOR_WEB indirection (user feedback:
one var name, no _FOR_WEB suffix).
investigator-runtime claude.ts:
- --system-prompt silently dropped by CLI v2.1.150 for multi-KB prompts;
inline the system content into the user prompt with a separator
(mirrors scripts/reextract/run.py pattern).
- Multi-line prompts via positional -- broke ("Input must be provided …");
pipe via stdin instead.
- --allowedTools "" is rejected; when no tools wanted, omit it and explicitly
--disallowedTools the writer/reader set so the model can't reach for any.
investigator-runtime locard.ts:
- Log the raw response (first 600 chars) to container stderr — saved hours
of debugging when the writer rejected.
- Grade fallback: when Locard omits `grade` but provides custody_steps,
infer the highest grade that fits (≥3 → A, ≥2 → B, ≥1 → C).
investigator-runtime write_evidence.ts:
- Filter related_hypotheses entries with empty/null hypothesis_id silently
(Locard sometimes emits [{}] when it knows no link yet) instead of
failing the whole write.
Migration 0006_investigator_serial_sequences.sql:
- BIGSERIAL on the 7 investigation tables created auto-sequences
(evidence_evidence_pk_seq etc) that 0004 forgot to GRANT to the
investigator role. Without those grants every INSERT failed with
"permission denied for sequence …". Grant USAGE/SELECT/UPDATE on each
auto-seq.
Verified live: Locard wrote E-0002 + E-0003 from real Sandia chunks
(green fireball Feb 1949; cobalt particle analysis). Grade B, confidence
high, custody chain of 3 steps with honest gaps. Cost $0.09 for both,
~70s wall.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| coolify | ||
| disclosure-stack | ||
| embed-service | ||
| supabase | ||
| DEPLOY-CHECKLIST.md | ||
| README.md | ||
| RETRIEVAL.md | ||
Infrastructure — Disclosure Bureau
Self-hosted stack on a single VPS (16 GB / 4 CPU / 200 GB NVMe) managed via Coolify.
Internet (443/80)
│
┌─────────▼─────────┐
│ Caddy (Coolify) │ ← auto-TLS Let's Encrypt
└────┬──────────────┘
│
┌─────────────┼──────────────────────┬──────────────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Next.js │ │ Supabase │ │ Supabase │ │ shared │
│ web │ │ disclosure│ │ project-B │ │ services │
│ :3000 │ │ stack │ │ stack │ │ Meili··· │
└─────────┘ │ ┌─────┐ │ │ ┌─────┐ │ │ Imgproxy │
│ │PG/GT│ │ │ │PG/GT│ │ │ Dragonfly│
│ └─────┘ │ │ └─────┘ │ └──────────┘
└──────────┘ └──────────┘
disclosure.top projeto-b.com
Components
| Layer | Service | Notes |
|---|---|---|
| Orchestration | Coolify v4 | Self-hosted PaaS — manages all containers, TLS, backups |
| Database + Auth + Storage | Supabase self-hosted (one per project) | Each project gets own Postgres + GoTrue + Storage |
| Frontend | Next.js 15 (this repo's /web) |
Deployed via Coolify Git integration |
| Search | Meilisearch (shared) | Full-text search across pages + entities |
| Cache + Queue | Dragonfly (shared) | Redis-compatible, multi-threaded |
| Images | Imgproxy (shared) | On-the-fly resize / WebP conversion |
| Backups | restic + Backblaze B2 | Nightly Postgres + Storage dumps |
Quick path
coolify/INSTALL.md— install Coolify on the fresh VPS (~10 min)coolify/SUPABASE.md— create thedisclosureSupabase project (~5 min)- Run
supabase/migrations/0001_chat_schema.sqlvia Supabase Studio SQL editor coolify/NEXTJS.md— deploy the/webapp pointing at the Supabase URLcoolify/SHARED.md— bring up Meilisearch, Dragonfly, Imgproxy
Adding more projects later
For each new project, repeat step 2 (new Supabase project in Coolify UI) and step 4 (new Next.js app). They get their own subdomain, own auth, own data. Total isolation.
Local development
For dev on macOS/Linux without the VPS, see ../web/README.md — uses the Supabase CLI to spin up a local stack on localhost:54321.