Expand description
Re-point six agent-child tables’ agent_id foreign key from
db_agent_definitions(id) to db_agents(id).
Agent-concept consolidation, Phase 3c
(SPEC_AGENT_ARCHITECTURE_2026_05_27.md). db_agent_content,
db_agent_skills, db_agent_history, db_agent_identity_links,
db_agent_skills_ref, and db_agent_mcp_ref all carry an agent_id
that has, until now, only ever been a db_agent_definitions id — so a
template-launched agent (a db_agents row with no definition row of its
own) could not hold any of these directly. That FK is the reason
listrecentsessions (PR 2, #3080) had to fall back to the launch’s
TEMPLATE for identity-link lookups instead of the agent’s own row.
Every existing db_agent_definitions row already has a db_agents
mirror at the SAME id (the dual-write PR 1 established and PR 2 kept
current, backstopped by the gap-repair this migration also runs), so
re-pointing the FK does not orphan a single existing row: every
agent_id value already in these tables satisfies the new target.
What it unlocks is new rows keyed by a launch id that has no
db_agent_definitions counterpart at all.
SQLite has no ALTER TABLE ... DROP CONSTRAINT / redefine-FK — changing
a foreign key’s target means rebuilding the table: rename, recreate with
the new FK, copy, drop the renamed original, recreate any secondary
indexes. Wrapped in one transaction per table with foreign_keys=OFF
for the swap (SQLite defers FK enforcement of the NEW schema to
PRAGMA foreign_key_check, which this migration runs before committing
rather than trusting each swap silently).
Tolerates a table whose FK already targets db_agents (a fresh install:
run_object_schema creates the six tables with the new FK directly, so
this migration has nothing to do there) and a store where a table is
missing entirely (Phase 3c-or-later: nothing to repoint). Idempotent.
Structs§
- M0028
Agent Child Tables Repoint Fk - Table
Spec 🔒 - One table this migration may need to rebuild.
Constants§
- TABLES 🔒
Functions§
- already_
targets_ 🔒db_ agents - True if
table’sagent_idFK already targetsdb_agents— either it was rebuilt by an earlier run of this migration, or it’s a fresh install whose base schema already declares the new target.Ok(true)for a missing table too: nothing to repoint is the same as already done. - frozen_
repair_ 🔒def_ gaps - Frozen copy of
agents_consolidate::repair_def_gapsas of v30 (codex P2 on #3088): a migration must produce the same rows on every machine it ever runs on, so it cannot call a live helper whose behavior a later release may change (migrations/mod.rs’s “migrations freeze copies of live logic” doc) — doubly so here, since the Phase 4 plan (SPEC_AGENT_ARCHITECTURE_2026_05_27.md) schedulesagents_consolidate.rsitself for removal, which would strand a live call the moment that PR lands. Finds everydb_agent_definitionsrow with no matchingdb_agentsid (written between the Phase 3a marker and Phase 3b dual-write landing) and projects one,INSERT OR IGNOREso it is safe to call every time this migration runs. Returns the number inserted.Ok(0)ifdb_agent_definitionsdoesn’t exist at all — dropped entirely as of v32 (OBJECT_SCHEMA_VERSION’s v32 doc comment); nothing to repair a gap in when there’s no source table left to have one. - rebuild_
table 🔒 - Rebuild one table so its
agent_idFK targetsdb_agentsinstead ofdb_agent_definitions. Rows whoseagent_idhas nodb_agentsrow at all are dropped (logged) rather than left to violate the new FK — the gap-repair pass immediately before this loop is what makes that count zero in the overwhelmingly common case. - repoint 🔒