docs: clarify Pi reload and update workflows

This commit is contained in:
2026-08-14 18:34:04 +02:00
parent 59a04123ea
commit a8623a2b18
4 changed files with 147 additions and 104 deletions
+47 -13
View File
@@ -65,6 +65,37 @@ this protection and are unsupported. Advanced documented Compose rendering must
`scripts/compose-with-preflight.sh` and include the same selector with `-f` when present; connector
secret overrides must never bypass that preflight wrapper.
## Reloading Pi configuration
Configuration reload is a separate lifecycle operation from an image update:
```text
thothctl --installation /absolute/path/thothii-installation.yaml pi restart --yes [--drain]
```
`--yes` is required after reviewing the planned core recreation. Restart activates the durable
maintenance gate before it checks sessions. Without `--drain`, active open sessions refuse the
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
recreated. Before reopening admission, it verifies health, the unchanged Pi version, the
provider/model/settings smoke, unchanged non-secret rendered configuration, the current image
identity, and the complete persistence-mount fingerprint.
Restart and update keep separate recovery state:
```text
<projectDirectory>/.thothctl/<installation-id>/restart-state.json
<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.
## Updating Pi
Every update requires a pinned version, an explicit source, and confirmation:
@@ -117,14 +148,16 @@ Recovery state and lock diagnostics live under:
```text
<projectDirectory>/.thothctl/<installation-id>/update-state.json
<projectDirectory>/.thothctl/<installation-id>/update-state.json.lock.owner.json
<projectDirectory>/.thothctl/<installation-id>/restart-state.json
<projectDirectory>/.thothctl/<installation-id>/*.lock.owner.json
```
The recovery file is mode `0600` and records transaction-scoped image identities, mount
fingerprints, target version/source, configuration digest, phase, and timestamp. It contains no
credentials, endpoint values, secret paths, Compose output, or logs. A cross-platform OS advisory
file lock serializes lifecycle operations; a crashed owner releases the lock automatically. Owner
metadata is diagnostic only and cannot wedge acquisition if empty, partial, or stale.
Each recovery file is mode `0600`. Update state records transaction-scoped image identities, mount
fingerprints, target version/source, configuration digest, phase, and timestamp; restart state
records the retained image and its verification inputs. Neither file contains credentials, endpoint
values, secret paths, Compose output, or logs. A cross-platform OS advisory file lock serializes
both lifecycle operations; a crashed owner releases the lock automatically. Owner metadata is
diagnostic only and cannot wedge acquisition if empty, partial, or stale.
Any post-candidate failure explicitly confirms or reactivates maintenance and rescans sessions
before compensation. Automatic rollback selects the transaction's previous image through the
@@ -149,13 +182,14 @@ thothctl --installation /absolute/path/thothii-installation.yaml pi maintenance
thothctl --installation /absolute/path/thothii-installation.yaml pi maintenance recover --yes
```
`maintenance recover` 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 `update-state.json`, repair the reported Docker/configuration issue, and rerun
rollback or maintenance recovery.
`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.
Missing confirmation, invalid arguments, active sessions, and an interrupted transaction exit
`2`. Docker and verification failures exit nonzero with concise, redacted guidance. Direct
+6
View File
@@ -2,6 +2,12 @@
Pi (il coding agent che orchestra il workflow NL→SQL) può risolvere un `provider/model` in tre modi diversi. Non sono alternativi: coesistono, e la scelta di quale usare dipende da **quanto è standard l'endpoint** e da **quanto deve essere ampia la visibilità** del modello (tutti i progetti vs. un progetto solo).
> **ThothII operator note:** ThothII runs Pi only in Docker Compose. Paths under
> `~/.pi/agent/` in this document describe Pi's container-side behavior. Operators edit
> `deploy/pi/models.json` and `deploy/pi/settings.json` in the ThothII project root and use
> the protected host credential file selected by `PI_AUTH_FILE`; they do not edit files inside
> the running container.
## Credenziali nel backend container
In produzione configurare una sola sorgente generica: il bundle `THT_SECRETS_FILE` con la voce
+79 -85
View File
@@ -1,88 +1,91 @@
# Pi management
Pi is pinned inside the ThothII `core` image. A local Pi, Node.js, Python, or Go installation is
not required. The browser can manage safe runtime settings, while the host-side `thothctl`
operator CLI performs container lifecycle and image updates. The core does not mount the Docker socket,
and there is no browser shell.
ThothII bundles Pi in the `core` image. Operators use the Pi Management page for safe application
defaults and the host-side `thothctl` CLI for lifecycle work. A local Pi installation is not
required; the core container does not mount the Docker socket and there is no browser shell.
In the commands below, replace `/absolute/path/to/thothii-installation.yaml` with the protected
installation descriptor created by the [local installation guide](local.md).
## Who can use Pi Management
On the loopback-only local profile (`AUTH_MODE=none`), the person using that PC can open Pi
Management and change installation defaults or run diagnostics. Do not expose ports 8080 or 8787
to another machine.
On a public server, Pi Management requires upstream authentication and a trusted administrator
claim supplied by the authenticated reverse proxy. Without that claim the API returns
`403 pi_management_forbidden`; ordinary users cannot change installation-wide Pi settings. Image
updates are never available from the web page on either profile.
## Use the Pi Management page
Open ThothII, choose **Pi Management**, and check the bundled version and readiness. The page:
- offers only supported provider, model, and reasoning choices;
- saves non-secret defaults;
- reports credentials only as present or missing;
- runs a bounded provider smoke test; and
- shows at most 200 sanitized log lines.
It never displays or accepts a credential, runs an image update, or opens a terminal. Per-user
browser preferences remain separate from installation defaults.
## Use thothctl
Set a short shell variable for the platform-specific executable. Examples below use macOS/Linux:
```sh
THTCTL=/absolute/path/to/thothctl
INSTALLATION=/absolute/path/to/thothii-installation.yaml
```
The complete Pi command set is:
## Choose application defaults
Use the **Pi Management** page to select the supported provider, model, and reasoning default, then
choose **Save defaults**. The page shows credentials only as present or missing and can run bounded
diagnostics; it never accepts or displays a credential, opens a terminal, or updates an image.
Alternatively, use the CLI from an administrator terminal:
```sh
"$THTCTL" --installation "$INSTALLATION" pi configure
"$THTCTL" --installation "$INSTALLATION" pi configure --provider zai --model glm-5.2 --thinking medium
```
Use GUI Save defaults or CLI `pi configure`, not both for the same change. The CLI's interactive
choices are restricted to supported models; non-interactive use must supply all three values.
Useful read-only checks are:
```sh
"$THTCTL" --installation "$INSTALLATION" pi status
"$THTCTL" --installation "$INSTALLATION" pi doctor
"$THTCTL" --installation "$INSTALLATION" pi test
"$THTCTL" --installation "$INSTALLATION" pi check
"$THTCTL" --installation "$INSTALLATION" pi configure
"$THTCTL" --installation "$INSTALLATION" pi configure --provider zai --model glm-5.2 --thinking medium
"$THTCTL" --installation "$INSTALLATION" pi logs
"$THTCTL" --installation "$INSTALLATION" pi maintenance status
```
- `pi status` reads the image-bundled version.
- `pi doctor` checks the version boundaries, core health, settings, and configured model.
- `pi test` runs the isolated Pi/core smoke; `pi check` is its alias.
- `pi configure` presents closed choices on a terminal. Non-interactive use requires all three
flags. Never pass a credential as an argument.
- `pi logs` returns a bounded, sanitized snapshot and deliberately has no follow mode.
- `pi maintenance status` reports whether new session admission is gated.
`pi check` is an alias for `pi test`; logs are a sanitized, bounded snapshot with no follow mode.
Use `thothctl status`, `doctor`, `logs`, `start`, `stop`, and `update --check-only` for the wider
installation. Direct Compose lifecycle commands can bypass the durable image selector and are not
the normal operator interface.
## Edit the provider catalog and enabled-model policy
## Handle credentials and secrets
Edit these project-root files in source control, then review and deploy the change through the
normal project process:
Keep provider credentials in the protected host file named by `PI_AUTH_FILE`, or in the documented
model secret file/bundle. Compose mounts protected material read-only under `/run/secrets` or at
Pi's protected auth path. Apply mode `0600` on macOS/Linux or a user-only ACL on Windows.
- `deploy/pi/models.json` is the provider catalog: provider endpoints and the models each provider
offers.
- `deploy/pi/settings.json` is the enabled-model policy and application defaults.
Never put secret text in the installation YAML, operator environment, workspace Git repository,
command arguments, browser, screenshots, tickets, rendered Compose, or logs. Pi configuration is
declarative: executable `!command` values are rejected. Use supported environment references or
the protected credential files.
These files contain configuration, not credentials. Keep provider configuration declarative: Pi
management rejects executable `!command` values. Do not edit generated files, the running
container, or a host-native Pi directory.
After rotating a credential, restart core through `thothctl stop` and `thothctl start`, then run
`pi doctor` and `pi test`. Do not print the file while troubleshooting.
## Store provider credentials
## Update and roll back Pi
`PI_AUTH_FILE` is a setting in the installation environment file (for example,
`deploy/env/local.env`). Its value is the absolute path of the protected host credential file that
this installation selects. Docker Compose mounts that selected file read-only for Pi.
Other declared protected material is likewise mounted read-only under `/run/secrets`.
Finish or close active work first. A build update uses source already present in this checkout:
Set restrictive permissions on the host file (`0600` on macOS/Linux or a user-only ACL on Windows).
Never put its contents in installation YAML, Git, command arguments, the browser, screenshots,
tickets, rendered Compose output, or logs. Do not print the file while troubleshooting.
## Reload changed configuration
After changing the provider catalog, enabled-model policy, or selected credential file, reload the
running application with one confirmed restart:
```sh
"$THTCTL" --installation "$INSTALLATION" pi restart --yes --drain
```
`--yes` confirms that core will be recreated. Without `--drain`, restart refuses active sessions;
with it, ThothII closes admission and waits for active sessions to finish without terminating them.
The wait is bounded. Restart retains the current image: it does not build, pull, select, or upgrade
an image. It will restart only core, then verifies health, Pi version, settings/model smoke,
non-secret rendered configuration, and persistence mounts before reopening admission.
Use `pi restart --yes` when there are already no active sessions. Do not substitute `thothctl stop`
and `thothctl start` or raw Compose commands for this reload workflow.
## Update the bundled Pi version
`pi update` is for a new bundled Pi version; it is not a configuration reload. Finish or drain
active work, then choose an explicit source and version. A build update uses this checkout:
```sh
"$THTCTL" --installation "$INSTALLATION" pi update \
@@ -98,29 +101,25 @@ A registry update must use an immutable digest, never a mutable tag:
--yes --drain
```
The operation gates new sessions, records non-secret recovery state, recreates only `core`, checks
the requested version, health, settings, smoke request, configuration, and persistence mounts,
then promotes the verified image. Frontend and named volumes are preserved.
Update keeps new-session admission gated while it builds or pulls a candidate, recreates only
`core`, verifies it, and promotes the image only after success. It preserves the frontend and named
volumes.
To restore the image recorded by the interrupted or latest update:
## Recover a failed lifecycle operation
```sh
"$THTCTL" --installation "$INSTALLATION" pi rollback --yes
```
## Recover a failed update
Do not delete `.thothctl`, `update-state.json`, `current-image.yaml`, containers, or volumes. First
inspect the durable gate and sanitized logs:
If a restart or update fails after core recreation, leave maintenance enabled and preserve the
reported recovery state. Do not delete `.thothctl`, state files, containers, or volumes. Inspect
status and sanitized logs, then restore the previous image when an update is involved:
```sh
"$THTCTL" --installation "$INSTALLATION" pi maintenance status
"$THTCTL" --installation "$INSTALLATION" pi status
"$THTCTL" --installation "$INSTALLATION" pi logs
"$THTCTL" --installation "$INSTALLATION" pi rollback --yes
```
If rollback reports a terminal or stale maintenance state, repair the reported Docker, disk, or
configuration problem, then run:
Repair the reported Docker, disk, or configuration problem, then have ThothII complete the safe
recovery path:
```sh
"$THTCTL" --installation "$INSTALLATION" pi maintenance recover --yes
@@ -128,19 +127,14 @@ configuration problem, then run:
"$THTCTL" --installation "$INSTALLATION" pi test
```
If recovery still fails, leave maintenance active and preserve the recovery file. Collect only
sanitized `pi logs`, `status`, and `doctor` output for support; do not ungate the installation by
editing state files.
`pi rollback --yes` restores the prior update image. `pi maintenance recover --yes` checks both
restart and update recovery state before it can reopen admission. If either command fails, keep the
installation gated and collect only the sanitized diagnostics.
## Direct support access
Raw Compose access is unsupported: there is no public operator command that safely reconstructs
the installation's hashed project name, project directory, environment file, optional overrides,
and durable current-image selector for ad-hoc Pi execution. Do not approximate those arguments or
delete/edit lifecycle state for support.
Route direct executable/version checks through `thothctl pi status`, and collect diagnostics with
`thothctl pi doctor`, `thothctl pi test`, and `thothctl pi logs`. These commands are
installation-aware and redact declared secret values. Share only their sanitized output. Do not
run package installers, alter Pi files inside the live container, mount the Docker socket, expose
a browser shell, or use a host Pi as a substitute.
Raw Compose access is unsupported because it can bypass the installation-specific environment and
durable image selector. For support, use the installation-aware `thothctl pi status`,
`thothctl pi doctor`, `thothctl pi test`, and `thothctl pi logs` commands. Do not run package
installers, alter files inside the live container, mount the Docker socket, expose a browser shell,
or use a host Pi as a substitute.
+15 -6
View File
@@ -1136,12 +1136,12 @@ verify_pi_management_guide() {
return 1
}
require_headings "$guide" "Pi management guide" \
"Who can use Pi Management" \
"Use the Pi Management page" \
"Use thothctl" \
"Handle credentials and secrets" \
"Update and roll back Pi" \
"Recover a failed update" \
"Choose application defaults" \
"Edit the provider catalog and enabled-model policy" \
"Store provider credentials" \
"Reload changed configuration" \
"Update the bundled Pi version" \
"Recover a failed lifecycle operation" \
"Direct support access"
require_text "$guide" "Pi management guide" \
"pi status" \
@@ -1149,6 +1149,11 @@ verify_pi_management_guide() {
"pi test" \
"pi check" \
"pi configure" \
"pi restart --yes --drain" \
"restart only core" \
"deploy/pi/models.json" \
"deploy/pi/settings.json" \
"PI_AUTH_FILE" \
"pi update" \
"pi rollback --yes" \
"pi maintenance status" \
@@ -1158,6 +1163,10 @@ verify_pi_management_guide() {
"Raw Compose access is unsupported" \
"no browser shell" \
"does not mount the Docker socket"
if grep -Fq '~/.pi/agent/' "$guide"; then
echo "Pi management guide must not direct ThothII operators to native Pi paths" >&2
return 1
fi
node - "$guide" <<'NODE'
const fs = require("fs");
const source = fs.readFileSync(process.argv[2], "utf8");