Files
Agent-System/deploy/control-center/goose/00001_init.sql
T

203 lines
8.9 KiB
SQL

-- +goose Up
-- Control Center core schema: plans, tasks, 8-stage pipeline, agent collaboration,
-- document/artifact vector store, audit findings, snapshots.
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE cc_plans (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
slug text NOT NULL UNIQUE,
title text NOT NULL,
horizon text NOT NULL DEFAULT 'short' CHECK (horizon IN ('short','long','backlog')),
status text NOT NULL DEFAULT 'planned' CHECK (status IN ('planned','in_progress','done','cancelled')),
summary_md text NOT NULL DEFAULT '',
doc_path text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE cc_agents (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
name text NOT NULL UNIQUE,
kind text NOT NULL DEFAULT 'generic',
token_hash text NOT NULL UNIQUE,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE cc_tasks (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
slug text NOT NULL UNIQUE,
plan_id uuid REFERENCES cc_plans(id) ON DELETE SET NULL,
title text NOT NULL,
kind text NOT NULL DEFAULT 'task' CHECK (kind IN ('task','proposal')),
status text NOT NULL DEFAULT 'planned'
CHECK (status IN ('planned','in_progress','blocked_pending_decision','done','cancelled')),
stage text NOT NULL DEFAULT 'proposal'
CHECK (stage IN ('proposal','analysis','design','review','implementation','testing','evaluation','confirmation')),
stage_state text NOT NULL DEFAULT 'idle'
CHECK (stage_state IN ('idle','assigned','in_progress','awaiting_review','changes_requested','approved')),
testing_required boolean NOT NULL DEFAULT true,
priority int NOT NULL DEFAULT 0,
owner text NOT NULL DEFAULT '',
agent_kind text NOT NULL DEFAULT '',
mutex text NOT NULL DEFAULT '',
branch text NOT NULL DEFAULT '',
worktree text NOT NULL DEFAULT '',
instruction_md text NOT NULL DEFAULT '',
doc_path text NOT NULL DEFAULT '',
assigned_agent text NOT NULL DEFAULT '',
lease_expires_at timestamptz,
heartbeat_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX cc_tasks_status_idx ON cc_tasks (status);
CREATE INDEX cc_tasks_stage_idx ON cc_tasks (stage, stage_state);
CREATE INDEX cc_tasks_plan_idx ON cc_tasks (plan_id);
CREATE TABLE cc_task_events (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
task_id uuid NOT NULL REFERENCES cc_tasks(id) ON DELETE CASCADE,
agent text NOT NULL DEFAULT '',
phase text NOT NULL CHECK (phase IN ('start','plan','progress','blocked','report','done','advance-request','decision','system')),
message text NOT NULL DEFAULT '',
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
ts timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX cc_task_events_task_idx ON cc_task_events (task_id, id);
CREATE TABLE cc_task_reports (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
task_id uuid NOT NULL REFERENCES cc_tasks(id) ON DELETE CASCADE,
agent text NOT NULL DEFAULT '',
kind text NOT NULL DEFAULT 'result' CHECK (kind IN ('result','test-report','handoff')),
content_md text NOT NULL,
links jsonb NOT NULL DEFAULT '[]'::jsonb,
ts timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX cc_task_reports_task_idx ON cc_task_reports (task_id, id);
CREATE TABLE cc_stage_artifacts (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
task_id uuid NOT NULL REFERENCES cc_tasks(id) ON DELETE CASCADE,
stage text NOT NULL,
kind text NOT NULL DEFAULT 'note',
title text NOT NULL DEFAULT '',
content_md text NOT NULL,
source_type text NOT NULL DEFAULT 'agent' CHECK (source_type IN ('agent','human','external')),
source_ref text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX cc_stage_artifacts_task_idx ON cc_stage_artifacts (task_id, stage);
CREATE TABLE cc_stage_transitions (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
task_id uuid NOT NULL REFERENCES cc_tasks(id) ON DELETE CASCADE,
from_stage text NOT NULL,
to_stage text NOT NULL,
actor text NOT NULL,
approved_by text NOT NULL,
note text NOT NULL DEFAULT '',
ts timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX cc_stage_transitions_task_idx ON cc_stage_transitions (task_id, id);
CREATE TABLE cc_stage_settings (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
scope text NOT NULL DEFAULT 'global' CHECK (scope IN ('global','task')),
task_id uuid REFERENCES cc_tasks(id) ON DELETE CASCADE,
stage text NOT NULL,
model text NOT NULL DEFAULT '',
executor text NOT NULL DEFAULT 'agent' CHECK (executor IN ('agent','human','external')),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (scope, task_id, stage)
);
CREATE TABLE cc_decisions (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
task_id uuid NOT NULL REFERENCES cc_tasks(id) ON DELETE CASCADE,
stage text NOT NULL,
question text NOT NULL,
context_md text NOT NULL DEFAULT '',
suggestions jsonb NOT NULL DEFAULT '[]'::jsonb,
status text NOT NULL DEFAULT 'open' CHECK (status IN ('open','resolved')),
resolution text NOT NULL DEFAULT '',
decided_by text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT now(),
resolved_at timestamptz
);
CREATE INDEX cc_decisions_open_idx ON cc_decisions (status) WHERE status = 'open';
CREATE TABLE cc_documents (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
path text NOT NULL UNIQUE,
title text NOT NULL DEFAULT '',
taxonomy text NOT NULL DEFAULT '',
frontmatter jsonb NOT NULL DEFAULT '{}'::jsonb,
sha256 text NOT NULL,
synced_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE cc_doc_chunks (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
doc_id uuid REFERENCES cc_documents(id) ON DELETE CASCADE,
artifact_id uuid REFERENCES cc_stage_artifacts(id) ON DELETE CASCADE,
seq int NOT NULL,
heading text NOT NULL DEFAULT '',
content text NOT NULL,
chunk_hash text NOT NULL UNIQUE,
embedding vector(1024),
tsv tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STORED,
created_at timestamptz NOT NULL DEFAULT now(),
CHECK (doc_id IS NOT NULL OR artifact_id IS NOT NULL)
);
CREATE INDEX cc_doc_chunks_embedding_hnsw ON cc_doc_chunks USING hnsw (embedding vector_cosine_ops);
CREATE INDEX cc_doc_chunks_tsv_idx ON cc_doc_chunks USING gin (tsv);
CREATE TABLE cc_audit_runs (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
kind text NOT NULL DEFAULT 'daily',
status text NOT NULL DEFAULT 'running' CHECK (status IN ('running','completed','failed')),
summary text NOT NULL DEFAULT '',
error text NOT NULL DEFAULT '',
started_at timestamptz NOT NULL DEFAULT now(),
finished_at timestamptz
);
CREATE TABLE cc_audit_findings (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
run_id bigint NOT NULL REFERENCES cc_audit_runs(id) ON DELETE CASCADE,
severity text NOT NULL DEFAULT 'medium' CHECK (severity IN ('low','medium','high','critical')),
kind text NOT NULL DEFAULT 'gap' CHECK (kind IN ('bug','gap','unfinished','doc-drift')),
title text NOT NULL,
detail_md text NOT NULL DEFAULT '',
refs jsonb NOT NULL DEFAULT '[]'::jsonb,
status text NOT NULL DEFAULT 'open' CHECK (status IN ('open','converted','dismissed')),
task_id uuid REFERENCES cc_tasks(id) ON DELETE SET NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX cc_audit_findings_status_idx ON cc_audit_findings (status);
CREATE TABLE cc_snapshots (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
revision text NOT NULL,
payload jsonb NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
-- +goose Down
DROP TABLE IF EXISTS cc_snapshots;
DROP TABLE IF EXISTS cc_audit_findings;
DROP TABLE IF EXISTS cc_audit_runs;
DROP TABLE IF EXISTS cc_doc_chunks;
DROP TABLE IF EXISTS cc_documents;
DROP TABLE IF EXISTS cc_decisions;
DROP TABLE IF EXISTS cc_stage_settings;
DROP TABLE IF EXISTS cc_stage_transitions;
DROP TABLE IF EXISTS cc_stage_artifacts;
DROP TABLE IF EXISTS cc_task_reports;
DROP TABLE IF EXISTS cc_task_events;
DROP TABLE IF EXISTS cc_tasks;
DROP TABLE IF EXISTS cc_agents;
DROP TABLE IF EXISTS cc_plans;