Repository navigation
Conversation
|
Batch compatibility validation: synthetic integration head 5b74b8b58058a969838ad9738f419be7eb907151 combines PR #2190, PR #3259, PR #3261, and this head. Source process-death recovery, deployment receipt/status (12/12), backup coverage, application-consistent backup, integrity, round-trip restore, rollback, and combined Bash syntax suites all passed. No production-file conflict was required for this PR. |
|
Thanks for this contribution. We're closing outside-contributor pull requests that have had no activity for 14 days or more, so the queue reflects work that can still land. This isn't a judgment on the change itself. If it's still needed, please rebase onto |
Ready for independent review (2026-09-15). Candidate
357c157e050e6deb92617b23f1646f695dae6541has a successful GitHub check rollup and no base-branch conflict at this review snapshot. This supersedes earlier draft-status wording only. All validation gaps, migration requirements, live gates and independent human review requirements below remain in force; this is not a merge-ready approval.Why this matters
ods-update.sh updatemutates source, configuration, migrations, and the running Compose stack as one operator action. Before this PR, normal migration/health failures restored configuration but left the checkout on the failed release. Even after adding source rollback, an uncatchable exit such as host reboot, power loss, orSIGKILLcould strand the installation between phases because all rollback context lived only in shell variables.The reachable path is the shipped source-checkout command itself and the dashboard host-agent update endpoint that invokes it. A later attempt previously had no durable proof of the pre-update revision, rollback snapshot, compose overlays, or last completed phase.
Root cause and invariant
Root cause: update rollback was process-local. The updater had no cross-process owner lock and no durable transaction record linking source, snapshot, compose plan, phase, and recovery result.
Invariant: before the first source mutation, ODS durably records enough information to restore the exact prior source/config/runtime state. A later update must recover or report an explicit incomplete state before starting new mutation, and automatic recovery must never overwrite tracked operator edits made after the interruption.
What changed
data/update-transaction.jsonwith phase receipts:prepared -> source_updated -> migrations_complete -> runtime_restarted -> verified -> committed.update, detect any non-terminal journal and restore the recorded source revision, snapshot, and compose stack before allowing another release attempt.recovery_requiredrather than resetting them.rolled_back,recovered,abandoned, orrecovery_failedreceipts and expose the latest state throughods-update.sh status.Overlap check
Searched open and closed PRs for
source rollback,update journal,interrupted update,crash recovery,update lock, and PRs changingods/ods-update.sh.None persists an in-flight source update across process death, performs next-run recovery, or excludes concurrent updater processes. This remains an extension of the original #2709 source-rollback scope rather than a competing PR.
Regression tests
bash tests/test-update-source-rollback.shuses a real bare Git remote and the public updater. It proves:SIGKILLto its parent leaves asource_updatedjournal and stale owner lock;recovery_required;recovered, and exposes that receipt through public status.Focused validation:
bash tests/test-update-source-rollback.sh— 5 passedbash tests/test-ods-update-runtime-compose.sh— 5 passedbash tests/test-rollback-compose-stack.sh— 7 passedbash tests/test-update-script-backup.sh— 6 passedbash -n ods-update.sh tests/test-update-source-rollback.sh— passedmake lint— passedgit diff --check— passedmake testprogressed through the model/tier suites (129 passing assertions) but stopped at the pre-existingtest-installer-context-parity.shassertionHermes template bounds each model turn. This branch does not change that test or any Hermes template; the same files are identical toupstream/main. Local ShellCheck is unavailable in this Windows environment, so CI owns the exact ShellCheck validation.Design, platform, and rollback
The journal contains no secrets: only schema/state, Git revision, snapshot path, compose flags, timestamps, and an outcome reason. It and the lock owner file are written mode
0600; phase changes use temp-file plus rename. The implementation uses Bash,mkdir,mv,kill -0, Git, and jq on Linux, macOS, WSL2, and Git Bash paths already supported by this script.Recovery deliberately stops after restoring the previous release; it does not immediately retry the same candidate that just killed the updater. Invalid journal/snapshot paths and malformed lock ownership fail closed. The snapshot is retained for operator inspection and explicit rollback.
Reverting this PR removes automatic source restoration, exclusion, and crash recovery; existing rollback snapshots remain readable. This is lifecycle-critical code and should receive independent human review before merge.