Ships the lineage layer that ties agents back to their team template
and wires the MCP skills server to actually merge template default
skills with per-agent overrides.
Migration 0050 adds `agent_template_link` (agent_id PK, template_id,
template_version, role_slot, seeded_at, created_at + indexes for
template/role lookups). Populated at agent-materialization time by
Slice 4's mission-launch orchestrator; read here by the skills MCP
server and by future level-up (Slice 8.5).
New Rust surface:
- cm_db::repo::agent_template_link (upsert / get / mark_seeded /
agents_for_template — the last is what level-up's "prompt upgrade
on template N+1" query needs)
- cm_api::brain_seed::ingest(claw_id, seed_md, identity_prompt)
opens cm_brain::ClawBrain on spawn_blocking, sets system_prompt
on first touch, writes seed as agent_md, commits. Idempotent —
skips when agent_md already populated.
- cm_api::mcp_skills::mcp_skills tools/call now resolves the caller
agent's template + role via agent_template_link and merges
template default skills with per-agent overrides (was overrides-
only in Slice 3.5b).
- cm_api::team_template_loader now binds template_role_skills after
upserting each template — looks up each declared skill by name,
attaches with pin_in_context=true for foundation skills and the
first two role skills. Missing skills log + skip.
- Boot ordering: skills load BEFORE team templates so the binding
lookup resolves.
Follow-up (Slice 4): mission-launch orchestrator calls brain_seed::ingest
+ agent_template_link::upsert when minting a team from a template.
Until that lands, the link is populated only by manual writes; the
MCP merge is silent-no-op for agents without a link (falls through
to overrides-only), which matches the pre-3.5d behavior.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
34 lines
1.6 KiB
SQL
34 lines
1.6 KiB
SQL
-- Slice 3.5d — agent → team-template lineage.
|
|
--
|
|
-- When a team is minted from a template we record which template +
|
|
-- version + role_slot produced each agent. Level-up (Slice 8.5) reads
|
|
-- this to:
|
|
-- - diff the agent's brain against the seeded brain_seed
|
|
-- - route "add skill to my team's template" proposals to the right
|
|
-- template row + version
|
|
-- - offer template-upgrade prompts when the template ships a new
|
|
-- version and the agent is still on an older one
|
|
--
|
|
-- Also: adds a `first_seeded_at` timestamp on agents so the brain-seed
|
|
-- ingestion is idempotent — we skip re-seeding an agent whose brain
|
|
-- was already populated from a template.
|
|
|
|
CREATE TABLE agent_template_link (
|
|
agent_id UUID PRIMARY KEY REFERENCES agents(id) ON DELETE CASCADE,
|
|
template_id UUID NOT NULL REFERENCES team_templates(id) ON DELETE CASCADE,
|
|
template_version INT NOT NULL,
|
|
role_slot TEXT NOT NULL,
|
|
-- When we ingested brain_seed. NULL means the link was recorded
|
|
-- but seeding hasn't run yet (rare — recovery / retry path).
|
|
seeded_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
-- Ensures we can query "all agents on template X, version Y"
|
|
-- without a table scan when the level-up proposer runs.
|
|
FOREIGN KEY (template_id, role_slot)
|
|
REFERENCES template_roles(template_id, slot)
|
|
);
|
|
CREATE INDEX agent_template_link_template_idx
|
|
ON agent_template_link (template_id, template_version);
|
|
CREATE INDEX agent_template_link_role_idx
|
|
ON agent_template_link (template_id, role_slot);
|