Skip to main content

Module runner

Module runner 

Source
Expand description

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.

Both paths report the SAME per-migration begin/done progress (ApplyProgress) but over different channels: the CLI path emits newline-delimited JSON to stdout (read by the dead subprocess path, kept for that reason); run_pending_migrations emits agentmux_common:: srv_stderr’s AGENTMUXSRV-MIGRATION-BEGIN/-END lines to stderr — the real, in-process boot path’s own protocol, so the launcher’s splash screen can show live per-migration sub-rows instead of a silent clock. Failures are written to <home>/logs/migration-error.log; the process exits non-zero so the launcher can surface the error rather than booting with a half-migrated data dir.

Structs§

AppliedIds
Which migration ids each tracking store records as applied, read through a FALLIBLE path. Err means the store exists but its tracking state could not be read (not a database, malformed table, locked): every migration of that scope then reports VerifyOutcome::Error instead of being silently skipped as “unapplied” and letting the pass exit 0 — codex P1 on #3058, which Store::migration_is_applied’s unwrap_or(false) would have caused. A store file that does not exist, or one predating the db_migrations table, has nothing recorded and is Ok(empty).
ApplyOutcome 🔒
What a batch did. skipped = already applied at the time of the run.
ApplyProgress 🔒
Per-migration progress hooks. Two real implementations: the CLI’s NDJSON stdout lines (run_migrate_command), and — since this PR — run_pending_migrations’s AGENTMUXSRV-MIGRATION-BEGIN/-END stderr lines, which the launcher turns into live splash sub-rows. Both also still get the unconditional tracing lines apply_pending emits regardless of whether a progress hook is passed at all.
DoctorReport
The complete migration doctor report for one data dir.
DoctorRow
One registry migration, in registry order.
DoctorSummary
MigrationLock 🔒
Held for the duration of a migration batch. Dropping it releases the lock.
VerifyRecord
One line of the verify report.

Enums§

PendingCountError
Why a pending count could not be determined. Distinguished from “zero pending” on purpose: a caller deciding whether the schema is current must be able to tell “nothing to do” from “I could not tell”, because the safe reaction to each is opposite.

Constants§

MIGRATION_LOCK_FILE 🔒
File name of the lock database, created beside the shared store.
MIGRATION_LOCK_WAIT 🔒
How long a second runner waits for the first to finish before giving up. Matches the launcher’s extended ESTART deadline for a long migration batch (srv_spawner.rs / sidecar.rs: 30 minutes).
VERIFY_FAILED_EXIT_CODE
Exit code of migrate --verify when at least one applied migration’s post-condition is a mismatch or its check errored. Distinct from 1 (a migration RUN failed) so a caller can tell “your data is inconsistent” from “the migrate command itself broke”, and from 2, which clap uses for a CLI usage error (a typoed flag must not read as a data finding — reagent P2 on #3058). See docs/exe-return-codes.md.

Functions§

apply_pending 🔒
The locked migration batch — the ONE apply path, used by the daemon (run_pending_migrations) and by agentmux-srv migrate. Generic over the registry so the concurrency contract can be tested with a fake migration.
backup_stores 🔒
build_doctor_report 🔒
Assemble the report from an already-run verify pass, so cmd_verify can print the per-record NDJSON lines from the same records the report summarises rather than verifying twice.
cmd_list 🔒
cmd_verify 🔒
count_pending_migrations
Return the number of REGISTRY migrations that have not yet been applied, reporting 0 on any error so startup is never blocked.
doctor_inputs 🔒
Paths and tracking state the doctor works from. Reads both tracking stores through the fallible read-only path; never opens a Store.
doctor_report
The doctor report for data_dir, against an explicit registry (tests pass fakes; production passes REGISTRY). Read-only.
doctor_report_for_instance
doctor_report for the running instance’s own registry and resolved shared store / home — what GET /api/v1/muxspect/migrations serves. Err when the shared root can’t be resolved at all (no AGENTMUX_SHARED_DIR, CI), the same condition under which run_migrate_command treats migrations as a no-op.
emit 🔒
emit_summary 🔒
open_readonly 🔒
Open an existing SQLite file read-only. Ok(None) when the file is absent — never creates one (the whole point of this path).
open_stores_for_preview 🔒
Open the shared + channel stores the way every writer does (creating the channel dir/db on a fresh install — see the comment inside). Shared by the locked batch and the lock-free --list/--dry-run previews.
pending_of 🔒
The migrations in regs whose tracking store does not record them applied.
prune_old_backups 🔒
read_applied_ids 🔒
SELECT id FROM db_migrations through a read-only connection. A missing file or a missing table is Ok(empty) — nothing was ever recorded there. Any other failure is Err, which verify_applied turns into an Error outcome for every migration of that scope.
resolve_home 🔒
The true, unconditional ~/.agentmux root — MigrationContext.home.
run_migrate_command
Called from main.rs when the migrate subcommand is active. Returns the exit code (0 = success, 1 = failure, 3 = --verify found a mismatch — see VERIFY_FAILED_EXIT_CODE).
run_pending_migrations
Apply all pending migrations in-process before srv opens its stores.
table_count 🔒
SELECT COUNT(*) FROM <table> on a (read-only) connection, treating a missing table as 0 rows — a store from before the table existed has nothing in it, which is exactly the answer a post-condition wants. Any other SQLite error is surfaced. table must be a literal identifier from the calling migration, never user input (it is interpolated, not bound).
tracking_store 🔒
Return the store that tracks applied state for a migration of the given scope. Global migrations → shared store; Channel migrations → channel store.
try_count_pending_migrations
Number of REGISTRY migrations not yet applied, or why that could not be determined.
verify_applied
Run verify() for every migration in regs whose tracking store records it as applied. Generic over the registry slice so the harness can be tested with fakes; production passes REGISTRY.
verify_event_line 🔒
One migration_verify NDJSON line. detail goes through serde_json so control characters (a multi-line SQLite error, say) cannot break the line-delimited stream a consumer tails (reagent P2 on #3058).
verify_exit_code
Exit code for a verify report: 0 unless any record is a mismatch or an error. NotVerifiable is not a failure — it is the honest default.
write_error_log 🔒