Pre-mortem-risk → mitigating-seam map

Six failure modes were pre-mortem’d during architecture (mid-2027 hindsight); each one’s prevention is a binding architectural constraint, not a hope. This table maps each risk to the seam or mechanism that parachutes it and where that mechanism lives.

This is the seed map (Story 0.7). Story 6.4 keeps it complete and current as the architecture evolves (AR-21). Source: architecture.md §"Pre-mortem-Hardened Mitigations" and §"Architectural Commitments Added".

Risk Failure mode Mitigating seam / mechanism Lives in

M1

The MMDVMHost engine port is the critical path — if it slips or misbehaves, nothing else matters

ModemPort/FrameSource trait at frame altitude (crates/modem) decouples the port from the driver; a captured BM-interop conformance corpus is the test oracle; explicit non-port scope is written down; subprocess-wrapping stock MMDVMHost is retained as the cuttable-ring fallback; first milestone = minimal single-TG on-air relay before any UI

crates/modem + crates/engine; corpus docs/interop/bm-corpus/ — Epic 1; proven on HW in Bench Spike 0(b) (Story 0.8)

M2

Update rollback is the least-tested path — a bad update bricks a headless box

systemd WatchdogSec + post-restart self-health-check auto-reverts to .prev; config-schema versioning with forward-migration tested in CI; a rollback chaos test ships a deliberately-broken build to a test Pi and asserts the revert fires (AR-15)

crates/updater + packaging/systemd + CI chaos job — Epic 4

M3

Onboarding network bring-up is the riskiest surface — regdom/AP/STA ceremony on real radios

HostShell seam (crates/host: nmcli/cloud-init/regdom/mDNS, AR-16); a zero-Wi-Fi rescue path (Ethernet + USB-serial console) that works regardless of WLAN state; a first-boot network self-diagnostic; a Pi4 × Pi5 × fresh-Trixie test matrix exercised early

crates/host + packaging/cloud-init + packaging/rescue — Epic 3; proven on HW in Bench Spike 0(c)(d) (Story 0.8)

M4

BM API-key blast radius — the key grants full SelfCare control

Key handling is opt-in / transient-by-default (prefer re-entry over storage); secrets are secrecy::SecretString (never logged/serialized) behind systemd-creds; loud SD-disposal + threat-model guidance in onboarding; the honest secrets ceiling is recorded and disclosed

crates/bm-client + crates/persistence + server::auth; rationale in ADR-006 (this story); user disclosure Story 6.2 / AR-22

M5

Bus-factor-1 — a solo maintainer is a single point of failure

The zero-hardware seam-fake harness doubles as the contributor on-ramp (AR-17): one seam fixable against fakes with no whole-system knowledge, runnable with zero hardware; the ADR set + this map + CONTRIBUTING make the rationale legible → strategic posture "Solo for now, legible for later"

crates/server/tests/zero_hardware_harness.rs + docs/adr/ + CONTRIBUTING.md — seeded in this story (0.7), completed in 6.4

M6

Leptos freeze — the frontend framework stalls on a future toolchain

Written trip-wire: if Leptos won’t build on stable Rust within a bounded window after a breaking toolchain change → evaluate Dioxus migration; pinned rust-toolchain.toml buys reaction time; CSS + ARIA spine kept framework-portable (only the reactive glue is exposed)

rust-toolchain.toml + crates/app; reversal trigger in ADR-005 (this story)

Reading this map

  • "Lives in" names the crate/path and the owning epic/story, so a maintainer can jump from a risk to the code that addresses it and to the work that completes it.

  • Two of the six (M1, M3) — plus the BM-client live-auth-header leg, which is a Bench Spike 0 concern but not one of the six pre-mortem risks — are gated on Bench Spike 0 (Story 0.8, leg (e)) — the hardware spike that retires the unverified joints before broad build-out.

  • Where a risk’s mitigation is itself a closest-call decision, it carries an ADR (M4 → ADR-006, M6 → ADR-005); the rest are tracked in their epics.