Source update completion ownership
Phase seam
The command process owns admission, the update lock and output lifetime, pre-update
inventory, all-profile snapshots, gateway pause, Git selection/stash/restore and
syntax/HEAD guards, and the ZIP download/stage/dirty recheck/release graft/swap.
It imports the completion transport before swapping code. Once the final tree is
selected (including upstream merge), Git, already-current retry and ZIP all send
one versioned JSON request to update_completion.py from that tree. No cached
application module is evicted or reloaded in the command process.
The request carries canonical source/home, desktop product selection, interactive and gateway mode, pre-update version, active and sibling snapshot identifiers, serialized runtime plan, open receipt identity/data and paused-Windows token. It contains data, never callables or pickles. stdin stays inherited for interactive configuration prompts; gateway mode retains its non-interactive behavior. Child output stays visible and is mirrored by the parent's update output stream.
New-code owner
A stdlib-only entrypoint starts using the available Python with -I -S, so no
old site-packages or executable .pth files initialize. A private bytecode-cache
prefix fences stale cache files before any new-checkout imports. Its explicit
import path points at the new checkout. It calls the new PM interface to prepare the
recorded dependency union, then starts the selected Python with the new activation
environment. That interpreter also starts with site initialization disabled,
then the runtime owner leases and activates its selected generation before any
application imports. Only that interpreter imports application completion code. The same
receipt/correlation identity crosses this preparation boundary (including PM
results). Selected-Python completion owns launcher publication, builders, cache
invalidation, all-profile configuration/state/skills maintenance, process scans,
fleet restart, Windows resume, dashboard deduplication and verification.
The existing per-kind restart and abort-recovery algorithms remain; transient supervisor/process failures are real even without mixed-generation imports. Only the purge/reload workaround and independent retry/ZIP tail compositions disappear. Gateway exit status is written before a restart can terminate the updater's cgroup, and is demoted on later failure. Verification publishes the final receipt.
Parent lifecycle and failures
The parent waits and propagates the child's exact nonzero result (a signal is mapped to shell-style 128+signal). A child cannot succeed by merely exiting zero: a terminal response with the matching receipt identity is required. The response returns the mutated Windows token so the parent's registered emergency resume does not repeat completed work. Normal parent completion performs no maintenance.
The parent retains its original receipt until acknowledged child finalization;
missing/failed child output leaves it available to the existing command-boundary
failure finalizer. The stdlib bootstrap returns correlated PM failure data even
when application imports are unavailable, and normalizes negative signal exits
at each process boundary. POSIX completion owns a new session/process group;
cancellation kills that group before releasing the lock (Windows uses the retained
child's taskkill /T tree). The parent records the pending fleet obligation before
starting the completion process, including when preparation cannot begin. The parent's emergency Windows resume remains a last-resort
lifecycle obligation when the child cannot execute or is killed. A failed child
never clears the pending fleet obligation. No automatic code rollback after
maintenance has begun (SQLite snapshots remain file-loss recovery, not rollback).
Historical surface
All names frozen from the complete reachable shipped updater history stay
resolvable. Historical dependency hooks retain the stdlib-only takeover bridge:
the old parent waits, carries receipt/recovery state and never resumes a retired
installer. Newly retired preparation and module-reload hooks explicitly marked
incomplete stop nonzero and request hermes update again; they cannot manufacture
a missing completion request. Current Git/current/ZIP callers use only the
canonical completion transport, not the historical takeover entrypoint.
Unfrozen branch-only retry compositions are deleted, not shimmed. ACP convenience
publication uses the launcher owner's expose_cli; the historical ACP entry is
only an adapter, never a second writer. The frozen set is never trimmed or replaced
with tag-only coverage. New current-path imports are unioned with that history.
Verification
Use isolated homes, disposable Git repositories and fake dependency/build/service adapters only. Exercise an old process with cached incompatible modules across a real Git transition to new code, selected-Python execution, receipt identity and snapshot transfer, nonzero/abrupt child exit, lock release and Windows-token return. Focused existing tests cover dirty ZIP checks/grafts, snapshots, fleet reconciliation, supervisor timing and historical imports. Native service restart and Windows/macOS acceptance remain separate required lanes; no live user service or user state is touched by this implementation's test runs.