-- Slice 3 — team templates. -- -- Team templates are the canonical rosters + tool bundles used to -- materialize concrete `teams` rows. They ship as TOML recipes on -- disk (see templates/teams/*.toml) and are upserted into these -- tables at server boot. -- -- Later slices layer more on: -- - Slice 3.5a: `skills` + `template_role_skills` (m2m join) -- - Slice 3.5d: `agent_template_link` for level-up lineage -- -- Discriminators kept TEXT so new templates ship as PRs without -- schema migrations. CREATE TABLE team_templates ( -- Deterministic id per template kind so seeded rows are stable -- across boots. We use uuid5 of a namespace + the template `key` -- computed in the loader; recording the key here lets us look -- them up by name from the API. id UUID PRIMARY KEY, -- Slug used in URLs + TOML filenames (e.g. "rust_sdlc"). key TEXT NOT NULL UNIQUE, name TEXT NOT NULL, stack TEXT[] NOT NULL DEFAULT '{}', default_topology TEXT NOT NULL, risk_profile TEXT NOT NULL, mcp_bundles TEXT[] NOT NULL DEFAULT '{}', version INT NOT NULL DEFAULT 1, description TEXT, -- Free-form for template-specific knobs (default cargo features, -- lint policy, etc.). Merged into missions.config when a mission -- is materialized from this template. config JSONB NOT NULL DEFAULT '{}'::jsonb, -- 'builtin' rows are re-upserted from disk at every boot. Rows -- with source='user' are workspace-authored and never overwritten. source TEXT NOT NULL DEFAULT 'builtin', workspace_id UUID, -- NULL for builtins; set for user rows created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX team_templates_workspace_idx ON team_templates (workspace_id) WHERE workspace_id IS NOT NULL; CREATE INDEX team_templates_source_idx ON team_templates (source); CREATE TABLE template_roles ( template_id UUID NOT NULL REFERENCES team_templates(id) ON DELETE CASCADE, -- role slot within the template (e.g. "planner", "coder"). Unique -- per template — a template can't have two "coder" slots. slot TEXT NOT NULL, order_idx INT NOT NULL, -- The system prompt for this role. Loaded from disk for builtins; -- editable for user templates. system_prompt TEXT NOT NULL, -- Skills attached by default when the template mints an agent for -- this slot. Stored as a name array; Slice 3.5a introduces the -- typed join table + real skills catalog. skills TEXT[] NOT NULL DEFAULT '{}', -- Brain seed content ingested into a fresh agent's .brain on -- creation (Slice 3.5d actually wires the ingestion; this column -- stores the seed markdown from the template). brain_seed TEXT, PRIMARY KEY (template_id, slot) ); CREATE INDEX template_roles_order_idx ON template_roles (template_id, order_idx); -- Track which template a team was minted from, so level-up (Slice 8.5) -- can diff learned knowledge back into template PR proposals. ALTER TABLE teams ADD COLUMN template_id UUID REFERENCES team_templates(id) ON DELETE SET NULL, ADD COLUMN template_version INT; CREATE INDEX teams_template_idx ON teams (template_id, template_version) WHERE template_id IS NOT NULL;