Menu
AkurAI-Build
publicLatest change 941c1e29871d5e7548906ba3b75ddd925cc9326e - ci: fail closed on PR branches, fix false rollback claims, drop PyYAML by Ólafur Búi Ólafsson
# PR queue recovery: binary rollback vs migration rollback Scope: what actually happens today when a production deploy needs to be walked back, and what is still only a plan. Owned by the `feature/pr-ci-safety` slice (`.akurai.yml`, this doc, and `tests/test_pr_pipeline.py`); it does not touch `src/`, `migrations/`, or Cargo files. Revision note: an earlier version of this doc labeled binary rollback "TESTED" and claimed it was schema-independent. Independent review (comment 76 on parent t_2578e75e) found both claims false. This revision corrects them; see "What is NOT tested" below for the exact gaps. ## 1. Deploy-agent binary rollback — IMPLEMENTED, NOT RUNTIME-TESTED Path: `deploy/service-deploy.sh` (in-sandbox CI job) hands a checksummed candidate to the root-owned host agent `deploy/host/akurai-deploy-agent.sh`, which: 1. Verifies the staged sha256 against the request file. 2. Copies the current `akurai` binary to `akurai.previous` before installing the candidate (`cp "$bin" "$bin.previous"`). 3. Restarts the service and polls `GET /api/health` up to 30 times (2s interval, 60s budget). 4. On health-gate failure: restores `akurai.previous` over the live binary, restarts, and reports failure — but does NOT re-poll `/api/health` on the restored binary before reporting (`akurai-deploy-agent.sh:67-69`). A restore that itself fails to come up healthy would still report "rolled back" without confirming it. 5. On health-gate success: deletes `akurai.previous`, `processing`, and the candidate (`akurai-deploy-agent.sh:57`). The backup is temporary — it exists only for the duration of one health-gate window, not retained as a standing rollback target. A second bad deploy after a first succeeded has no `.previous` to restore from. Status: this is a description of what the script does, verified by reading `deploy/host/akurai-deploy-agent.sh` end to end. It is NOT runtime-tested: no test in this repository (`tests/`, `src/`) exercises this script, forces a candidate health failure, or observes the restore actually happen and the restored service actually come back healthy. Do not call it "TESTED" until that runtime evidence exists (forced failure -> observed restore -> observed post-restore health-check pass, plus a test verifying step 4's blind spot is closed). ## 2. EC2 rollback (`src/ec2/deploy.rs::rollback`) — SEPARATE, unrelated path `src/ec2/deploy.rs::rollback` is a distinct, manually-invoked `akurai-ec2 rollback <name>` verb operated against `AkurAI-EC2`-managed services. It is NOT invoked by `.akurai.yml`'s `deploy-production` job, which calls `deploy/service-deploy.sh` only. The two rollback mechanisms share the same shape (back up to `.prev`/`.previous` before overwrite, require the backup to exist to roll back) but are independent code paths for independent deployment targets. Treat them separately; do not assume test or runtime evidence for one applies to the other. ## 3. Migration rollback — PLANNED, not yet implemented `src/db.rs::migrate` applies `MIGRATIONS` (currently 001-010) forward inside one transaction per boot, tracked by a ledger table and `PRAGMA user_version`. There is no down-migration, no reverse-SQL table, and no CLI verb that reverts a specific migration number. Every migration file inspected (001-010) is additive (`ALTER TABLE ...ADD COLUMN`, `CREATE TABLE`, `CREATE INDEX`) with no destructive change to existing columns/rows. Because binary rollback (section 1) puts an older binary in front of the current (possibly newer) schema, "rolling back" a bad deploy that shipped alongside a migration means running an old binary against a new, additive schema. Whether an older binary genuinely tolerates a newer additive schema at runtime is NOT verified by any automated test today — it is an assumption resting on the migration authors' additive discipline, not a proven runtime property. Binary rollback is therefore NOT schema-independent in general; it is conditioned on that untested compatibility assumption holding, and production rollback after a migration should be treated as unverified until an integration test exercises old-binary-against-new-schema. If a future migration needs to be destructive (drops a column, rewrites data) the additive assumption breaks entirely and a tested down-path would be required before that migration ships; this doc does not claim such a path exists. Coordination note: this slice does not add migration 011 or PR persistence — that is owned by the primary application-integration builder (t_2578e75e / t_2667e5e8 parent). If migration 011 stays additive, section 3's reasoning continues to hold without further doc changes; if it is not additive, the primary builder should update this section rather than assume it. ## 4. What is NOT tested - Deploy-agent rollback under a forced candidate health failure (no test drives `akurai-deploy-agent.sh` through a failure and observes restore). - Health verification of the restored binary after a rollback restore (`akurai-deploy-agent.sh` does not re-check health post-restore; nothing papers over that gap). - Recovering from two consecutive bad production deploys (only one `.previous` generation exists, and only until the first deploy's health gate succeeds — after success it is deleted). - Reverting a specific already-applied migration (no down-SQL exists). - Old-binary-against-newer-additive-schema runtime compatibility (assumed from migration authors' discipline, not verified by an integration test). - `src/ec2/deploy.rs::rollback` runtime behavior (separate mechanism per section 2; not exercised by this repository's `deploy-production` job or by any test referenced in this doc).