Skip to content

rtb-update v0.1

Self-update for tools built on RTB. A composition of three standards-grade primitives — rtb_vcs (release metadata + asset bytes), ed25519-dalek (detached-signature verification), and self-replace (atomic binary swap). The crate's contribution is the flow: every step is survivable, so the binary on disk is always either the old version or the fully-verified new one — never anything in between.

Public API

use rtb_update::{CheckOutcome, RunOptions, Updater};

# async fn run(app: &rtb_app::app::App, provider: std::sync::Arc<dyn rtb_vcs::ReleaseProvider>) -> Result<(), rtb_update::UpdateError> {
let updater = Updater::builder()
    .app(app)
    .provider(provider)
    .build();

if let CheckOutcome::Newer { .. } = updater.check().await? {
    let outcome = updater.run(RunOptions::default()).await?;
    println!("{outcome:?}");
}
# Ok(())
# }
Item Purpose
[Updater], [UpdaterBuilder] Typestate builder (app + provider required); check() and run().
[RunOptions], [RunOutcome] Inputs / result of a full update run.
[CheckOutcome] Result of a metadata-only check()UpToDate / Newer / Older, no asset download.
[ProgressEvent], [ProgressSink] Streamed progress (download %, verify, swap) for TUI/CLI reporting.
[UpdateError] thiserror + miette::Diagnostic error enum.

The builder also accepts swap_fn, self_test_fn, and cache_dir overrides — the first two are the test seams that let the flow be exercised without actually replacing the running process.

Verification

Release archives ship with an Ed25519 detached signature and a SHA-256 .sum. run() verifies both before calling self-replace. A signature or checksum mismatch aborts the swap and leaves the existing binary untouched. See secure releases.

CLI

The update command is registered into BUILTIN_COMMANDS and is a default-enabled runtime feature. Updater::run_from_file supports the offline/airgap path (verify + swap from a locally-staged archive).

Spec

Authoritative contract: docs/development/specs/2026-04-23-rtb-update-v0.1.md.