Skip to main content

Module migrations

Module migrations 

Source
Expand description

Data migration framework.

Migrations are versioned steps that run once, either via agentmux-srv migrate or in-process at startup via run_pending_migrations (called unconditionally; fast-paths to Ok(0) when already current). The in-process path runs before any store is opened for normal operation so that id_store always binds to a fully-backfilled shared store.

Adding a migration: implement Migration, add it to REGISTRY, add a file under this module. The ID must be unique and lexicographically ordered (use the NNNN_slug convention). Retiring old migrations: remove from REGISTRY once the minimum supported upgrade path passes the migration’s origin version — the db_migrations row stays as a permanent record.

§No private marker files

db_migrations (plus a Migration::verify post-condition) is the sole source of truth for “has this run” — SPEC_MIGRATION_SYSTEM_HARDENING_2026_08_03 Phase 2. A new migration must not introduce its own flag file, and no migration may treat the mere existence of a marker as proof of completion: that is the shape that left 0007’s target table empty while its flag said “done” (§1.2, F1). The three legacy markers that remain are evidence only — 0007’s and 0002’s helpers decide from the data (consolidate_looks_incomplete, block_zones_look_incomplete) and are content-idempotent, 0003’s helper ignores its marker and re-asserts its invariant every run — and m0000_bootstrap consults them only together with those content checks when stamping a pre-framework install.

§Migrations freeze copies of live logic on purpose

Some migrations carry verbatim copies of helpers that also exist in live code: m0017_ambient_login_grandfather mirrors ~35 lines of backend/blockcontroller/core.rs; m0020_agent_color_backfill and m0021_backfill_agent_bundles mirror 25–30 lines each of backend/storage/mcp_servers.rs and def_registry_mirror.rs. That is deliberate, not accidental duplication. A migration must produce the same rows on every machine it ever runs on, so it cannot call a live helper whose behaviour a later release may change; the copy pins the logic as it was at the migration’s origin version. Do not “deduplicate” a migration against live code. When you copy logic into a new migration, say so next to the copy — // frozen copy of <path>::<fn> as of <version> — so the next reader can tell a freeze from a drift.

Re-exports§

pub use runner::count_pending_migrations;
pub use runner::doctor_report_for_instance;
pub use runner::run_migrate_command;
pub use runner::run_pending_migrations;
pub use runner::try_count_pending_migrations;
pub use runner::PendingCountError;

Modules§

