Expand description
Backfill db_agents’ latest-launch state (schema v29:
session_id, status, started_at, ended_at, and last_block_id
where still empty) from the legacy db_agent_instances rows.
Agent-concept consolidation, Phase 3b
(SPEC_AGENT_ARCHITECTURE_2026_05_27.md): these four columns are what
kept the legacy table alive — the recent-sessions picker, the pane
close/reopen continuity write-back and the status-filtered instance
list all read them from db_agent_instances. Once every consolidated
row carries its own launch state, those reads can flip and the table
can go.
Rule: for each projection key (the db_agents row an instance chain
maps to — the chain head’s own id for a template launch, the user-clone
definition’s id for a launch of a user agent) take the most recently
created instance in the chain and copy its launch state, but only into
a row whose launch state is still entirely default. That makes the
migration idempotent and means it never overwrites state the dual-write
has written since v29 shipped. Channel-scoped: each channel’s
objects.db has its own rows.
Frozen copy of dual_write::agents_projection_key_for_inst’s rule
(as of v29) — deliberately not a call into it, per this module’s “freeze
copies of live logic” doc: dual_write is deleted when the legacy
table is dropped, and this migration must keep producing the same rows
on every machine it ever runs on.
Tolerates a store that has already dropped db_agent_instances
(Phase 3c): nothing to backfill, Ok.
Structs§
- Backfill
Stats 🔒 - What the backfill did.
projectedcounts template-launch chains whose consolidated row was missing and had to be created first;updatedcounts rows that received launch state. - Legacy
Instance 🔒 - The legacy instance columns the backfill reads.
- M0025
Agents Launch State Backfill
Functions§
- backfill_
launch_ 🔒state - The backfill proper, on an open connection.
- frozen_
repair_ 🔒def_ gaps - Frozen copy of
agents_consolidate::repair_def_gapsas it existed when this migration was written (deleted from live code by the definition flip — nothing writesdb_agent_definitionswithout also writingdb_agentsany more, so the gap this backfills can no longer open going forward; it can still exist on an install upgrading THROUGH this exact migration from a pre-flip version, which is what this migration must keep repairing on every machine it ever runs on). Backfill anydb_agent_definitionsrow missing fromdb_agents.INSERT OR IGNORE, so idempotent. Returns the number of rows inserted. - project_
template_ 🔒launch_ row - Create the consolidated row for a template-launch chain whose head has
no
db_agentsrow yet — the “Phase 3a stamped, db_agents partially populated” upgrade shape (codex P1 on #3075). Without this the UPDATE below affects zero rows, the migration is still recorded applied, and the chain’s session/status is unreachable once readers flip. Frozen copy of the consolidate pass-3 / dual-write head-INSERT column mapping as of v29,INSERT OR IGNOREso it can never clobber a row that appeared in between.Ok(false)when the definition itself is gone — nothing to project against (the legacy FK cascade would have removed such an instance; if it survived it is an orphan). - projection_
key 🔒 - Frozen copy of the v29 projection rule: walk
parent_instance_idto the chain root; if the root’s definition is a user-clone (is_seeded = 0) the key is that definition’s id (the launch was folded into the def’s row), otherwise it is the root instance’s own id (a template launch is its own row). A missing definition counts as seeded, matching theCOALESCE(d.is_seeded, 1)in the live helper. A chain whose parent pointer no longer resolves is rooted at the last instance that does.