-- Phase completion summaries. -- -- When a mission_phase reaches terminal state, `phase_summarizer` calls -- Claude Opus 4.8 with all the phase's checkpoint outputs + task-card -- rows + artifact rows and gets back a structured JSON payload that -- fuels the UI's phase-completion card (narrative + metrics + sources -- + tooling recommendations + next actions). -- -- ONE row per (mission_phase). Re-generation is allowed (retry) and -- overwrites via the unique index below. -- -- `metrics` shape varies by kind: -- research → { insights, sources, int_cards, artifacts, tokens, turns } -- coding → { cards_picked_up, cards_closed, commits, tests_added, -- tests_passing, tests_failing, issues_found, issues_fixed } -- benchmark → { snapshots, deltas, regressions } -- security → { findings_by_severity, patches_applied } -- -- `sources`, `artifacts`, `next_actions` are arrays of small objects. CREATE TABLE mission_phase_summaries ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), mission_id UUID NOT NULL REFERENCES missions(id) ON DELETE CASCADE, phase_id UUID NOT NULL REFERENCES mission_phases(id) ON DELETE CASCADE, kind TEXT NOT NULL, -- research | coding | benchmark | security_scan model TEXT NOT NULL, -- e.g. "claude-opus-4-8" narrative TEXT NOT NULL, metrics JSONB NOT NULL DEFAULT '{}'::jsonb, sources JSONB NOT NULL DEFAULT '[]'::jsonb, artifacts JSONB NOT NULL DEFAULT '[]'::jsonb, tooling JSONB NOT NULL DEFAULT '[]'::jsonb, next_actions JSONB NOT NULL DEFAULT '[]'::jsonb, generated_at TIMESTAMPTZ NOT NULL DEFAULT now(), error TEXT ); CREATE UNIQUE INDEX mission_phase_summaries_phase_id_uidx ON mission_phase_summaries(phase_id); CREATE INDEX mission_phase_summaries_mission_id_idx ON mission_phase_summaries(mission_id);