Expand description
SPEC_LAUNCHER_TEARDOWN_BACKSTOP_2026_07_11 Phase 2 — the armed J0 teardown state machine.
Disarmed ──(PoolDrained / OrphanInstance drift)──▶ Armed(t0)
Armed ──(host exits — supervisor disarms)─────▶ Disarmed
Armed ──(any WindowOpened event)──────────────▶ Disarmed
Armed ──(t > t0+GRACE and ≥2 unanswered probes)▶ TeardownConsumes Phase 1’s ui_liveness telemetry: the decision to tear down
requires BOTH the grace period elapsing since arming AND the UI-thread
prober reporting ≥ N consecutive unanswered probes — a wedged UI thread
cannot answer, and transport failures never count as misses (the prober
retracts probes whose SEND failed, so silence here is genuinely
UI-thread evidence, not pipe evidence).
Arm/disarm are driven from ipc::server’s post-reducer event hook
(validated events only — same layering as the Phase 1 transport-side
ReportUiThreadAlive intercept: this is process-supervision state about
the host, not domain state the reducer owns). The supervisor’s select
loop polls should_teardown on a low-rate tick and, on true,
TerminateJobObject(J0)s the tree — the one deliberate exception to
“never kill what a saga can reconcile”: zero user windows remain and the
UI thread is provably dead, so there is nothing left to reconcile.
False-positive guards (spec §Phase 2), and where each lives:
- Startup: nothing arms until a drain/orphan event, which requires a registered host that already opened (and closed) a user window.
- Crash-restart gap: the supervisor disarms on every host exit; the machine can only re-arm from a fresh drain report by the NEW host.
- Crash-reproject: reproject re-opens windows within the grace; the
mirror’s
WindowOpenedevent disarms. - Probe transport failure:
ui_liveness::retract_probekeeps failed sends out of the consecutive-miss count entirely.
Like ui_liveness, all logic lives on the struct (unit-testable with an
injected clock); the module-level functions delegate to one
process-global instance.
Structs§
Constants§
- TEARDOWN_
GRACE - Grace period between arming and the earliest possible teardown. An order of magnitude above the slowest healthy quit observed (multi-window with pool sweep: ~2-5s), far below “user annoyed”.
- TEARDOWN_
REQUIRED_ MISSES - Consecutive unanswered UI-thread probes required (on top of the grace) before the host counts as wedged. At the Phase-1 probe rate (60s) this bounds worst-case wedge→teardown latency to roughly GRACE + 2 probe intervals — the spec’s stated verification envelope.
Functions§
- arm
- See
TeardownBackstop::arm. Process-global instance. - cell 🔒
- disarm
- See
TeardownBackstop::disarm. Process-global instance. - should_
teardown - See
TeardownBackstop::should_teardown. Process-global instance, evaluated against the spec constants and the live probe-miss count.