feat(cli): show native update progress and drop the rollback point - #1375
Conversation
The rollback point took about two of the two and a half minutes of a native update on the home box (a 410 MB settings database), and nothing on native could restore it. ADR 0007 already removes it: a native update now has three steps (download, check, start) and keeps data in place. Manual rollback points are refused on native, and the rollback refusal names ftw rollback and a full backup instead of a tool that could not read the point. Core records each finished step with its own timing and bytes in the update status, and the new Core closes the start step when it commits. A download that ends between two reads still shows. Before downloading, Core refuses when the install root has less than three times the current release free, since state and history usually share that disk. /api/version/check reports the install root, its free space and that need; /api/backups reports free space beside the archives. ftw draws each step on a terminal as its name and a bar with size, rate, time left and elapsed time, and closes it with one line giving its duration and average rate. Logs and scripts get one line per step. It polls every half second, shows a history migration while the new Core starts, names the previous release's directory, and stops before asking Core when the disk is short. ftw status adds free space for releases and backups and lists rollback points an older Core left. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da73e46caa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| return err | ||
| }) | ||
| return 3 * size, err |
There was a problem hiding this comment.
Size the guard from the target release
SpaceNeeded assumes both the next archive and extracted tree are no larger than the current installation, but nothing enforces that assumption: archives may be up to 1 GiB and extraction up to 2 GiB. If a release grows substantially or is accidentally bloated, this check can pass with only 3 * currentSize free and the subsequent extraction can exhaust the filesystem shared with state/history—the exact failure this guard claims to prevent. Base the requirement on target asset/package metadata or a conservative enforced maximum instead.
AGENTS.md reference: AGENTS.md:L66-L68
Useful? React with 👍 / 👎.
| if err := manager.CheckSpace(slots.Current); err != nil { | ||
| return err |
There was a problem hiding this comment.
Let retries reuse an already-installed target
When a restart or trial fails after InstallArchive succeeds, CancelPrepared/Select records the target as LastFailed and deliberately retains its release directory. On a host that initially had only slightly more than the new three-times-current requirement, that retained target consumes roughly one current release's space, so this unconditional check rejects every retry before InstallArchive can take its idempotent existing-target path. Account for an already-installed target, or remove/reuse it before applying the full fresh-install threshold, so recovery from a transient restart failure remains possible.
AGENTS.md reference: AGENTS.md:L24-L25
Useful? React with 👍 / 👎.
Summary
Fredrik tested
ftw updateon the home box (v0.132.0-beta.1 → v0.133.0-beta.1). Of its 2 min 33 s, about two minutes went to "Saving rollback point", with no progress shown for the first 1.5 minutes. The settings database there is 410 MB. The request was clearer progress: a bar, MB/s, time left, disk space and paths.ftw-backup, which cannot read it./api/version/checkreportsinstall_root,install_free_bytesandinstall_need_bytes./api/backupsreportsfree_bytes.ftwprogress:✓line with duration and average rate, for example✓ 1/3 Downloading verified Core release 24.0 MB in 0.4s (60.0 MB/s). The bar width follows the terminal, and non-UTF-8 locales get ASCII.ftw updatestops before asking Core when there is not enough space.ftw statusadds free space for releases and backups. It lists rollback points an older Core left, with size and directory. Core deletes nothing; the owner decides. On the home box they are 906 MB in five points.schollz/progressbar,cheggaaa/pbandmpb. None was added, because a plain-line mode for wrappers is needed anyway and the rendering is about 150 lines.golang.org/x/syswas already a dependency and gives the terminal width.minorchangeset, because it removes the rollback point. Owner approval needed.Tests
nativeupdate: space needed equals three times the release; a sparse 8 TiB release is refused.selfupdate: three native steps with recorded phases.cmd/ftw: the new Core records its start step at commit.api: a native update takes no rollback point, manual points are refused, and backups report free space.ftwcli:make test,go vet ./...,go build ./..., the release-workflow script tests, and a cross build offtw-clifor darwin and windows all pass.LANG=C npm test, 654 pass.ftw statusshows the new lines.ftw rollbackfrom the published v0.133.0 shows✓ 1/2 Starting the previous Core once in 2.5s, taken from the branch Core's record.ftw updateto the published v0.133.0 shows download and restart. That older target drops the record when it rewrites status, so the CLI falls back to what it saw.ftw backup --output-dirshows the copy.🤖 Generated with Claude Code
https://claude.ai/code/session_01MuerPFZFG88kgu8sWVHeq7