Team templates are the canonical rosters + tool bundles that mint
concrete teams for a mission. Every builtin ships as a TOML recipe
under templates/teams/*.toml, loaded into the DB at server boot.
Migration 0048 adds:
- team_templates (id, key, name, stack, default_topology,
risk_profile, mcp_bundles, version, source,
workspace_id)
- template_roles (m2m: template_id + slot; system_prompt,
skills[], brain_seed)
- teams gets template_id + template_version for level-up lineage
Ships 6 builtins:
- rust_sdlc — planner/coder/tester/reviewer/committer for Rust
- backend — api_designer/db_engineer/coder/tester/committer
(Postgres, DuckDB, graph DBs, wire protocols)
- frontend — designer/coder/tester/committer (React + Tailwind + ShadCN)
- mobile — designer/coder/tester/committer (Expo, RN, iOS, Android)
- gpu — arch_analyst/kernel_author/bench_engineer/coder/committer
(CUDA, Metal, ROCm from Rust)
- threejs — scene_designer/coder/shader_author/perf_engineer/
committer (three.js, WebGL, WebGPU)
Each role has a versioned system_prompt + skill list + brain_seed
markdown. Skills column is a name array today; Slice 3.5a promotes it
to a typed m2m join with the real skills catalog.
Server boot:
- team_template_loader::load_builtins reads TOML from
/etc/clawmates/templates/teams (container) or templates/teams (dev),
upserts idempotently. Deterministic uuid per template key (sha256
of a fixed namespace + key) so ids are stable across boots.
- Dockerfile copies templates/ to /etc/clawmates/templates.
Read API:
- GET /api/team-templates — list all
- GET /api/team-templates/{id} — detail with roles
Wizard:
- Step 3 rewired from a raw team_id text field to a template picker
with "LLM auto-provision" as the default option + one card per
builtin, showing stack, topology, risk profile, and description.
- Mission create now passes team_template_id (not team_id) so phase
execution knows which template to mint from.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
75 lines
3.3 KiB
SQL
75 lines
3.3 KiB
SQL
-- 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;
|