docs(agent): D1 — README self-update section, REUSE, CHANGELOG v0.70.0, CONTEXT
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -1,3 +1,33 @@
|
||||
## v0.70.0 — agent self-update (operator-signed, A/B slots, crash-loop auto-rollback) (2026-07-05)
|
||||
|
||||
Closes the update asymmetry: the root-adjacent agent was updated by manual SSH binary-replace while
|
||||
the lower-stakes controller already auto-updates. Design provenance:
|
||||
`felhom.eu/documentation/audits/SPIKE-agent-selfupdate-2026-07-05.md` (SF-findings binding). Core
|
||||
principle (as with the controller swap): the thing that performs rollback is never the thing being
|
||||
updated — here systemd + an ~80-line root wrapper.
|
||||
|
||||
- **Trust model:** an update is an operator-signed `agent_update` op (new `reconcile.ClassAgentUpdate`,
|
||||
always Destructive) through the existing signed-jobs pipeline; the signed params pin version + sha256,
|
||||
so the sha is the ONLY integrity root (hub = dumb transport, Gitea = dumb storage — neither can
|
||||
substitute a binary). `felhom-opsign -op agent_update -agent-version <v> -sha256 <hex>`.
|
||||
- **Host artifacts** (`configs/`): `felhom-selfupdate-guarded` (apply/commit/rollback — root re-verify,
|
||||
path confinement, same-fs assert, `.prev`, atomic mv, pending marker, detached restart [SF-6];
|
||||
rollback pending-guarded [SF-1]); `felhom-agent-rollback.service` (OnFailure oneshot);
|
||||
`felhom-agent-limits.conf` ([Unit]-only drop-in [SF-3] with the spike's tuned 120s/4 [SF-2] +
|
||||
OnFailure=); `FELHOM_SELFUPDATE` sudoers alias.
|
||||
- **Go** (`internal/selfupdate/`): `Executor` (download → verify vs signed sha → `sudo -n` wrapper
|
||||
apply; job completed after verify+download, before apply); `Manager` (startup dwell → `commit`;
|
||||
version-mismatch → no-commit + WARN + marker-left; report seam `SelfUpdatePending()`). Wired as a
|
||||
3rd executor-chain element + a `MaybeCommit` goroutine after core init. `SelfUpdateConfig`
|
||||
(url_template/creds/dwell, Token redacted). Additive report fields `selfupdate_pending(+version)`
|
||||
(omitempty → cross-repo golden contract byte-stable, no hub change). 3 non-critical capability probes.
|
||||
- **felhom.eu:** `felhom-host-install.sh` installs the wrapper + rollback unit + drop-in on day-0
|
||||
(self-update from birth); agent README "Self-update" section.
|
||||
- Tests: executor (happy / sha-mismatch + companion / bad-params / wrapper-fail), gate ride-along
|
||||
(agent_update rides the LOCKED gate: pinned-key executes, non-pinned + retarget rejected), commit
|
||||
(dwell-commit / version-mismatch / no-pending / shutdown), opsign, classify. Wrapper covered by
|
||||
shellcheck + the live crash-rollback drill. Full `go test ./...` green.
|
||||
|
||||
## v0.69.0 — S5: host-loss DR — recovered WG-key install + directive→restore-PLAN (safe halves) (2026-07-04)
|
||||
|
||||
The two safe, non-destructive mechanical links for host-loss DR (the destructive in-place restore is
|
||||
|
||||
Reference in New Issue
Block a user