Releases
The unified steelframe binary ships from a versioned Cloudflare R2 channel. The same binary is the operator TUI (default), the project agent (steelframe agent run), and the updater (steelframe update).
Channel layout
Section titled “Channel layout”install.sh # bootstraplatest.json # { version, released_at, target, url, sha256 }vX.Y.Z/ steelframe-linux-x64 # the agent/TUI binary steelframe-gui-linux-x64 # native GUI gui/index.html gui/dist/<hash>/steelframe_gui.js gui/dist/<hash>/steelframe_gui_bg.wasm manifest.json SHA256SUMSlatest gui/… (mirrored at the root for Web)latest.json is the only mutating key; version directories are immutable. The web GUI pair is content-addressed: gui/index.html imports ./dist/<hash>/steelframe_gui.js and the glue loads its wasm relative to itself, so JS and wasm always come from one build. Only gui/index.html revalidates; the hashed pair is immutable. install.sh downloads the binary named in latest.json, verifies its SHA-256, and installs to $STEELFRAME_INSTALL_DIR or the first writable of /usr/local/bin, ~/.local/bin. The release job fails closed if the GUI wasm artifacts are missing.
Cut a release
Section titled “Cut a release”The workspace version and the git tag must match:
# bump [workspace.package] version in Cargo.tomlgit add Cargo.toml Cargo.lockgit commit -m "chore: release 0.2.0"git tag v0.2.0git push origin maingit push origin v0.2.0The release-r2 workflow builds the agent, native GUI, and GUI wasm on separate runners, then uploads them. To re-publish the current Cargo.toml version without a new tag, run Actions → release-r2 → Run workflow. To publish locally with the same R2 secrets in the environment:
make releaseSetup and secrets (R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET, R2_ENDPOINT, R2_PUBLIC_BASE) are in docs/releasing.md.
Install
Section titled “Install”curl -fsSL https://pub-320c65d12c95410aa947b2b539e51834.r2.dev/install.sh | shsteelframe versionUpdate
Section titled “Update”steelframe update fetches latest.json, compares semver, downloads and verifies the newer binary, and atomically replaces the running file (*.tmp then rename). It only replaces when the remote version is strictly newer; equal version with a different SHA does not replace, to avoid flapping.
- TUI startup checks the channel before entering the alternate screen and re-execs the new binary with the same arguments if it was replaced.
- The agent systemd unit runs
ExecStartPre=-steelframe update. The-prefix means a downed CDN does not take the agent offline. STEELFRAME_UPDATE_BASEoverrides the channel base.STEELFRAME_NO_UPDATE=1skips the TUI/agent update check entirely. The agent also skips the poll whenauto_update_minutes=0.
Auto-update in a running agent
Section titled “Auto-update in a running agent”The agent polls latest.json every auto_update_minutes (default 5; 0 disables). When a newer version is pending:
- Dispatch is locked, so no new workers start.
- The agent waits for in-flight workers to finish — the drain gate. It fails closed: if the worker count cannot be read, the gate holds and the next watchdog tick retries.
- The agent applies the binary and re-execs.
Restart=always plus ExecStartPre=steelframe update cover the case where the process exits instead of re-execing.
The Dashboard shows auto_update.enabled, pending, and draining.
Error handling
Section titled “Error handling”| Failure | Behavior |
|---|---|
| CDN timeout / 5xx | Keep the current binary, warn, start normally |
| SHA-256 mismatch | Delete the temp file, do not replace, warn |
| Disk full / permission | Warn, start the current binary |
| Unknown target | install.sh exits non-zero with an OS/arch message |
agent install missing master key | Refuse and print how to set STEELFRAME_MASTER_KEY |
Gotchas
Section titled “Gotchas”- A failed update never bricks a running install: the current binary stays in place.
- The GUI origin in front of R2 must send
Cross-Origin-Opener-Policy: same-originandCross-Origin-Embedder-Policy: require-corpfor the Web target to work. - The agent does not delete
steelframe.db, credentials, orprojects.tomlwhen it updates.