feat(backup): vendor SHA-pinned restic v0.19.0 + secret-scrubbed runner
Foundation lode for sol private backup (spb): a new solstone/think/backup/
package with two concerns and no business logic (no keys, repo-init,
backup/restore/prune, scheduling, UI, or CLI — those are later lodes).
- readiness.py (stdlib-only, read-only): pinned restic 0.19.0 constants, the
four .bz2 SHA256 pins, the official GitHub download-URL template, per-platform
tool dirs, os/arch mapping (x86_64->amd64, aarch64->arm64), sentinel load +
reuse gate (check_restic_ready), and on-disk binary verification.
- install.py (the writer): ensure_restic acquires the per-platform .bz2 from the
official restic GitHub release (never a sol-pbc URL), SHA-verifies against the
embedded pin before decompress/exec (fail-closed, no re-download loop),
decompresses, chmods +x, and atomically installs the binary, a drift-detecting
sentinel, and restic's BSD-2 LICENSE via temp-file + Path.rename. A bundled
.bz2 override (SOLSTONE_RESTIC_BUNDLE) routes through the same pin-verify path.
- runner.py (the runner, capture-mode only): run_restic passes every secret via
env (RESTIC_PASSWORD / backend AWS_*/B2_*), keeps RESTIC_REPOSITORY
credential-free, builds a minimal allowlisted child env, never uses
--insecure-tls, supports --json and --max-repack-size, and scrubs all secrets
from stdout/stderr/json/argv on success, non-zero-exit, and timeout paths.
Long-running/streaming mode is deferred to avoid leaking restic output through
ManagedProcess health logs + the callosum logs tract.
Network-mocked unit tests cover fail-closed verification, sentinel reuse,
per-platform asset selection, the bundled override, and the load-bearing runner
secret-scrubbing invariants, plus a skip-if-restic-absent local: round-trip.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>