m0000_bootstrap 🔒
Bootstrap: stamp all pre-framework migrations as applied for existing users.
m0001_legacy_data_dir 🔒
m0002_block_zones_v1 🔒
m0003_template_sessions_v1 🔒
m0004_registry_from_sqlite 🔒
m0005_registry_source_bases 🔒
m0006_definitions_global 🔒
m0007_agents_consolidate 🔒
m0008_default_bundle 🔒
Seed Default OAuth identity bundle from ambient credentials — historical.
m0009_transcript_backfill 🔒
m0010_session_ids 🔒
m0011_shared_store_backfill 🔒
m0012_dedup_identity_accounts 🔒
Deduplicate identity accounts that share the same (provider, credential).
m0013_agent_direct_bindings 🔒
Backfill direct agent↔account links from bundle bindings — historical.
m0014_agent_direct_bindings_rerun 🔒
Re-run the direct agent↔account link backfill to catch instances launched in the gap between m0013’s original run and the launch flow write-through landing (PR B1, #1950) — historical.
m0015_seed_starter_skills 🔒
Seed the global Skills catalog (db_skills, per-channel) with a curated starter set on fresh install.
m0016_seed_starter_mcp_servers 🔒
Seed the global MCP Servers catalog (db_mcp_servers, per-channel) with a curated, credential-free starter set on fresh install.
m0017_ambient_login_grandfather 🔒
Grandfather the layer-3 use_ambient_login opt-in for pre-existing agents (spec §2.4 of SPEC_ACCOUNT_DELETE_DEAUTH_LAYERS_2_4_2026_07_14.md).
m0018_ambient_login_registry 🔒
Grandfather use_ambient_login on the GLOBAL cross-channel definition registry (~/.agentmux/shared/agents/definitions/) — the sibling of m0017_ambient_login_grandfather, which handles the per-channel SQLite projections.
m0019_repair_malformed_secret_ref 🔒
Repair db_accounts.secret_ref rows whose JSON was corrupted by an out-of-band edit of the shared store — found live: a raw Windows path pasted into the JSON string with its backslashes never escaped ({"backend":"oauth_config_dir","dir":"C:\Users\..."}, valid JSON needs \\ per separator). Not reproducible from any write path in this codebase (Store::identity_upsert always serde_json::to_strings correctly) — see ANALYSIS_ARMORY_STASH_CREDENTIAL_VISIBILITY_GAP_2026_08_04 (never committed to this repo) §7 for the full incident.
m0020_agent_color_backfill 🔒
Backfill a display color (agent_content ui:color) for every existing agent definition that doesn’t have one — the “generate a random color for all the existing agents” one-time script from docs/specs/SPEC_AGENT_COLOR_2026_08_08.md.
m0021_backfill_agent_bundles 🔒
Backfill a dedicated ABF bundle for every existing agent definition that doesn’t have one — the data-migration half of docs/specs/ARCHITECTURE_MANDATORY_ABF_RETHINK_2026_08_14.md §3/§7: “every agent must have an ABF,” and, at the time, that ABF carried its own provider/model (readonly once set by a bundle-level guard). Since SPEC_AGENT_BUNDLE_FORMAT_V0_3_2026_10_05.md §3 the bundle carries no harness: the agent owns its provider, locked by app_api::check_provider_unchanged, and m0035 reconciles agents with the bundles this migration wrote.
m0022_identity_store_links_backfill 🔒
Backfill db_agent_identity_links, plus a db_accounts fallback mirror (reagentx P0 review, added after this migration’s first version — see identity::resolver::inject::resolve_account’s own doc comment for why the mirror is needed even though db_accounts itself stays on id_store as the authoritative store), from every reachable store into the new, permanently-global identity store — see docs/specs/SPEC_IDENTITY_STORE_SPLIT_2026_08_17.md.
m0023_native_memory_versions_backfill 🔒
Backfill db_agent_native_memory_versions with one source: "agent_inferred" version per existing db_agent_native_memory row — reagent P1 (re-review of PR #2674): the spec this migration completes (docs/specs/SPEC_MEMORY_VERSION_CONTROL_AND_ARMORY_AUDIT_2026_08_19.md §9 Rollout) explicitly calls for this backfill so history views aren’t empty for pre-existing memory on upgrade. Without it, an existing user’s first post-upgrade overwrite of a memory file records only the NEW content as version 1 — the prior live content (everything that file held before this feature shipped) is permanently unrecoverable via MemoryRevert/MemoryDiff.
m0024_native_memory_backfill_from_fs 🔒
Finish the job m0023 was meant to do, and repair the label it left behind — SPEC_MEMORY_VERSION_CONTROL_AND_ARMORY_AUDIT_2026_08_19.md §9 (rollout backfill) and §4.5 (drift detection).
m0025_agents_launch_state_backfill 🔒
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.
m0026_registry_agent_id_rekey 🔒
Re-key the named-agent registry from launch ids to agent ids.
m0027_agents_workspace_backfill 🔒
Backfill db_agents.working_directory with the workspace each agent actually ran in, taken from its latest legacy db_agent_instances launch.
m0028_agent_child_tables_repoint_fk 🔒
Re-point six agent-child tables’ agent_id foreign key from db_agent_definitions(id) to db_agents(id).
m0029_drop_legacy_agent_tables 🔒
Drop db_agent_definitions and db_agent_instances — the two legacy tables the agent-concept consolidation retires.
m0030_backfill_bundle_component_refs 🔒
Backfill db_bundle_skills_ref from the inline db_bundles.skills JSON column.
m0031_carry_skills_and_mcp_servers_to_identity_store 🔒
Carry each channel’s db_skills / db_mcp_servers rows into the permanently-global identity store, which became authoritative for them in Phase 2a (IDENTITY_STORE_SCHEMA_VERSION v6/v7 — see SPEC_DURABLE_BINDINGS_2026_09_10.md §7 Phase 2).
m0032_drop_catalog_fk_from_ref_tables 🔒
Drop the skill_id/mcp_id foreign key from all four skill/MCP ref tables (db_agent_skills_ref, db_agent_mcp_ref, db_bundle_skills_ref, db_bundle_mcp_ref), leaving every other constraint verbatim (the agent-level pair’s agent_id → db_agents FK, every PRIMARY KEY, all column types).
m0033_narrow_skill_global_uniqueness_index 🔒
Narrow the global skill uniqueness index from (name, skill_type) to name alone, matching the invariant skill_upsert_unique_global’s own dup-check has always enforced — with a defensive dedup pass for any existing same-name/different-type pair the OLD, wider index let through.
m0034_identity_history_backfill 🔒
One-time sweep for identity conversation history stranded before ensure_history_link (SPEC_AGENT_IDENTITY_HISTORY_PERSISTENCE_PROTOCOL_2026_08_16.md, shipped in 0007c6b64051e8 / PR #2605) existed to keep it linked into the always-global shared/identities/<id>/<provider>/<subdir>/ tree.
m0035_agent_owns_its_provider 🔒
Give every agent the provider it actually runs with, before the bundle stops deciding it (docs/specs/SPEC_AGENT_BUNDLE_FORMAT_V0_3_2026_10_05.md §3.3).
m0036_drop_bundle_mcp 🔒
Bundles stop carrying MCP servers: they belong to Connectors (docs/specs/SPEC_BUNDLE_CONTENTS_MEMORY_NOT_MCP_2026_10_07.md §3.1, D3).
m0037_retire_old_pane_names 🔒
Rewrites the retired pane names in stored data, once, so the frontend and srv can drop the shims that translated them on every read. The Armory (and the Trust Center before it) was split into Connectors and Memory, the Knowledge pane was renamed Memory, and Remotes became a section of Connectors (SPEC_RETIRE_ARMORY_CONNECTORS_AND_KNOWLEDGE_PANES_2026_10_05.md Phase 3, SPEC_RENAME_KNOWLEDGE_TO_MEMORY_2026_10_06.md, SPEC_REMOTES_INTO_CONNECTORS_2026_10_08.md).
runner 🔒
Migration runner — invoked by agentmux-srv migrate (a CLI subcommand, and the now-dead agentmux-launcher::srv_spawner::run_migrate subprocess path) and, separately, in-process at every srv boot via run_pending_migrations.

Structs§

MigrationContext
Context passed to every migration’s up() call.
MigrationError

Enums§

MigrationScope
VerifyOutcome
Result of an applied migration’s post-condition check (agentmux-srv migrate --verify, SPEC_MIGRATION_SYSTEM_HARDENING_2026_08_03 Phase 1). db_migrations records only that up() returned Ok — never that it wrote what it was meant to. A migration that can state its own effect as a cheap query implements Migration::verify; the rest report NotVerifiable and the doctor pass says so rather than guessing.

Statics§

REGISTRY 🔒

Traits§

Migration