ba5dc00bb2
Addresses the human review findings on the memory-pressure feature: * [P2] Dismissal hid later incidents of the same kind. The gateway now publishes `boot_id` (the lifecycle sentinel's started_at — changes on every gateway life) in the /api/status memory block, and the dashboard keys OOM-restart dismissal on it: acknowledging one restart no longer mutes the NEXT one (the OOM-loop case this banner exists for). Live pressure dismissals now also reset once pressure is demonstrably back to "ok" — "unknown" (stale heartbeat) is absence of evidence and clears nothing. Dismissal storage moved to a JSON list; old bare-string entries fail JSON.parse and degrade to a clean reset. * [P2] suspected_oom is a heuristic (unclean exit + low-memory final heartbeat), not proof the OOM killer acted — banner copy now says "restarted unexpectedly, most likely because it ran out of memory" instead of stating OOM as fact. * [P3] Mobile header clearance was applied per-banner (mt-14 on both MemoryPressureBanner and ProfileScopeBanner) AND on the content (pt-14), double/triple-stacking 56px gaps when banners were visible. Replaced with a single h-14 spacer above the banner stack.