harden Phase 2B Stage 1 installation state

This commit is contained in:
makearmy 2026-07-12 22:34:04 -04:00
parent 82e64cec43
commit df6b53e639
10 changed files with 1062 additions and 20 deletions

View file

@ -2,11 +2,8 @@
Do not remove Phase 1 identity/workspace, Phase 2A packages, kernels, snapshots, production resources, or unrelated nftables objects.
1. Stop `user@1200.service`; confirm UID 1200 has no processes. This is the only user-manager stop in scope.
2. Stop `le-app-codex-netns.service`. Its `ExecStop` removes only `lecodex-host` and `/run/netns/le-app-codex` and deletes only the two `le_app_codex*` nftables tables.
3. Remove only the Phase 2B files enumerated in `MANIFEST.sha256` and `/etc/le-app-codex-runtime/OPERATOR-INPUTS-APPROVED`, preserving the pre-existing `/srv/le-app-codex` skeleton.
4. Run `systemctl daemon-reload` and `systemctl reset-failed le-app-codex-netns.service`.
5. Confirm there is no UID 1200 process, socket, namespace, veth, project nftables table, containment/resource drop-in, launcher, Docker user unit, daemon/client config, or Phase 2B test copy.
6. Confirm lingering is still disabled and production/rootful Docker remains healthy and unchanged.
For Stage 1 rollback, run only `tests/31-rollback-stage1.sh` from a clean artifact worktree whose `MANIFEST.sha256` digest matches the authoritative state generation. The current branch may have later unrelated commits. Rollback accepts verified `IN_PROGRESS` or `COMPLETE`, uses the allowlist parser shared through `tests/stage1-state-lib.sh`, and refuses operation unless the approval marker, user manager, UID-1200 processes, socket, namespace, and project nftables tables are absent. Before removal it atomically renames the whole Stage 1 transaction subtree to a retryable cleanup tombstone. A retry accepts already-removed entries and re-verifies and removes any matching entries that remain. It removes only recorded matching payload/temporary files and created or pending directories; a `COMPLETE` record requires all 16 files. Shared parents recorded as pre-existing are never removed or altered. Immutable authoritative state remains intact through all payload and directory removals and while unreferenced state is cleaned; its manifest and checksum are removed only in the final cleanup phase.
If a file existed before Phase 2B, stop: this rollback package intentionally has no overwrite/restore path because installation must have failed closed on pre-existence.
Later-stage rollback, after explicit runtime activation, is separate: stop the user manager and namespace first, then verify the runtime is inert before using a stage-appropriate reviewed rollback. Stage 1 rollback must never be used after the approval marker is created or any namespace/firewall/runtime component has been activated.
If a destination file existed before Phase 2B, stop: Stage 1 has no overwrite/restore path and fails closed on pre-existence.