Implements the two missing branches of runUpgrade dispatcher:
- runFreshInstall: gated by --yes, runs doctor.next_action.ai_executable
steps in order, fails fast on first error, attaches steps[] to thrown
errors. Accepts mockExec for unit tests.
- runRollback: locates latest or named snapshot in ~/.ocp/, reads
from-commit.txt, restores plist + db + admin-key + service file (with
per-file warn lines on copy failure), git-checkouts the from-commit,
npm installs at that revision, restarts the service. --list shows all
snapshots; --dry-run prints the plan without mutation.
Both paths use the same exec() error-wrap pattern as runFullUpgrade
(stderr capture, phases attached to thrown errors, restart heads-up).
CLI entrypoint extended to parse --rollback / --list / --target / and
optional positional snapshot path after --rollback.
6 unit tests cover: --yes gate, fresh_install ai_executable run,
--rollback --list, no-snapshots error, --rollback --dry-run, mock-exec
restore.
No cli.js citation needed: this is OCP-internal upgrade tooling with
no corresponding cli.js operation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 issues raised by code-quality reviewer on c12013a:
A. exec() wrapper now captures stderr from execSync failures and
re-throws with `phase X failed: <stderr>` instead of the terse
"Command failed: ..." default. Operators see the actual git/npm
error.
B. runFullUpgrade body wrapped in try/catch; any error after phase 2
(snapshot written) carries snapshotPath + phases + hint pointing
at `ocp update --rollback`. Aligns with the post-flight failure
pattern.
C. CLI entrypoint now prints snapshotPath + hint on error.
Plus minor:
- snapshot.mjs tryCopy logs a [snapshot] warn line instead of silently
swallowing copy errors (e.g. permission-denied admin-key)
- heads-up window 1s → 3s, more operable per the policy intent
- opts.yes intent comment added (Bundle 3 will use)
One regression test added.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements the upgrade dispatcher (noop / dry-run / light delegation /
full path) and the snapshot writer/reader/list module. Full path snapshots
plist + db + admin-key + openclaw.json before mutating, runs the 6 phases
(pre-flight, snapshot, fetch+install, reconfigure, restart, post-flight),
and emits a heads-up before launchctl bootout per
notify_before_prod_service_restart.md policy.
mockExec/mockDoctor injection points let tests verify the phase ordering
without touching the real shell. fresh_install + rollback paths are
deferred to Bundle 3.
No cli.js citation needed: this is OCP-internal upgrade tooling with no
corresponding cli.js operation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>