Foundation slice for letting a coding loop bring its own team instead
of reusing the paired research topic's team. Turns out the teams
table already exists (0010_teams.sql) with full CRUD — this scales
back to the minimal missing bits:
Schema (0045_teams.sql)
- ALTER TABLE teams ADD risk_profile TEXT (NULL = template default)
- ALTER TABLE teams ADD mcp_bundles JSONB DEFAULT '[]'
- ALTER TABLE loops ADD team_id UUID REFERENCES teams ON DELETE SET NULL
- ALTER TABLE research_topics ADD team_id UUID REFERENCES teams
- Two partial indexes (team_id NOT NULL) for the future cascade queries
cm-db (dynamic sqlx::query so the existing get_team's compile-time
cache doesn't need regenerating):
- TeamRuntimeConfig struct
- get_team_runtime_config / set_team_runtime_config
- team_for_loop / team_for_research_topic (resolvers)
- set_team_for_loop / set_team_for_research_topic (binders)
cm-api
- GET /api/teams/{id} now surfaces risk_profile + mcp_bundles
- PATCH /api/teams/{id}/runtime-config sets them
Not touched (comes in follow-up slices):
- Wizard picker exposing 'reuse research team' vs 'fresh coding team'
- Runtime container spawn keyed on team_id
- Migration of existing paired coding loops onto their own team
47 lines
2.2 KiB
SQL
47 lines
2.2 KiB
SQL
-- Teams-for-loops foundation. The `teams` table already exists (see
|
|
-- 0010_teams.sql) — a workspace-scoped topology graph + node→claw
|
|
-- bindings via team_members. This migration adds only the fields
|
|
-- needed to make an existing team attachable to a loop or research
|
|
-- topic with its own runtime constitution.
|
|
--
|
|
-- Motivation: today the paired coding loop reuses the research topic's
|
|
-- ZeroClaw team container, which forces one risk_profile on both the
|
|
-- read-heavy research workload and the write-heavy coding workload.
|
|
-- Attaching a distinct team lets a loop bring its own risk_profile
|
|
-- (e.g. "coding_readwrite" allowing file_write + shell) without
|
|
-- weakening the research team's posture.
|
|
--
|
|
-- Backward compat: every new column is NULLABLE. NULL preserves the
|
|
-- legacy "inherit from wherever the runtime template says" behavior.
|
|
-- No existing row is invalidated; wizards + runtime opt into the new
|
|
-- fields in follow-up slices.
|
|
|
|
-- Per-team runtime posture. NULL falls back to the runtime template
|
|
-- default (currently `research_readonly` for research-spawned
|
|
-- containers). Named profiles resolve at daemon startup against
|
|
-- [risk_profiles.<name>] in the runtime config.
|
|
ALTER TABLE teams
|
|
ADD COLUMN IF NOT EXISTS risk_profile TEXT;
|
|
|
|
-- Extra MCP bundle aliases the team's agents load in addition to the
|
|
-- template defaults. Stored as JSONB array of strings so a team can
|
|
-- carry {"clawmates_door", "git_writer"} for a coding pair without
|
|
-- affecting other teams. Empty array = inherit template only.
|
|
ALTER TABLE teams
|
|
ADD COLUMN IF NOT EXISTS mcp_bundles JSONB NOT NULL DEFAULT '[]'::jsonb;
|
|
|
|
-- Wire loops and research_topics to an optional team_id. ON DELETE SET
|
|
-- NULL so deleting a team unbinds without destroying the loop/topic
|
|
-- (the runtime falls back to the template default).
|
|
ALTER TABLE loops
|
|
ADD COLUMN IF NOT EXISTS team_id UUID
|
|
REFERENCES teams(id) ON DELETE SET NULL;
|
|
CREATE INDEX IF NOT EXISTS loops_team_idx ON loops (team_id)
|
|
WHERE team_id IS NOT NULL;
|
|
|
|
ALTER TABLE research_topics
|
|
ADD COLUMN IF NOT EXISTS team_id UUID
|
|
REFERENCES teams(id) ON DELETE SET NULL;
|
|
CREATE INDEX IF NOT EXISTS research_topics_team_idx
|
|
ON research_topics (team_id) WHERE team_id IS NOT NULL;
|