`wanderbooks update` reads a release manifest (default: GitHub Releases' fixed address, D-26), refuses anything not higher than this version, downloads the platform's file and accepts it only if its sha256 matches the manifest AND its minisign signature verifies against the release key compiled into the program (WANDERBOOKS_RELEASE_PUBKEY at build time; a build without one updates from nothing but a file:// feed whose key the owner names with --trusted-key, so a local release can be tried). The verified file is staged under <root>/updates/<version>/, the running version is kept under updates/previous/ with the journal format it understood, and the program file is replaced by a rename of a complete copy made beside it (a reader sees the old file or the new, never a part). The new program must answer --help; if not, the old one is put back. Nothing tells the books to stop: the host already notices a replaced executable and restarts onto it, finishing calls in progress (host.rs INVARIANT 7). `wanderbooks rollback` swaps the kept version back, and refuses while any book declares a journal format or feature the kept version does not know (plan 3.9: after the owner consents to a newer format the only way back is the pre-upgrade restore). A package-managed install (a package ships share/wanderbooks/install-method beside bin/) refuses both and says to use the package manager. An AppImage replaces the file named by $APPIMAGE. Tests (crates/ledger-cli/tests/update.rs): update_is_atomic, failed_update_rolls_back, unsigned_update_refused (another key, other bytes, a sha that differs, no signature, not a signature), bridge_survives_update, update_waits_for_a_running_call, package_managed_install_refuses_update, the kept-version and format-gate tests; unit tests in ledger-host/src/update.rs. Dependencies: minisign-verify 0.3 in ledger-host (what cargo-packager's updater uses to check release files; no dependencies of its own) and minisign 0.10 as a ledger-cli dev-dependency (the tests sign with a key they make). sha2 and the two minisign crates are built optimized in debug and test builds: the tests hash a debug build's program. The release profile strips symbols, for the packages (P11a step 3). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
42 lines
1.3 KiB
Rust
42 lines
1.3 KiB
Rust
//! The books open while something holds them (plan 3.9, D-21, D-23).
|
|
//!
|
|
//! Nothing runs in the background: the first holder (the app, an agent's
|
|
//! bridge, `wanderbooks serve`, or a command that needs the books) starts
|
|
//! the **host**, which starts the books server and holds it open while
|
|
//! any lease on its socket lasts, and closes it 10 s after the last one
|
|
//! ends. Each part is a mode of the one `wanderbooks` executable:
|
|
//! [`host::run`] (`wanderbooks host`), [`bridge::run`] (`wanderbooks
|
|
//! mcp`), and the owner's commands in [`commands`] (`serve`, `close`,
|
|
//! `books`, `token`, `connect`, `doctor`, `passphrase`, and what the
|
|
//! viewer's Books menu does). Agents' tokens are kept in files under the data root
|
|
//! ([`tokens`]).
|
|
|
|
#[cfg(unix)]
|
|
pub mod bridge;
|
|
#[cfg(unix)]
|
|
pub mod commands;
|
|
#[cfg(unix)]
|
|
pub mod host;
|
|
pub mod knobs;
|
|
pub mod lease;
|
|
#[cfg(unix)]
|
|
pub mod opener;
|
|
#[cfg(unix)]
|
|
mod start;
|
|
pub mod tokens;
|
|
#[cfg(unix)]
|
|
pub mod update;
|
|
|
|
/// How a mode stops when it can't go on: the reason is already printed,
|
|
/// and the number is the process's exit code.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub struct Exit(pub i32);
|
|
|
|
impl std::fmt::Display for Exit {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "exit code {}", self.0)
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for Exit {}
|