disclosure-bureau/infra/supabase/migrations/0009_pro_anomaly_briefs.sql

50 lines
2.1 KiB
MySQL
Raw Normal View History

W5.5 (Phase 3C): Sun-Tzu strategist feeder + entity hero illustrations Sun-Tzu (silent backend) — builds the strongest pro-anomaly brief the corpus supports for any topic. Bilingual JSON: thesis + 2-4 pillars (each with claim + citation-backed support) + honest residual unexplained clause. NEVER surfaced reader-facing. Migration 0009 (apply as supabase_admin): public.pro_anomaly_briefs brief_pk BIGSERIAL PK brief_id B-NNNN unique topic + topic_pt_br thesis + thesis_pt_br pillars JSONB unexplained + unexplained_pt_br doc_id, job_id, created_by, created_at + brief_id_seq sequence + GIN trigram indexes on topic + topic_pt_br + RLS policies (investigator INSERT, public SELECT) + GRANTs on seq + table to investigator prompts/sun-tzu.md "Adversarial strategist who plays the pro-disclosure side with the same rigour a red-team plays skeptic" — single thesis, 2-4 pillars, honest residual. Every claim cites a chunk. No fabrication from training-time knowledge. Output INTERNAL — case-writer pulls it. Bilingual mandatory. NO_STRONG_CASE sentinel when corpus is thin. detectives/sun_tzu.ts Grounds with hybridSearch top 18 chunks, calls Sonnet, parses JSON strict, calls writeProAnomalyBrief. tools/write_pro_anomaly_brief.ts Validates 2-4 pillars with bilingual claim+support, requires at least one [[wiki-link]] citation per pillar, INSERTs. orchestrator: new kind "anomaly_brief" dispatches Sun-Tzu. Case-writer integration (detectives/case_writer.ts): - Pulls most recent matching brief via ILIKE on topic or doc_id. - Renders brief as a separate prompt section labelled "Strategic brief (internal — do NOT cite or attribute)". - Instructs the narrator to weave the thesis as a quiet through- line, use pillar facts in scenes, let the unexplained clause inform the closing paragraph. Forbidden to name "the analyst", say "a brief argues", or use the words "thesis"/"pillar" explicitly. Translate it into prose. Entity hero illustrations: - 3 painterly editorial illustrations generated via Nano Banana Pro at 2K, stored under /data/disclosure/processing/case-art/: * EV-1947-06-24-kenneth-arnold-sighting.png — cockpit POV of Arnold in a CallAir A-2 over Mount Rainier, 9 chevron disc objects in formation, 1947 Life-magazine register. * EV-1947-07-08-roswell-incident.png — debris field in NM desert, USAAF officer in 1947 uniform examining foil fragments, period staff car. * EV-1947-06-21-maury-island-incident.png — wooden patrol boat on Puget Sound, 6 doughnut craft hovering, one shedding glowing slag, Harold Dahl + son + dog watching. - app/e/[cls]/[id]/page.tsx: full-bleed editorial hero replaces the old gradient header card when an illustration exists for that entity_id. Title sits over the painting with gradient overlay. "Ilustração editorial" chip in the top-right. Quota note: Claude OAuth still rate-limited as of this commit, so Sun-Tzu hasn't been smoke-tested in production. Code is shipped and ready; first brief will land when the weekly quota refreshes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 19:41:20 +00:00
-- 0009_pro_anomaly_briefs.sql — Sun-Tzu's silent intermediate artefact.
--
-- The strategist produces one brief per topic. The case-writer pulls
-- the brief at narrative-assembly time and weaves the thesis + pillars
-- into a confident closing scene. The brief is NEVER surfaced reader-
-- facing — the table is internal to the runtime.
--
-- Apply as supabase_admin.
BEGIN;
CREATE SEQUENCE IF NOT EXISTS public.brief_id_seq START 1;
CREATE TABLE IF NOT EXISTS public.pro_anomaly_briefs (
brief_pk BIGSERIAL PRIMARY KEY,
brief_id TEXT UNIQUE NOT NULL, -- B-NNNN
topic TEXT NOT NULL,
topic_pt_br TEXT,
doc_id TEXT, -- optional scope
thesis TEXT NOT NULL,
thesis_pt_br TEXT NOT NULL,
pillars JSONB NOT NULL, -- [{claim,claim_pt_br,support,support_pt_br}]
unexplained TEXT NOT NULL,
unexplained_pt_br TEXT NOT NULL,
created_by TEXT NOT NULL DEFAULT 'strategist@detective',
job_id UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS pro_anomaly_briefs_topic_trgm
ON public.pro_anomaly_briefs USING gin (topic gin_trgm_ops);
CREATE INDEX IF NOT EXISTS pro_anomaly_briefs_topic_pt_trgm
ON public.pro_anomaly_briefs USING gin (topic_pt_br gin_trgm_ops);
CREATE INDEX IF NOT EXISTS pro_anomaly_briefs_doc_idx
ON public.pro_anomaly_briefs (doc_id) WHERE doc_id IS NOT NULL;
-- Grants — investigator role (least privilege)
ALTER TABLE public.pro_anomaly_briefs ENABLE ROW LEVEL SECURITY;
GRANT SELECT, INSERT ON public.pro_anomaly_briefs TO investigator;
GRANT USAGE, SELECT, UPDATE ON SEQUENCE public.brief_id_seq TO investigator;
GRANT USAGE, SELECT, UPDATE ON SEQUENCE public.pro_anomaly_briefs_brief_pk_seq TO investigator;
CREATE POLICY pro_anomaly_briefs_read ON public.pro_anomaly_briefs FOR SELECT USING (true);
CREATE POLICY pro_anomaly_briefs_insert ON public.pro_anomaly_briefs FOR INSERT
TO investigator, postgres, service_role WITH CHECK (true);
COMMIT;