Skip to content

Runtime lifecycle debt (from the 2026-07-01 audits)

The full audits live at git e5eae6229 (var/audit-{runtime,backend,client}.md, since removed from the tree). This register carries the actionable findings so they survive the refactor. None of them block the RFC's M-steps; the M-step column marks where the refactor already rewrites the file — fixing there avoids double churn.

# Finding Principle Evidence Opportunistic M-step
1 No deadline on the remote authority-server link: reqwest::Client::new() without timeouts; every post_link + the SSE subscribe wait unbounded — a hung authority server wedges the mutation pipeline forever VI posthaste-runtime/src/transport.rs:56,88,196 M4 renames RemoteBackend → RemoteAuthorityServer in this file
2 No reconnect/reconciler behind the down-channel: run_backend_down_channel is fire-and-forget; stream end = permanent silent staleness (outbox never retires, cache never evicts) VIII, XIV posthaste-runtime/src/read.rs:288-310; spawned unretained build.rs:281 M3/D29 splits build.rs; the reconciler is the missing level-triggered edge
3 Shutdown is a stub: AtomicBool nobody checks; account tasks hard-abort()ed mid-operation; no drain deadline XII posthaste-runtime/src/build.rs:1253-1256; supervisor/manager.rs:95-99 M3/D29 extracts shutdown.rs — implement, don't just move
4 Push reconnect: jitterless exponential backoff, unbounded retry, fallback cycle resets the failure counter (loops forever), no poll-only degraded tier VII, XIX authority-runtime/src/push.rs:104-155 — (follow-up unit)
5 Account sync awaited inline in the supervisor select! loop with no timeout — a hung provider blocks push/commands/ticks for that account V, VI supervisor/sync_flow.rs:172; runtime.rs:67 — (follow-up unit)
6 IMAP: zero tokio::time::timeout in the whole crate; unbounded BODY.PEEK[]/uid_search allocations from a hostile server VI, VII, IV posthaste-imap/src/{discovery.rs:123,idle.rs:40,body.rs:65,fetch/headers.rs:18} — (follow-up unit)
7 Domain outbox retries FlushError::Transient with no backoff and no max-attempts XIX, VII posthaste-domain/src/service/outbox.rs:460-466 M1 moves this file into domain-service
8 Web client: flat 1s reconnect forever (no backoff/jitter/breaker, no degraded-mode UI); unbounded request-waiter queue with no timeout VI, VII, XIX apps/web/src/runtime/linkClient.ts:40-55; core.ts:121-145 — (follow-up unit)
9 SSE frames and HTTP responses cast unchecked at the network boundary (JSON.parse(…) as RuntimeFrame) III, IV httpAdapter.ts:246,336; core.ts:218 M5's typed vocabulary is the natural moment to add a parse boundary client-side
10 Snooze scheduler compares wall-clock (SystemTime::now) for due-times XXIII supervisor/runtime.rs:241-244 — (follow-up unit; small)

Related open issues in the main tree's docs/issues/ that intersect M-steps: L2-runtime-nearnode-remote-seam (items B/C/D — account-scoped overlay, phantom seq gaps; item D's dead Conflict arm is D16, executed at M5), L2-engine-absorption-footguns (retire invariant lives only in EntityStore::settle — D9/M6 lifts it into the engine seam), L2-store-correctness-grabbag (replica-projector in_range/GC), L2-legacy-leftover-structures (item B, ungated invalidation storm).