Skip to main content

Module m0028_agent_child_tables_repoint_fk

Module m0028_agent_child_tables_repoint_fk 

Source
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§

M0028AgentChildTablesRepointFk
TableSpec 🔒
One table this migration may need to rebuild.

Constants§

TABLES 🔒

Functions§

already_targets_db_agents 🔒
True if table’s agent_id FK already targets db_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_gaps as 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) schedules agents_consolidate.rs itself for removal, which would strand a live call the moment that PR lands. Finds every db_agent_definitions row with no matching db_agents id (written between the Phase 3a marker and Phase 3b dual-write landing) and projects one, INSERT OR IGNORE so it is safe to call every time this migration runs. Returns the number inserted. Ok(0) if db_agent_definitions doesn’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_id FK targets db_agents instead of db_agent_definitions. Rows whose agent_id has no db_agents row 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 🔒