fix: close Pi management final review findings

This commit is contained in:
2026-08-14 20:15:21 +02:00
parent 225d13cd75
commit 900faad983
13 changed files with 621 additions and 71 deletions
+26 -18
View File
@@ -78,10 +78,13 @@ maintenance gate before it checks sessions. Without `--drain`, active open sessi
command. With `--drain`, the command polls the authenticated session inventory until no active
sessions remain; it never terminates sessions and the wait is bounded.
Restart retains the exact current image and does not build, pull, select, tag, or upgrade an image.
It recreates only `core` with `--no-deps --force-recreate`; `frontend` and named volumes are not
Restart retains the exact current image and never builds, pulls, or upgrades an image. Before any
core mutation, it tags the captured running image ID with a transaction-scoped reference and
selects that reference through a lifecycle-only Compose override. A configured mutable tag moving
after capture therefore cannot change the restarted image. It recreates only `core` with
`--no-deps --force-recreate --no-build --pull never`; `frontend` and named volumes are not
recreated. Before reopening admission, it verifies health, the unchanged Pi version, the
provider/model/settings smoke, unchanged non-secret rendered configuration, the current image
provider/model/settings smoke, unchanged non-secret rendered configuration, the captured image
identity, and the complete persistence-mount fingerprint.
Restart and update keep separate recovery state:
@@ -91,10 +94,13 @@ Restart and update keep separate recovery state:
<projectDirectory>/.thothctl/<installation-id>/update-state.json
```
The files are mode `0600` and share one installation lifecycle lock, so a restart cannot race an
update. A restart refuses an incomplete update or restart state. After core mutation, a failure
leaves admission gated and preserves `restart-state.json`; the operator must use status/logs and
maintenance recovery rather than deleting state files.
The files are mode `0600` and share one installation lifecycle lock, so restart, update, and
rollback cannot race. Every mutating lifecycle command checks both files. Malformed or non-terminal
restart recovery state blocks update and rollback; malformed or incomplete update recovery state
blocks restart. A verified terminal restart state is cleaned up safely before a later mutation.
After core mutation, a restart failure leaves admission gated and preserves both
`restart-state.json` and its exact-image override; the operator must use status/logs and maintenance
recovery rather than deleting recovery material.
## Updating Pi
@@ -139,7 +145,7 @@ files and never deletes the durable selector.
Only `core` is recreated, with `--no-deps --force-recreate`; `frontend` is not recreated and no
volume-replacement flags are used. Verification checks health; exact requested Pi version at all
three declared boundaries (the candidate executable, `PI_VERSION` environment, and
`org.opencontainers.image.version` image label); the provider/model/settings smoke; unchanged
`io.thothii.pi.version` image label); the provider/model/settings smoke; unchanged
non-secret rendered configuration; and the complete persistence-mount fingerprint.
## Recovery, rollback, and maintenance cleanup
@@ -175,8 +181,9 @@ For a failed update with `update-state.json`, first run:
thothctl --installation /absolute/path/thothii-installation.yaml pi rollback --yes
```
Rollback operates on update state only. A failed restart with `restart-state.json` retains its
current image and has no candidate image to roll back; first inspect status and logs, repair the
Rollback restores the image recorded in update state, but it checks restart state before making any
change. A failed, pending, or malformed restart state rejects rollback. A failed restart retains its
captured image and has no candidate image to roll back; first inspect status and logs, repair the
reported problem, then use maintenance recovery.
Inspect and clean a stale durable gate with:
@@ -186,14 +193,15 @@ thothctl --installation /absolute/path/thothii-installation.yaml pi maintenance
thothctl --installation /absolute/path/thothii-installation.yaml pi maintenance recover --yes
```
`maintenance recover` verifies and removes an interrupted restart state before it processes update
state. It completes an interrupted verified-image promotion, safely finalizes a preparation
interrupted before core mutation, and refuses other pending mutations. For terminal or absent
recovery state, it removes only a stale transaction override, verifies the running installation
when the gate is active, and only then removes the durable marker and reopens admission. It never
removes `current-image.yaml`. If rollback or recovery fails, leave the marker in place, preserve
the relevant recovery state, repair the reported Docker/configuration issue, and rerun rollback or
maintenance recovery.
`maintenance recover` restores the captured restart image pin and lifecycle override when needed,
verifies and removes interrupted restart recovery material, and only then processes update state.
It completes an interrupted verified-image promotion, safely finalizes a preparation interrupted
before core mutation, and refuses other pending mutations. For terminal or absent recovery state,
it removes only a stale transaction override, verifies the running installation when the gate is
active, and only then removes the durable marker and reopens admission. It never removes
`current-image.yaml`. If rollback or recovery fails, leave the marker in place, preserve the
relevant recovery state and override, repair the reported Docker/configuration issue, and rerun
rollback or maintenance recovery.
Missing confirmation, invalid arguments, active sessions, and an interrupted transaction exit
`2`. Docker and verification failures exit nonzero with concise, redacted guidance. Direct