v0.289.0: off-site key cannot delete — append-only rclone transport, box sends only its public key (hub registrar), retention only inside a hub window behind the fake-snapshot guard (decisions 68-69, R-820, R-822)
gates / gates (push) Successful in 27s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-03 17:01:36 +02:00
parent 09453325d1
commit 55bb6c3d32
15 changed files with 1039 additions and 386 deletions
+30
View File
@@ -1,3 +1,33 @@
## v0.289.0 — the off-site key cannot delete: append-only transport, no password on the box, retention only inside a hub window (decisions 68–69, R-820, R-822) (2026-10-03)
**MinAgent: 0.131.0** (unchanged). **Needs hub v0.127.0** (the key registrar and the window endpoints; an older hub
answers 404 to `register-key` and the apply-bridge keeps retrying). No new household string.
- **The box never fetches the Storage Box password any more.** The apply-bridge (`offsiteapply`) sends its PUBLIC key
to the hub's registrar (`HubRegistrar`: `register-key`, `confirm-key`), which pins it in the sub-account to
`command="rclone serve restic --stdio --append-only <repo>",restrict`; the box then PROVES the key reaches the pinned
server (`PinnedProber`: exit 0 and rclone's output — an unpinned key gets the restricted shell, exit 8, measured)
before configuring anything. `HTTPConsumer`, `SSHCopyIDInstaller` and the `sshpass` path are gone. A box upgraded
from v0.288.0 re-applies once (`descriptorHash` gains `|pinned-v1`) and re-registers its EXISTING key.
- **Transport.** A hub-provisioned target (`Transport: "rclone-pinned"`, set by `ApplyOffsiteTarget`) uses restic's
`rclone:` backend with `-o rclone.program="ssh -p 23 … -i <key> … rclone"` — restic 0.14.0 suffices, rclone is NOT in
the image (it runs at the provider). An sftp-written repository reads, extends, restores and `check --read-data`s
through it (measured on the provider). The household's own SFTP NAS target is unchanged.
- **Retention leaves the box on the pinned tier (decision 68).** Both `forget --prune` sites (after a run; over quota)
go through `offsiteWindowRetention`: no window → nothing deleted; inside a hub-granted window the **fake-snapshot
guard (R-822)** refuses on any future-dated snapshot, any snapshot newer than the hub's bound, or a plan that would
remove a snapshot younger than 8 days; otherwise the OLDEST `max_remove` planned snapshots are forgotten by id and the
window is closed with counts. **Disagreement recorded:** the brief said abort when the plan exceeds a week's
removal; the first window after the interim legitimately does, so the box caps and takes the oldest instead.
- **Move-aside is the hub's** (`POST /offsite/move-aside`); **abandonment is deferred to the operator** on the pinned
tier — nothing deleted, `offbox_abandon_deferred` (operator-only) — because the key cannot delete (R-823).
- Transport failures of the `rclone:` backend (`error talking HTTP to rclone`) classify as transport.
- Bug found by the existing suite and fixed before release: the NAS move-aside path assigned a shadowed `newPath`.
- Tests: `offsiteapply` rewritten (fresh, upgraded, already-pinned, registered-but-not-pinned, wrong fingerprint,
host-key mismatch, idempotent, confirm failure); `offbox_window_test.go` (the lab's 13 future fakes refused; recent
removal refused; honest plan oldest-first capped; pinned run never forgets without a window; pinned move-aside asks the
hub; pinned abandonment defers). Red-proofs: `felhom.eu/documentation/audits/offsite-lock-build-2026-10-03/partC/`.
## v0.288.0 — remove tells the truth about the household's files (decision 67, R-800) (2026-10-02)
**MinAgent: 0.131.0** (unchanged). Needs hub v0.123.0 (unchanged). New string: `layout.userdata_marad` (both languages).