-- Research topics: user-scoped inquiry containers that group a set of agents -- around a shared question and drive them toward a named outcome (spec, -- prod_plan, roadmap, or paper). The status field is a small state machine -- driven by the orchestrator + a manual publish gate (approvals; see 0032). -- -- standby — created, agents assigned, not started -- processing — running; each iteration writes to topology_runs -- (with research_topic_id back-ref) -- reviewing — orchestrator flipped it here on last run_completed; -- a human approver still has to click Publish -- publishing — approval landed; artifact assembly + release in flight -- published — terminal -- -- A topic OWNS runs (topology_runs.research_topic_id). Runs carry all the -- durable execution state — the topic row is just the container + status. CREATE TABLE research_topics ( id UUID PRIMARY KEY, workspace_id UUID NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE, title TEXT NOT NULL, -- LLM-refined description from the wizard: structured markdown with the -- topic prompt + refined framing + key questions + success criteria. description TEXT NOT NULL, outcome_kind TEXT NOT NULL CHECK (outcome_kind IN ('spec', 'prod_plan', 'roadmap', 'paper')), status TEXT NOT NULL DEFAULT 'standby' CHECK (status IN ('standby', 'processing', 'reviewing', 'publishing', 'published')), created_by UUID NOT NULL REFERENCES users (id) ON DELETE RESTRICT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), -- Set on the reviewing→publishing transition (after the publish approval -- lands). Used by list queries that surface recent publishes. published_at TIMESTAMPTZ ); CREATE INDEX research_topics_workspace_idx ON research_topics (workspace_id, updated_at DESC); -- Speeds up the "topics in each status" sidebar bucket count. CREATE INDEX research_topics_status_idx ON research_topics (workspace_id, status); -- Assigned agents (many-to-many). role_slot is a free-form label the wizard -- captures ("lead", "critic", "writer") so the canvas can group avatars -- when the topic has multiple agents playing different parts. CREATE TABLE research_topic_agents ( topic_id UUID NOT NULL REFERENCES research_topics (id) ON DELETE CASCADE, agent_id UUID NOT NULL REFERENCES agents (id) ON DELETE CASCADE, role_slot TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (topic_id, agent_id) ); CREATE INDEX research_topic_agents_agent_idx ON research_topic_agents (agent_id); -- Back-ref from durable runs to the topic they belong to. Nullable — runs -- outside a research topic (chat, ad-hoc topology exec) leave this NULL and -- the existing indexes keep serving them. ALTER TABLE topology_runs ADD COLUMN research_topic_id UUID REFERENCES research_topics (id) ON DELETE SET NULL; CREATE INDEX topology_runs_research_topic_idx ON topology_runs (research_topic_id, created_at DESC) WHERE research_topic_id IS NOT NULL;