10 KiB
Disposable handover rehearsal — SAU-384
Authority: /docs/design/plugin-handover/design.md, Rollout; /docs/symphony/artifacts/SAU-356/plan.md, Approval and operator gates.
Status: blocked, not a live execution approval. Rehearsal evidence and the reviewed target bundle are under /docs/symphony/artifacts/SAU-384. No shipped plugin or host behavior changes on this branch. The temporary migration implementation and native controller were executed only in a throwaway box and deleted after the successful migration verification. Their hashes/deletion record and source-as-log remain, not an executable migration tool.
Required resolution before completing the kit
- Pin the actual external host launcher/service owner, stop/start interface, host architecture and runtime closure. Those are not projected into this world. The supplied local native artifact is aarch64-linux, dynamically linked to the Nix paths printed in the build evidence; it is NOT a verified live-host package. Do not guess a systemd unit, use
core.restartas stop-all, or install a mismatching binary. - Correct the rollback alternative: 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_effortand 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. Either make unsubscribe mandatory, or specify what stronger meaning of “re-key” is intended. Do not claim an ID rename is safe. - Complete remaining integrated acceptance: deterministic manager armed/exit-race injection on real core (the real callback-boundary sequence and primitive watch tests are not that injection), replacement orchestrator readiness after the observed upgrade, and old-manager/gateway rollback without re-registration. The old orchestrator's exit preceded the core's replacement service-start event; the immediate process snapshot still had no new owner, so readiness is not claimed.
The safe unsubscribe option can be selected without inventing compatibility code. The runbook nevertheless withholds a live-ready claim until the card's rollback wording and host installation manifest are unambiguous.
What was built and exercised
- Host source
e09c4f9f0ef6b5833d6be066771eecd9e0a1f572. Disposable Nix build, native workspace suite passed after correcting the cold SDK-probe dependency cache. Target native binary was built and stripped, not released/deployed. CLI--versionpassed. Native controller used the realsausage::Host, real VFS, watches, locks, service supervisor and WASM execution; model/skills/memory/ledger/push effects were synthetic or loopback only. - Reviewed session
cb844151/ SAU-409 final; orchestratorc80a5854/ SAU-408; webd883fbf2/ SAU-403; agent/board retained reviewed components. Fresh card-worktree builds: mail 1600 / 53 tests, cred 1601 / 272, cron 1602 / 24, rooms 1603 / 59, all passed. No activation. Component/source provenance and every bundled file hash are inevidence/manifest.json. - Frontend is exactly approved commit
3d76026749a5d21722033bbfe8743ac368946b0f, retained production build from SAU-375 rework-1318. It remainspublish:hold; no publication was attempted. - World SDK runtime sources already matched the selected host SDK. The only needed source-copy delta is
src/lib.rs, documenting effective grace. Preserve world-owned Cargo manifests, relocatedinterface, and imports. A first broad SDK-copy attempt incorrectly included repository-relative Cargo paths; comparison caught this before any live change, and the final migration used only the one-file patch. Never copy the repository's SDK Cargo manifests over the world SDK. - Accepted SAU-362 byte snapshot: 1,491 sessions / 580,355,405 bytes, including 70,689,796-byte default history. Pristine snapshot remained unpreopened. Executable clones used synthetic model settings; their historical byte volume was retained. Source snapshot consistency is per-file, not a transactional live snapshot.
Successful checks and limits
| Check | Evidence/result |
|---|---|
| Old ownership → stop-all → offline swap → target boot | Old mail.start, old session send and detached ledger processes inventoried. Native external controller awaited Host.stop, verified zero remaining processes and host exit, then backed up/transformed/swapped. Final shutdown 0.0958 s in this fixture. One target manager, no mail deliverer, cred locked. |
| Partial swap + rerun | Injected interruption after operation 3; hash-guarded completion and repeated installed-phase apply preserved all 4,374 non-target inventoried files. No live/new work reset. |
| Exact losses/preservation | Only pending.jsonl, cancel, and unclaimed pending non-Surma delivery rows selected for removal. Original mail messages, done/Surma copies and uncertain unknown deliveries retained without replay; scheduled SQL IDs, calendar/outcome fields and non-session JSON bytes retained. Synthetic grant DB bytes preserved. Loss inventory backs every removed file/row. |
| Offline failure boundaries | Before-start rollback restored exact bytes; conflicting outside edits refused; ambiguous legacy interrupt:true refused without mutation. After-start apply and whole-world rollback both refused. |
| Default/advisor HTTP replay | Three identical same-ID POSTs each, before/after consumption; exactly one answered run per session. Default returned null on repeats; advisor returned its same receipt. |
| Explicit open target run | A run-start/consumed record with a finished-looking assistant tail, but no run-end, recovered under the same agent-run UUID, with one start. Legacy finished-looking history alone produced no target event/run. |
| Real VFS/runner-boundary work | Actual SDK armed then plugin-write changed; five follow-ups published at durable callback/runner-end boundaries produced five distinct runs, each consuming its one ID. Does not force the exact armed-exit seam. |
| Real core detached errors | Full nested error data survived a detached core.call. |
| Real cron research deadline | 305.427 s send→stopped in the final gate; real cron invoked warning and Stop. The 305-second test deadline is the existing 300-second warning interval plus design grace 5 seconds, not a new default. Held inference was cut, no follow-up run. Original configured research default remains 1,200 seconds. |
| Effective grace / crash supervision | Passing native host suite exercises real WASI uniform-grace and before/after-readiness crash-supervision fixtures. Deliberate core.kill is NOT a crash: it disables that boot service; an initial rehearsal expecting its restart failed, correctly, and was replaced by the existing crash tests. |
| Orchestrator upgrade/idle | Real file-watcher upgrade, FIFO singleton release, old exit before one replacement start event. Paused empty-board/live-size-world host CPU 0.02 s / 20.0002 s ≈ 0.10%. This is whole-host idle CPU, not per-plugin CPU or live active-work load. Replacement readiness remains unverified. |
Live-size latency after real records exist
After producing actual run-start/run-end/mailbox-consumed records, subsequent full boot measured 0.544 s from manager service-start to the next boot service-start (includes discovery/ack overhead). Narrow registration catch-up samples ranged 0.0239 s to 12.0419 s in the integrated world: the long sample coincided with other synthetic recovery/surfacing work, and the untagged sink cannot isolate attribution. Do not present this as a bounded manager-only benchmark.
The clean final live-size end-to-end gate measured manager acknowledgement 0.6078 s, registration catch-up 0.0128 s, and mail.send publication to default 0.5376 s. The integrated post-record mail sample was 0.5235 s. Both publication samples are below the existing orchestrator 3 s and cred 10 s caller budgets (SAU-400 report cites the originating SAU-366 review). These warm-cache synthetic-loopback real-core observations are not live latency guarantees. First scanning still delays first new input after the fast boot acknowledgement.
Evidence and failures
All following logs are under /logs/box/2026-10-31/:
- Full workspace pass:
tc-asa3yr-exec-2320283969.stderr. First cold-cache/full-load failure:tc-asa3yr-exec-158345583.stderr, missing offline async-task and a queued-build timing test. Populated the separate SDK-probe cache; entire suite then passed unchanged. - Final stop/swap/start:
tc-asa3yr-exec-1922130515.stderr; offline fault/grant preservation:tc-asa3yr-exec-616022371.stderr. - Final live-size HTTP/deadline gate:
tc-asa3yr-exec-1243993190.stderr. Earlier malformed mailtoscalar, 30-second startup observation bound and blank JSONL parser mistakes were harness errors; corrected to a sequence, existing 120-second test budget and blank-line skipping. Final gate passed. - Open-run recovery and boundary runs:
tc-asa3yr-exec-903419814.stderr(subsequent console-watch attempt failed). A console is not a running watch caller; the final SDK guest watch passed intc-asa3yr-exec-3261552495.stderr. Same log retains the real upgrade trace and idle sample. An identical already-acknowledged registration correctly produced no second catch-up; the final probe used a fresh registration identity. - Actual old-manager unsubscribe/re-key comparison:
tc-asa3yr-exec-3307393394.stderr. - Native artifact architecture/runtime paths:
tc-asa3yr-exec-899103518.stderr; bundle build/CLI:tc-asa3yr-exec-1075679130.stderr. - Executed temporary tool and controller as log only, followed by deletion proof:
tc-asa3yr-exec-2902726782.stderr(31,475 bytes).evidence/tool-deletion.jsonlists removed executables. No transition code was put in a shipped plugin.
The initial broad-copy fixture and earlier failed tests are not the final kit. evidence/migration-plan.json identifies the final verified migration. Provider billing/cancellation, power loss, hung host filesystem behavior, physical browsers and independent per-plugin recovery follow-ups are not claimed complete. No live DB was opened; the accepted session snapshot was reused. No live config/SDK change, stop, activation, release, restart, push, deployment or /www write occurred.
See operator runbook for approval gates and the deliberately blocked live steps.