Record read-only launcher inspection trust prerequisite and caller inventory
Card: SAU-384
This commit is contained in:
@@ -10,7 +10,7 @@ Authority: [/docs/design/plugin-handover/design.md](/docs/design/plugin-handover
|
|||||||
2. Resolved rollback choice: **unsubscribing works; merely re-keying the registration does not**. An actual pre-best-effort session component, reading a registration written by the target component, ignores `best_effort` and sends history to its new ID. Rehearsal: unsubscribe = one barrier callback and no gateway-shaped replay; re-key = barrier plus historical replay. The test used the actual old manager and a native callback sink, not browser SSE. The runbook now makes unsubscribe mandatory, using the card's authorized option. Do not claim an ID rename is safe.
|
2. Resolved rollback choice: **unsubscribing works; merely re-keying the registration does not**. An actual pre-best-effort session component, reading a registration written by the target component, ignores `best_effort` and sends history to its new ID. Rehearsal: unsubscribe = one barrier callback and no gateway-shaped replay; re-key = barrier plus historical replay. The test used the actual old manager and a native callback sink, not browser SSE. The runbook now makes unsubscribe mandatory, using the card's authorized option. Do not claim an ID rename is safe.
|
||||||
3. **Closed in run 1369:** armed/exit-race delay-gate tests passed on real core with actual target WASM; replacement orchestrator readiness/one-owner/all-watch arming passed; actual old-manager/gateway rollback without re-registration reproduced unsubscribe safety and ID-only re-key replay. See [resume evidence](SAU-384-resume-1369.md). The delay/observation hooks were only in a disposable host copy, not the selected host artifact or committed code.
|
3. **Closed in run 1369:** armed/exit-race delay-gate tests passed on real core with actual target WASM; replacement orchestrator readiness/one-owner/all-watch arming passed; actual old-manager/gateway rollback without re-registration reproduced unsubscribe safety and ID-only re-key replay. See [resume evidence](SAU-384-resume-1369.md). The delay/observation hooks were only in a disposable host copy, not the selected host artifact or committed code.
|
||||||
|
|
||||||
Use the card's explicit **unsubscribe** rollback option; an ID rename is not a safe alternative. The remaining blocker is the actual external host launcher/native installation manifest. Read-only SSH credential request **055995a51608c57dd25b323bea731fcb** is pending; it grants no stop/restart permission.
|
Use the card's explicit **unsubscribe** rollback option; an ID rename is not a safe alternative. The remaining blocker is the actual external host launcher/native installation manifest. Read-only SSH credential request **055995a51608c57dd25b323bea731fcb** is approved, but connection was refused before authentication for an unknown Citadel host. Mediator must add the observed public host key, then resume inspection; workers may not change live config. See [run 1372](SAU-384-resume-1372.md). No new approval request or live stop/restart permission is needed/granted.
|
||||||
|
|
||||||
## What was built and exercised
|
## What was built and exercised
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# SAU-384 resume — run 1372
|
||||||
|
|
||||||
|
No live operation is authorized or performed. The existing rehearsal and target bundle are unchanged.
|
||||||
|
|
||||||
|
## Read-only launcher inspection: trust prerequisite
|
||||||
|
|
||||||
|
The existing card-duration SSH grant was approved; no new credential request was filed. `ssh.exec` to `citadel.vpn.surma.technology`, login `surma`, with the read-only command `uname -m; ps -eo pid,ppid,user,args | grep -E '([h]erdr|[s]ausage)'` was refused **before authentication/command execution** because the host is unknown. The refusal reported:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SHA256:Fj3jS6DuV9SAo4PVQl/hTLI9SZPqWDwEd7E5hemfFkE
|
||||||
|
citadel.vpn.surma.technology ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB8gP37Pnb3EyyQnkR2VdeJNzGU3OAuyJc3E3a8XpDaV
|
||||||
|
```
|
||||||
|
|
||||||
|
The SSH skill permits installing this observed key without another person approval, but this card explicitly forbids worker live-configuration changes. Therefore the **mediator** must add the observed line to `/config/known_hosts`, preserving existing entries, then resume this worker. Surma does nothing. No private key was requested or fetched. `ssh.hosts_status` confirmed there is no already-trusted Citadel alias. The preceding run already tried the preferred read-only systemd-web route: it cannot identify the Herdr panel/native installation boundary. Do not substitute Nexus credentials, forward another host's SSH agent, bypass host checking, or treat this as permission to stop anything.
|
||||||
|
|
||||||
|
After trust is installed: reuse the attached grant, inspect launcher/process parents/Herdr config read-only; pin actual world path, architecture, executable/runtime closure and event/completion stop/start interface; then build/rehearse that specific outer host swap in a disposable box. No live stop, restart, config change or deployment is part of the resume.
|
||||||
|
|
||||||
|
## Caller-store inspection (not a frozen live audit)
|
||||||
|
|
||||||
|
`evidence/resume-1372-caller-inventory.json` records a read-only observation via `cron.list`, `board.hook_list`, boot-file inspection and current-main schema inspection. All eight cron jobs currently have `next_run:null`; six are historical `session.send` jobs with the legacy inner `detach:true`. Convert their executable JSON fields once with the already-rehearsed cron procedure, preserving SQL IDs, schedule/outcome fields and prompt bytes. References to old RPCs *inside their prompt strings* are history/instructions, not nested executable configuration; do not rewrite or replay them.
|
||||||
|
|
||||||
|
Five board hooks were observed. Only `mediator-done` calls `session.send`; its `{session,text}` payload already fits the target contract without legacy detach/notify/interrupt fields. Target board supplies a fresh per-attempt input ID and follow-up kind. No rewrite is needed for that observed hook. Other hooks target mail/orchestrator and must remain intact.
|
||||||
|
|
||||||
|
The frozen operator audit must additionally include board `invariant_target.data` (an arbitrary RPC template without a read-only target-get API), hooks and historical `hook_attempts`, board subscriptions/batches, room workflow/action records, orchestrator run/skill-review/host-job records and target session event registrations if present. Distinguish resumable target inputs from old diagnostic snapshots and never infer safe replay from a stored call-looking string. Current schemas are pointers, not substitutes for predecessor decoding or the actual frozen bytes. This session does **not** claim that final audit complete.
|
||||||
|
|
||||||
|
## Evidence/checks
|
||||||
|
|
||||||
|
- SSH refusal/public trust metadata: `evidence/resume-1372-ssh-trust.json`. No secret/JWT is copied to artifacts.
|
||||||
|
- Existing box `tc-asa3yr` was inspected, not restarted. Executed controllers remain absent, including Python cache contents. Inspection log: `/logs/box/2026-10-31/tc-asa3yr-exec-803562803.stderr`, lines 1–40; the initial directory-list command returned 2 only because optional guessed directories did not exist, next inspection succeeded.
|
||||||
|
- Host worktree fetched origin and merged local `main`: already current at documentation commit `8bf2a3c661ead774689e508ed45f609b40f60dd1`. Initial merge used `target` instead of the typed `rev` argument and was rejected without changes; corrected call succeeded.
|
||||||
|
- JSON/caller/trust/manifest assertions and controller/cache-absence checks passed: `/logs/box/2026-10-31/tc-asa3yr-exec-666665822.stderr`. All 20 retained target file sizes/SHA-256 matched the updated manifest: `/logs/box/2026-10-31/tc-asa3yr-exec-3598104138.stderr`. No executable test/controller was written for these inline checks.
|
||||||
|
- No Rust/plugin behavior changed or rebuilt. Run 1369's forced-recompile workspace pass and builds 1600–1603 remain the relevant gates. Independent plugin recovery follow-ups remain independent.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# One-off handover operator runbook — blocked draft
|
# One-off handover operator runbook — blocked draft
|
||||||
|
|
||||||
Read [rehearsal/results](SAU-384-rehearsal.md) and [resume verification](SAU-384-resume-1369.md), the [authority](/docs/design/plugin-handover/design.md) and [approval gates](/docs/symphony/artifacts/SAU-356/plan.md). This is **not** authorization to execute. Workers must not perform these live steps. Mediator/orchestrator alone lands and executes.
|
Read [rehearsal/results](SAU-384-rehearsal.md), [resume verification](SAU-384-resume-1369.md) and [inspection prerequisite](SAU-384-resume-1372.md), the [authority](/docs/design/plugin-handover/design.md) and [approval gates](/docs/symphony/artifacts/SAU-356/plan.md). This is **not** authorization to execute. Workers must not perform these live steps. Mediator/orchestrator alone lands and executes.
|
||||||
|
|
||||||
## 0. Finish the installation manifest (no live mutation)
|
## 0. Finish the installation manifest (no live mutation)
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ Bundle: `/docs/symphony/artifacts/SAU-384/target-artifacts.tar.gz`.
|
|||||||
- Verify bundle hash against `bundle-sha256.txt`, then every extracted target file against `manifest.json`. This bundle contains target binaries/static assets and the one-file SDK patch, **not** a migration executable.
|
- Verify bundle hash against `bundle-sha256.txt`, then every extracted target file against `manifest.json`. This bundle contains target binaries/static assets and the one-file SDK patch, **not** a migration executable.
|
||||||
- Record the actual native service owner/launcher, its synchronous stop/start commands, automatic host restart mechanism, runtime closure and native architecture. Manifest fields are deliberately null until inspected. The bundled host is a local **aarch64-linux debug-profile, stripped** build of `e09c4f9f`; it has not been established as the right live-host installation package. Stop here on a mismatch; build/rehearse the right artifact rather than substituting an untested binary.
|
- Record the actual native service owner/launcher, its synchronous stop/start commands, automatic host restart mechanism, runtime closure and native architecture. Manifest fields are deliberately null until inspected. The bundled host is a local **aarch64-linux debug-profile, stripped** build of `e09c4f9f`; it has not been established as the right live-host installation package. Stop here on a mismatch; build/rehearse the right artifact rather than substituting an untested binary.
|
||||||
- Pin all old plugin hashes, full boot bytes, current SDK source hashes, caller configuration, and `/proc/*/info.json` inventory. Record active agent/tool processes and any external effects whose result is uncertain. Do not infer settlement from the last assistant text.
|
- Pin all old plugin hashes, full boot bytes, current SDK source hashes, caller configuration, and `/proc/*/info.json` inventory. Record active agent/tool processes and any external effects whose result is uncertain. Do not infer settlement from the last assistant text.
|
||||||
- Inventory executable caller payloads in cron jobs, boot and other saved callback/action/configuration stores using their predecessor schemas. History text mentioning an old RPC is not an executable payload. The tested converter covers `jobs.data` where `method == session.send`; it does not claim a full live caller-store audit. Unknown executable references, `session.work`, `session.cancel`, ambiguous `interrupt:true`, invalid text or unexplained notify destinations stop preflight for explicit resolution.
|
- Inventory executable caller payloads in cron jobs, boot and other saved callback/action/configuration stores using their predecessor schemas. History text mentioning an old RPC is not an executable payload. The tested converter covers `jobs.data` where `method == session.send`; it does not claim a full live caller-store audit. Run 1372 observed six historical legacy session cron jobs (all jobs have `next_run:null`) and one already-target-valid board session hook. See `evidence/resume-1372-caller-inventory.json`; the frozen audit must also cover board `invariant_target.data`, hook attempts/subscription batches, room/orchestrator workflow records and any session event registrations. Diagnostic call snapshots and RPC names inside prompt strings must not be rewritten/replayed as executable configuration. Unknown executable references, `session.work`, `session.cancel`, ambiguous `interrupt:true`, invalid text or unexplained notify destinations stop preflight for explicit resolution.
|
||||||
- Source references for predecessor formats: session `f9122585`, `src/main.rs` Paths (`pending.jsonl`, `cancel`) and `src/queue.rs`; cron `ba75c102`; target cron README's one-off conversion procedure. Active old component hashes are separately captured; do not equate a source reference with its compiled active binary without checking.
|
- Source references for predecessor formats: session `f9122585`, `src/main.rs` Paths (`pending.jsonl`, `cancel`) and `src/queue.rs`; cron `ba75c102`; target cron README's one-off conversion procedure. Active old component hashes are separately captured; do not equate a source reference with its compiled active binary without checking.
|
||||||
- Confirm the frontend artifact is approved commit `3d76026749a5d21722033bbfe8743ac368946b0f`; keep `publish:hold` until step 5. Do not publish a worktree snapshot or release it early.
|
- Confirm the frontend artifact is approved commit `3d76026749a5d21722033bbfe8743ac368946b0f`; keep `publish:hold` until step 5. Do not publish a worktree snapshot or release it early.
|
||||||
- Rollback uses the card's explicit **unsubscribe** option. ID-only re-key is **unsafe**, proven again with the actual old manager and gateway in run 1369. Prevent the gateway from re-registering `web-chat` against an old session binary; never call `web.start` in that state. A different proposed “re-key” needs its own defined semantics/rehearsal.
|
- Rollback uses the card's explicit **unsubscribe** option. ID-only re-key is **unsafe**, proven again with the actual old manager and gateway in run 1369. Prevent the gateway from re-registering `web-chat` against an old session binary; never call `web.start` in that state. A different proposed “re-key” needs its own defined semantics/rehearsal.
|
||||||
@@ -23,7 +23,7 @@ Run the one-off controller **outside the world and outside the service/process g
|
|||||||
|
|
||||||
Close the actual ingress and stop the **external host/service owner** synchronously using the pinned command. Await its shutdown/process-exit completion, not a loop over `/proc`, endpoint retry, sleep, or a set of stop requests. If an outer launcher would respawn the host, deliberately stop that owner too; do not edit boot config while agents can still run. `core.restart`/exit-75 is a restart request, not stop-all. The real core's `Host.stop` suppresses service restart admission and stops all trees in parallel. Design budgets are grace 5 seconds and separate EOF-stop 5 seconds, not arbitrary new timeouts.
|
Close the actual ingress and stop the **external host/service owner** synchronously using the pinned command. Await its shutdown/process-exit completion, not a loop over `/proc`, endpoint retry, sleep, or a set of stop requests. If an outer launcher would respawn the host, deliberately stop that owner too; do not edit boot config while agents can still run. `core.restart`/exit-75 is a restart request, not stop-all. The real core's `Host.stop` suppresses service restart admission and stops all trees in parallel. Design budgets are grace 5 seconds and separate EOF-stop 5 seconds, not arbitrary new timeouts.
|
||||||
|
|
||||||
The rehearsal's native external controller awaited `Host.stop`, asserted its process table was empty, then awaited host exit. The live equivalent needs the actual launcher identity from step 0. **That identity is currently missing; do not invent a unit name.** Source config has `services.sausage.enable = false` and describes a Herdr panel; read-only systemd-web inspection corroborates a user Herdr socket, not a system `sausage.service`. Credential request `055995a51608c57dd25b323bea731fcb` awaits approval for read-only inspection to pin the actual panel/launcher. It is not permission to stop or change it.
|
The rehearsal's native external controller awaited `Host.stop`, asserted its process table was empty, then awaited host exit. The live equivalent needs the actual launcher identity from step 0. **That identity is currently missing; do not invent a unit name.** Source config has `services.sausage.enable = false` and describes a Herdr panel; read-only systemd-web inspection corroborates a user Herdr socket, not a system `sausage.service`. Credential request `055995a51608c57dd25b323bea731fcb` is approved for read-only inspection, but SSH refused the unknown Citadel host before authentication. Mediator must install the observed public host-key line from `evidence/resume-1372-ssh-trust.json` in `/config/known_hosts` and resume inspection; worker configuration changes remain forbidden. No additional person approval is needed for that trust entry under the SSH skill. It is not permission to stop or change the launcher.
|
||||||
|
|
||||||
## 2. Back up frozen state and plan changes
|
## 2. Back up frozen state and plan changes
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user