Skip to main content

Module migrations

Module migrations 

Source
Expand description

SQL schema setup for Store, FileStore, and the saga log.

objects.db uses a flat schema: run_object_schema defines the final table set directly in one idempotent CREATE TABLE IF NOT EXISTS batch. It replaced an 11-step incremental migration chain (run_forge_v1 … run_forge_v11) — see docs/specs/SPEC_SCHEMA_FLATTENING_2026_05_19.md. The chain was pure historical accretion: per-version data dirs mean every new version is born with a fresh objects.db and ran the whole chain top-to-bottom anyway, so the intermediate states were never reachable in production.

filestore.db and sagas.db were already single-DDL stores; they keep their existing schema functions and gain only the user_version tripwire (check_schema_compat + stamp_version).

Constants§

DEAD_TABLE_DROPS 🔒
Tables retained by the old chain only for a downgrade path the flatten abandons. Dropped from any legacy DB by the adopt step; never created by the flat schema. db_workflow_* data was already copied into db_drone_* by the old v10 migration, so dropping loses nothing.
FILESTORE_SCHEMA_VERSION
user_version value stamped into filestore.db.
IDENTITY_STORE_SCHEMA_VERSION
user_version stamped into the new, permanently-global ~/.agentmux/shared/identity-store.db (distinct file from store.db — see run_identity_store_schema’s own doc comment for why). Independent counter from SHARED_STORE_SCHEMA_VERSION. v1 — initial: agent→account links, bundles, drone definitions, muxbus credentials, per-agent M2M credentials, native memory mirror, cron jobs. Everything run_shared_store_schema already held EXCEPT db_accounts — see docs/specs/SPEC_IDENTITY_STORE_SPLIT_2026_08_17.md §3.1. v2 — db_accounts, as a FALLBACK MIRROR only (reagentx P0 review on PR #2632): the link resolves via this store now, but the account row it points to could still only exist in the per-channel-isolatable id_store, which is empty on a fresh channel — the reported bug wasn’t actually fixed end to end without this. id_store remains the PRIMARY, authoritative, write path (so Armory’s disposable-test-account isolation is unchanged); this copy is consulted only when id_store doesn’t have the row. See identity::resolver::inject’s account resolution for the read-with-fallback + write-back-to-source-store logic this enables. v3 — db_agent_native_memory_versions, for schema parity with the v1 native memory mirror this store already carries. Same as that table, this store’s copy is not an actively-written duplicate (id_store/store.db remains the authoritative write path — see v2’s note above) — added here only so a future always-global read path (mirroring what v2 did for db_accounts) is not blocked on a missing table. See docs/specs/SPEC_MEMORY_VERSION_CONTROL_AND_ARMORY_AUDIT_2026_08_19.md. v4 — db_bundles.is_system, for schema parity with OBJECT_SCHEMA_VERSION v27 / SHARED_STORE_SCHEMA_VERSION v9 (same column, same reasoning as v3 above — this store’s db_bundles copy is not an actively- written duplicate either). Real ALTER TABLE ADD COLUMN added to run_identity_store_schema in the same change, so this counter MUST bump alongside it — an unbumped counter would leave an existing identity-store.db stamped at the old user_version forever, silently defeating check_schema_compat/stamp_version’s forward-compat lock for this one store (reagent P1, PR #2782). See docs/specs/SPEC_GLOBAL_MEMORY_SYSTEM_TIER_2026_08_24.md. v5: db_work_queue — the Muxqueue backlog (docs/reports/REPORT_UNIVERSAL_AGENT_WORK_QUEUE_2026_09_01.md). A NEW table, so no ALTER is involved, but the counter still bumps: an identity-store.db stamped v4 that a v5 binary opens must be recognized as older, not “already current” (same reagent P1 on PR #2782 reasoning recorded for v4 above).
LEGACY_INDEX_DROPS 🔒
Legacy index names that must be dropped after their table is renamed — ALTER TABLE … RENAME keeps indexes attached but under their old names, which would collide with the flat DDL’s CREATE INDEX. The flat DDL recreates each under the new name.
LEGACY_TABLE_RENAMES 🔒
Legacy objects.db table names retired by the de-forge rename, paired with their replacement. adopt_legacy_table_names renames any of these it finds — the single surviving piece of the old migration chain (it also subsumes the v11 db_memories rename).
OBJECT_SCHEMA_VERSION
user_version value stamped into objects.db after run_object_schema. The flat schema reset the counter to 1 (the pre-flatten chain never set user_version, so legacy files read 0). Bumped per additive migration: v1 — flat schema baseline v2 — db_agent_definitions.updated_at v3 — db_agent_definitions.user_hidden (Phase 2 hide templates, SPEC_AGENT_PICKER_TWO_TIER_2026_05_24.md Q2 Decision Y) v4 — db_agents consolidation table (Phase 3a: every definition/ instance write dual-writes here). Reads moved over piecemeal afterwards — the instance side in Phase 3b (#3080), every agent_def_* method in Phase 3d (#3092, v31) — and both legacy tables were dropped in v32. v5 — db_agents.last_block_id (Phase 3c; latest launch’s block, so the consolidated read can find the session snapshot without joining db_agent_instances) v6 — container_image / container_volumes / container_name on both db_agent_definitions and db_agents (Phase 0 of SPEC_CONTAINER_PANE_SUPPORT_2026_06_11.md; host agents default to ‘’ / ‘[]’ / ‘’) v7 — db_muxbus_credentials: global singleton for MuxBus cloud Cognito PKCE tokens (access, refresh, id) + expiry + user email v8 — db_memory_bundles.is_global: global-tier flag for Armory bundles injected into every agent’s CLAUDE.md at launch v9 — db_memory_bundles.sort_order: explicit ordering for the Armory global bundles (controls CLAUDE.md injection order). Existing rows default to 0; the Armory Global section assigns positions via reorder. v10 — db_skills, db_mcp_servers, db_agent_skills_ref, db_agent_mcp_ref: standalone MCP Server and Skill primitives with per-agent ref tables (v1 composable model, SPEC_V1_MCP_SKILLS_PRIMITIVES_2026_06_30.md). v11 — Phase 4a of SPEC_PRESET_TO_BUNDLE_REFACTOR_2026_07_02.md: rename db_identity_accounts -> db_accounts, db_memory_bundles -> db_bundles (SPEC_ARMORY_PHASE4_STORAGE_RENAME_COMPLETION_2026_07_12.md). v12 — use_ambient_login on both db_agent_definitions and db_agents: explicit per-agent opt-in to the CLI’s global (ambient) login when no oauth-class account resolves at spawn (layer 3 of SPEC_ACCOUNT_DELETE_DEAUTH_LAYERS_2_4_2026_07_14.md §2.3). Defaults to 0 (fail-by-default); the m0017 data migration grandfathers pre-existing linkless agents to 1. v13 — db_agent_credentials: per-agent M2M muxbus credential, mirroring db_muxbus_credentials’ presence in both schemas — id_store falls back to this (per-channel) schema on installs that haven’t yet applied 0011_shared_store_backfill, so cloud_subscriber’s calls must not assume the shared-schema copy (v4 there) is the one in use. v14 — db_agent_native_memory: durable mirror of each agent’s native memory files, keyed by (agent_id, filename). Same both-schemas duplication as db_agent_credentials, for the same id_store fallback reason. See docs/specs/SPEC_NATIVE_MEMORY_DURABLE_SYNC_2026_08_07.md. v15 — model_vendor_base_url on both db_agent_definitions and db_agents: redirects a harness (CLI) at a non-default model vendor backend (e.g. ANTHROPIC_BASE_URL for a claude-provider agent) — the data- model side of formalizing harness vs. model-vendor as distinct concepts. Defaults to ‘’ (use the harness’s default vendor). Only settable via agent.define, validated against the resolved provider’s ProviderConfig::base_url_env_var. v16 — db_bundles.instructions_by_provider: JSON object of {provider_id: content} instruction variants, additive to the existing flat instructions column (which keeps meaning “default”). ABF v0.2 storage half of provider-scoped instructions — see docs/specs/SPEC_ABF_V0_2_PROVIDER_AWARE_COMPONENTS_AND_NATIVE_MEMORY_2026_08_10.md §2.2. Defaults to ‘{}’ for existing rows; delivering a selected variant into a running agent is explicitly out of scope for this version (per that spec’s non-goals) — this column only makes the data storable/exportable/importable. v17 — auto_continue_enabled on both db_agent_definitions and db_agents: per-agent opt-in letting a Warden Supervisor watcher agent auto-continue this agent’s session on turn-end (subject to a server-side consecutive-nudge ceiling). Defaults to 0 (opt-in required — fail-by-default, same posture as use_ambient_login). See docs/analysis/ANALYSIS_WARDEN_AUTO_CONTROLLER_CONTINUATION_WATCHER_2026_08_12.md. v18 — db_agent_jekt_keys: per-agent HMAC-SHA256 signing key for host-tier jekt sender verification. One row per agent_id, minted on first use and injected into that agent’s own MCP server process env (AGENTMUX_JEKT_KEY) at spawn — never into any other agent’s env, so a signature can only be produced by the agent it claims to be from. See docs/specs/SPEC_JEKT_TRUST_LAYER_COMPLETION_2026_08_13.md §2.2. v19 — db_agent_definitions.memory_id: the agent’s own dedicated ABF bundle, set once at creation and never updated thereafter (agent_def_update’s SET clause deliberately omits it, same immutable-after-creation treatment as is_seeded/slug/parent_id). Distinct from db_agent_instances.memory_id (a specific launch’s bundle, can still diverge on purpose). Mirrored into db_agents as a SEPARATE default_memory_id column, not db_agents.memory_id — that column is instance-only by existing convention (see db_agents’ CREATE TABLE comment). Defaults to ‘’ for existing rows; the m0021 migration backfills every unbound definition to a freshly-provisioned bundle. See ARCHITECTURE_MANDATORY_ABF_RETHINK_2026_08_14.md §3.1. v20 — db_agent_lan_keys: per-agent Ed25519 keypair for LAN-tier jekt sender verification — mirrors v18, asymmetric instead of HMAC (LAN is multi-party: a receiving peer must verify without being able to forge, which a shared secret can’t provide). public_key is distributed to LAN peers on demand (not secret); private_key is injected into that one agent’s own MCP process env (AGENTMUX_LAN_KEY) at spawn, same never-over-RPC guarantee as v18. See docs/specs/SPEC_JEKT_LAN_TIER_SIGNING_2026_08_15.md §2.1. v21 — db_lan_peer_pubkey_pins: trust-on-first-use pin of a REMOTE agent_id’s LAN public key, as first observed from mDNS-discovered peers. reagentx P0 on the LAN signing PR: peer discovery itself is unauthenticated (any device can broadcast an mDNS instance and register an agent under an existing agent’s name), so trusting “whichever peer answers first” for a pubkey lookup lets an attacker’s self-minted key be accepted as authoritative for a victim’s agent_id. Pinning the first-seen key and rejecting any later mismatch (rather than silently accepting the newest answer) is the standard SSH-host-key mitigation for exactly this “no PKI available” situation — closes the always-spoofable case, narrows it to a race on the very first lookup ever performed for that agent_id. See docs/specs/SPEC_JEKT_LAN_TIER_SIGNING_2026_08_15.md §2.2. v22 — db_background_tasks: durable record of a declared long-running (run_in_background: true) task attached to a block, so its liveness survives past DockSnapshotCache‘s 1-hour eviction and a session reconnect/reload — the ephemeral client-transcript- derived signal chain had no durable source of truth at all. Per- channel (block ids are only meaningful within their own channel), not the shared store. Renumbered from an earlier v20 to v22 when merged alongside the LAN-tier jekt signing PR, which independently claimed v20/v21 for an unrelated table pair — see docs/status/STATUS_ATTACHED_TASK_AXIS_AND_DEV_LOOP_2026_08_15.md, issue #2492. v23 — db_bundle_skills_ref, db_bundle_mcp_ref: bundle-level references to the standalone skill/MCP-server primitives, mirroring the v10 agent-level ref tables but keyed by bundle_id — composable model v2, step 1 of docs/specs/SPEC_BUNDLE_AS_CONTAINER_V2_2026_08_17.md (GH issue #2024 item 3). A bundle’s existing mcp_servers/skills JSON columns are untouched by this — still the .abf export/import format — these ref tables are the new live-resolution path. Deliberately NO FK to db_bundles (unlike the agent-level ref tables’ FK to db_agent_definitions) — see this table’s own doc comment at its CREATE TABLE for why. v24 — db_agent_native_memory_versions: append-only version history for native memory content, mirroring the v14 table’s own dual- schema duplication (id_store per-channel fallback). See docs/specs/SPEC_MEMORY_VERSION_CONTROL_AND_ARMORY_AUDIT_2026_08_19.md. v25 — db_agent_groups: saved, named target sets for the fleet-control feature (broadcast/bulk-stop across many agent panes at once — docs/specs/SPEC_MULTI_AGENT_FLEET_CONTROL_2026_08_20.md). A group is just a durable list of block ids under a name — the Ansible-inventory-group lesson from that spec’s research: a saved group, not raw ephemeral selection, is the abstraction that scales as a fleet grows. Per-channel (block ids are only meaningful within their own channel), not the shared store. Renumbered from an earlier v24 — merged alongside the native- memory-version-history PR, which independently claimed v24 for an unrelated table (see that entry above for the same class of collision this codebase has hit before, e.g. v20→v22). v26 — db_agent_definitions.conversation_visibility (TEXT, default ‘private’) + db_conversation_trust_grants: muxspect Phase B/C’s per-agent disclosure policy for an incoming cross-tier transcript_request jekt (LAN/WAN conversation visibility — docs/specs/SPEC_MUXSPECT_CROSS_TIER_CONVERSATION_VISIBILITY_2026_08_21.md, jekt tier rules confirmed in docs/specs/SPEC_JEKT_TRANSCRIPT_REQUEST_TIER_RULES_2026_08_22.md). One of “private” (default, auto-deny)/“trusted_peers” (auto- approve an allow-listed requester)/“ask” (force human escalation). Also dual-written to db_agents (mirrors auto_continue_enabled’s treatment exactly — a simple per-agent opt-in-style setting, unlike memory_id/model_vendor_base_url, which use a differently-named column there). Deliberately NOT added to DefinitionRecordV1’s cross-channel wire format — channel-local only, same precedent as those two fields; a cross-channel-reopened agent starts back at the safe “private” default. db_conversation_trust_grants mirrors db_lan_peer_pubkey_pins’s exact shape (own module, get/set-style methods, case-insensitive agent_id lookups). v27 — db_bundles.is_system: an AgentMux-controlled, highest-priority Global Bundle tier (INTEGER, default 0). A system row is always also is_global=1 (enforced in code, not a CHECK constraint — see bundle_upsert_system). Writable only through the dedicated upsertsystemmemory/deletesystemmemory RPCs and Store::bundle_upsert_system/_delete_system — the generic bundle_upsert/_delete/_reorder all refuse to touch an is_system=1 row. Injected first in format_global_bundle_block’s output, wrapped in explicit override wording, ahead of every ordinary Global Bundle section. See docs/specs/SPEC_GLOBAL_MEMORY_SYSTEM_TIER_2026_08_24.md. v28 — db_agent_activity_summaries: one-shot, on-demand Haiku-generated activity summary per definition_id, used as the AgentPicker’s “My Agents” conversation-preview fallback when a row has no structured output.state.json snapshot to preview (legacy rows predating snapshot persistence — see has_snapshot in listrecentsessions, agent_handlers/session.rs). Generated from the instance’s raw "output" filestore file (present even when the newer structured snapshot isn’t) via the same shared Ambient Model Call gateway dispatch_name/term:ambient_summary already use (invoke_haiku, docs/specs/SPEC_AMBIENT_MODEL_CALLS_FRAMEWORK_2026_07_03.md). Generated lazily (first picker load that needs it, not on every turn) and cached forever once non-empty — mirrors SubAgent.display_name’s cache-once posture, not term:ambient_summary’s per-turn refresh. Renumbered from an earlier v27 — merged alongside the Global Bundle system-tier PR (#2782), which independently claimed v27 for an unrelated column (same collision class as this file’s own v20→v22 and v24→v25 history, see those entries above). See docs/reports/REPORT_AGENT_PICKER_FIELD_ORDER_SORT_AND_DATA_GAPS_AUDIT_2026_08_24.md §5a. v29 — db_agents.session_id / status / started_at / ended_at: the agent’s LATEST launch state, the four db_agent_instances columns the consolidated row never got (Phase 3a deliberately left them “on the block”, but the recent-sessions picker, the pane close/reopen continuity write-back and the status-filtered instance list all kept reading them from the legacy table — the reason it could not be dropped). One row per agent ⇒ one launch state per agent; a continuation moves it to the new block/session. Backfilled from the legacy rows by m0025_agents_launch_state_backfill (latest instance per projection key), kept current by the instance dual-write, and the read flip in SPEC_AGENT_ARCHITECTURE_2026_05_27.md Phase 3b retires the legacy reads on top of it. No unique index on db_agents(slug) is added: template-launch projections copy their template’s slug, so uniqueness stays a definition-level rule enforced by the slug collision scan in agent_def_insert. v30 — db_agent_content / db_agent_skills / db_agent_history / db_agent_identity_links / db_agent_skills_ref / db_agent_mcp_ref: agent_id‘s foreign key now targets db_agents(id) instead of db_agent_definitions(id). Every existing row already satisfies the new target (its agent_id is a definition id, and every definition has a db_agents mirror at the same id) — what changes is that a db_agents row with NO definition counterpart (a template launch) can now hold these directly too, closing the gap listrecentsessions’ template fallback (Phase 3b, #3080) exists for. SQLite has no in-place FK redefinition, so an existing store needs its six tables rebuilt; m0028_agent_child_tables_repoint_fk does that (rename, recreate, copy, drop, PRAGMA foreign_key_check before commit). A fresh install gets the new FK directly from the CREATE TABLE statements below — nothing to rebuild there. Phase 3c (SPEC_AGENT_ARCHITECTURE_2026_05_27.md). v31 — No DDL change. Every agent_def_* write now lands on db_agents only — db_agent_definitions is no longer kept in sync (Phase 3d, #3092). Bumped anyway (codex P1 on #3092): check_schema_compat is a downgrade guard as much as a schema guard, and this release changes what a NEWER binary’s writes mean to an OLDER one just as much as a column would. Without the bump, rolling back to the immediately preceding binary after this version has run would silently accept a store where new agents exist only in db_agents — that binary’s agent_def_get/ update/delete still target db_agent_definitions and would 404 on them, or replay stale legacy values back into db_agents on edit. Stamping 31 makes that downgrade refuse to open instead. v32 — db_agent_definitions and db_agent_instances are dropped. Nothing has read or written either table since v31 (agent-concept consolidation’s definition and instance flips, #3080/#3092); this is the final phase (Phase 3e, SPEC_AGENT_ARCHITECTURE_2026_05_27.md) closing out the tracking spec. db_agent_instances’ CREATE TABLE/indexes and db_agent_definitions’ CREATE TABLE are gone from this function — leaving either would silently recreate the tables (empty) on the very next Store::open() after the drop migration runs, since migrations execute before this function does on every boot. db_agent_definitions’ own ALTER TABLE ADD COLUMN entries, by contrast, are KEPT — gated on the table still existing (see that block’s own comment below) — because several pending migrations (m0007, m0025, m0026, m0028) call Store::open() internally, running this function, before m0029 (numbered last) ever drops the table in the SAME upgrade pass; a store old enough to be missing one of those columns would fail those migrations’ own reads with “no such column” otherwise (Codex P1 on #3096). An existing store’s tables are actually removed by m0029_drop_legacy_agent_tables; a fresh install never has them to begin with, so the gate is a no-op for it. adopt_legacy_table_names’s db_forge_agents → db_agent_definitions rename entry is left in place deliberately: an install old enough to still carry db_forge_agents reaches it during an EARLIER migration’s own Store::open() call (every migration in this chain lays down schema that way), so the rename still fires before m0029 runs later in the same upgrade pass and correctly drops what the rename just produced — no special-casing needed, and no data is stranded under the old name. v33 — db_agent_project_instructions: what each agent was last observed to read as project instructions from its working directory, keyed (agent_id, path). Phase 3 of SPEC_INSTRUCTION_AND_MEMORY_PORTABILITY_2026_09_09.md.
SAGA_LOG_SCHEMA_VERSION
user_version value stamped into sagas.db.
SHARED_STORE_SCHEMA_VERSION
user_version stamped into ~/.agentmux/shared/store.db after run_shared_store_schema. Versioned independently from objects.db. v1 — initial: identity accounts/bundles/bindings/links, memory bundles, drone definitions, muxbus credentials v2 — db_cron_jobs: persistent scheduled injection jobs v3 — Phase 4a of SPEC_PRESET_TO_BUNDLE_REFACTOR_2026_07_02.md: rename db_identity_accounts -> db_accounts, db_memory_bundles -> db_bundles (SPEC_ARMORY_PHASE4_STORAGE_RENAME_COMPLETION_2026_07_12.md). v4 — db_agent_credentials: per-agent M2M Cognito client_id/secret + cached access token, one row per locally-registered agent_id. Lets cloud_subscriber use a credential bound to a specific agent instead of the single shared per-account MUXBUS_TOKEN for every /reactive/* call. v5 — db_cron_jobs.max_age_secs: optional hard expiry bound (seconds since created_at) alongside the existing max_fires bound. NULL = no expiry (existing rows unaffected). See docs/specs/SPEC_AGENT_POLLING_AND_WAKEUP_HARDENING_2026_08_04.md Phase 0. v6 — db_agent_native_memory: durable, location-consistent mirror of each agent’s native memory files, keyed by (agent_id, filename). See docs/specs/SPEC_NATIVE_MEMORY_DURABLE_SYNC_2026_08_07.md. v7 — db_bundles.instructions_by_provider: JSON object of {provider_id: content} instruction variants, additive to the existing flat instructions column. ABF v0.2 §2.2, see docs/specs/SPEC_ABF_V0_2_PROVIDER_AWARE_COMPONENTS_AND_NATIVE_MEMORY_2026_08_10.md. v8 — db_agent_native_memory_versions: append-only version history for native memory content, one row per agent:memory:write_file call (plus reverts and, later, out-of-band-write detection) — the mirror in v6 only ever holds the current value, with no way to see what a file contained before its last write. See docs/specs/SPEC_MEMORY_VERSION_CONTROL_AND_ARMORY_AUDIT_2026_08_19.md. v9 — db_bundles.is_system: AgentMux-controlled, highest-priority Global Bundle tier — see OBJECT_SCHEMA_VERSION’s v27 doc comment (objects.db, above run_object_schema) for the full design; this store just needs schema parity. v10 — db_bundle_versions: append-only version history for Global Memory entry content — see OBJECT_SCHEMA_VERSION’s v35 doc comment for the full rationale (SPEC_AGENT_FACING_GLOBAL_MEMORY_API_2026_09_15.md); this store just needs schema parity, same as v9 above. v11 — db_cron_jobs.target_uid: the target agent’s UID (db_agents.id) beside the slug column, resolved once at create time and dual-written; nothing reads it yet, a job still fires by target. Identity M1b of SPEC_AGENT_IDENTITY_CARRIED_NOT_DERIVED_2026_09_23.md §9.1 — spec §5.4: non-interactive ingress never resolves a name at fire time, so the UID has to be captured while a human or model is present. Empty when the name did not resolve; never guessed. v12 — db_cron_jobs.created_by_uid and db_bundle_versions.written_by_uid: the actor’s UID beside each actor-name column, taken from the request’s Caller (its X-Agent-Token), never from a body field. Empty for an Unattributed request; never guessed. Dual-written, not yet read. Identity M4c-1 of SPEC_AGENT_IDENTITY_CARRIED_NOT_DERIVED_2026_09_23.md §6.5.9.
WSTORE_OTYPES 🔒
Object type table names matching the db_<otype> convention.

Functions§

adopt_legacy_table_names 🔒
Rename any pre-flatten objects.db tables to their de-forged names and drop the dead workflow/sentinel tables. Idempotent — on a fresh or already-flat database every check is a no-op.
check_schema_compat
PRAGMA user_version tripwire (AUDIT_SQLITE_SYSTEMS §8.5).
run_filestore_migrations
Initialize the FileStore schema. Creates the wave_file and file_data tables. Already a flat single-DDL store — unaffected by the objects.db flattening.
run_identity_store_schema
Initialize (or re-validate) the ~/.agentmux/shared/identity-store.db schema — the permanently-global store introduced by docs/specs/SPEC_IDENTITY_STORE_SPLIT_2026_08_17.md to fix conversation-continuity-across-a-version-switch (docs/specs/REPORT_HISTORY_CONTINUITY_ACROSS_VERSION_UPGRADE_2026_08_17.md).
run_object_schema
Initialize (or re-validate) the full objects.db schema.
run_saga_log_migrations
Initialize the saga durability schema (saga + saga_step tables and their indexes). See docs/specs/SPEC_SAGA_DURABILITY_2026-05-01.md §2.2. Already a flat single-DDL store.
run_shared_store_schema
Initialize (or re-validate) the ~/.agentmux/shared/store.db schema.
stamp_version
Stamp the database’s user_version PRAGMA to current. Called AFTER run_*_schema succeeds, paired with a prior check_schema_compat that gated the migrations on the caller-binary speaking a compatible (or newer) schema version.