From af0ba13573d67f982709e2151446fff338e309f7 Mon Sep 17 00:00:00 2001 From: Gabriel Brown Date: Tue, 18 Aug 2026 07:52:25 -0400 Subject: [PATCH] Design Panama Health and Recovery --- ...026-08-18-panama-health-recovery-design.md | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-18-panama-health-recovery-design.md diff --git a/docs/superpowers/specs/2026-08-18-panama-health-recovery-design.md b/docs/superpowers/specs/2026-08-18-panama-health-recovery-design.md new file mode 100644 index 0000000..e507abe --- /dev/null +++ b/docs/superpowers/specs/2026-08-18-panama-health-recovery-design.md @@ -0,0 +1,235 @@ +# Panama Health & Recovery Design + +## Purpose + +Panama Health & Recovery makes the desktop explain itself. It verifies the +local services, dependencies, links, and integrations that Panama relies on, +then presents useful recovery actions without asking the user to read logs or +diagnose a collection of unrelated Linux processes. + +The feature is intentionally quiet. A healthy desktop produces no notification, +banner, or permanent bar ornament. Problems appear in Panama Settings and, when +actionable, as one restrained bar indicator. User-initiated repairs receive +immediate Prism OSD or inline feedback. + +## Product boundaries + +The first release covers Panama-owned or Panama-integrated functionality: + +- Hyprland, Quickshell, the notification server, XDG desktop portals, PipeWire, + Vicinae, the clipboard watcher, wallpaper, idle policy, and Panama's runtime + configuration links. +- The Panama command collection, screenshot and OCR dependencies, DDC + brightness support, and the currently selected terminal and launcher. +- Nextcloud, RustDesk, KDE Connect, BlueBubbles, Home Assistant, calendar + aggregation, and the configured autostart entries. +- Orphaned Panama processes and inhibitors, including duplicate Caffeine locks. +- Versions and non-sensitive diagnostic context needed for a useful copied + report. + +It does not become a package manager, a generic system monitor, or a replacement +for Fedora's troubleshooting tools. It never installs packages, invokes `sudo`, +deletes user data, rewrites arbitrary configuration, or repairs services Panama +does not own. + +An optional integration that has never been configured is neutral **Not set +up**, not a warning. A configured integration that cannot operate is degraded. +This distinction prevents the health UI from pressuring the user to enable +features they do not want. + +## Information architecture + +The existing **Startup & Services** destination becomes **System Health**. This +avoids two pages reporting the same background services. Its existing Open and +Refresh actions remain available through the richer health rows. + +The page has four levels: + +1. A compact summary hero: **Healthy**, **Needs attention**, or **Action + required**, the last completed scan time, Refresh, and Copy Report. +2. An issues-first section shown only when one or more checks are degraded. +3. Grouped cards for Desktop Foundation, Input & Media, Integrations, and Panama + Tools. Healthy rows remain visible but visually quiet. +4. A short boundary note linking to GNOME or Fedora tools for system areas Panama + does not own. + +Each row contains a stable title, one-sentence observation, status label, and at +most one primary action. Actions use concrete language such as **Restart +Vicinae**, **Repair command link**, **Open Home settings**, or **View setup +instructions**. There is no generic Fix Everything button. + +The Settings sidebar's existing health footer becomes real and clickable. It +shows the aggregate state and opens System Health. The top bar gains a small +`HealthIndicator` only while an actionable warning or error exists; clicking it +opens the same page. Background scans never publish Signal Glass events or +desktop notifications. + +## Diagnostic engine + +`config/dot/quickshell/scripts/panama-doctor` is the single operating-system +boundary. It supports: + +- `panama-doctor --json` for a complete versioned snapshot. +- `panama-doctor --summary` for a concise human-readable installer or terminal + result. +- `panama-doctor --repair CHECK_ID --json` for an explicitly allow-listed repair. + +The helper emits one schema: + +```json +{ + "schemaVersion": 1, + "generatedAt": "2026-08-18T12:00:00Z", + "summary": { + "status": "warning", + "healthy": 18, + "warnings": 1, + "errors": 0, + "unconfigured": 2 + }, + "checks": [ + { + "id": "launcher.panama-commands", + "group": "panama-tools", + "title": "Panama Commands", + "status": "warning", + "detail": "16 of 17 commands are loaded", + "action": { + "kind": "repair", + "label": "Repair command link" + } + } + ] +} +``` + +Allowed statuses are `ok`, `warning`, `error`, and `unconfigured`. Check IDs, +group IDs, titles, and repair mappings are authored constants. Probe output may +populate observations but can never become a command or executable argument. + +Checks run concurrently where doing so is safe, with short per-probe timeouts. +A failed or timed-out probe yields a check result rather than aborting the whole +snapshot. Output order is deterministic so tests, copied reports, and visual +rows do not jump between scans. + +No secrets are read. The report may state whether a Home Assistant URL or token +is configured, but never includes either value. It excludes clipboard contents, +notification bodies, calendar event data, SSIDs, device addresses, environment +values, file contents, and command output that has not been explicitly parsed. + +## Quickshell state and refresh model + +`services/Health.qml` owns the latest accepted snapshot, aggregate severity, +busy state, last scan time, and the result of the most recent repair. It invokes +`panama-doctor` with argument arrays through `Process`; UI components never +construct shell commands. + +Health performs one delayed scan after the shell reaches a stable startup state. +It scans again when the System Health page is opened, when the user presses +Refresh, and after a repair settles. There is no periodic polling loop while the +desktop is idle. Services that already expose event-driven state remain the +authoritative source for their own interactive controls; Health is a diagnostic +snapshot, not a competing live service model. + +Every scan receives a monotonically increasing generation. Late output from an +older scan is discarded. A malformed snapshot leaves the last valid result in +place, marks the diagnostic engine unavailable, and offers a bounded Retry. + +The shell exposes a typed `health` IPC target with `refresh`, `status`, `open`, +and `repair(id)` operations. Vicinae gains **Panama: Check System Health**, which +opens the page and requests a fresh scan through the existing `panama-action` +dispatcher. + +## Repair policy + +Repairs are narrow, reversible, and attached to one check. The first release may: + +- Restart Panama's user services such as Vicinae, Hyprpaper, or Hypridle. +- Recreate Panama-owned symlinks when their destination is known and tracked. +- Reload Vicinae's Panama command collection. +- Release duplicate user-owned inhibitors whose metadata identifies Panama and + Caffeine. +- Restart Quickshell through the verified `panama-action restart-shell` path. +- Open the exact Panama Settings page required to finish credentials or entity + selection. + +Restarting a working service is not presented as a repair. Repairs that interrupt +visible desktop chrome require a confirmation sheet in Settings. Navigation and +setup actions do not. Package installation, privileged service changes, display +mode writes, and destructive cleanup are never automatic; the UI shows concise +instructions instead. + +After a repair, Health rescans and judges success from the observed result. A +zero exit status alone never turns a row green. Failure remains inline on the +affected row and also produces the existing Panama action-failure notification +when the action originated outside Settings. + +## Visual language and interaction + +System Health uses the established Settings cards and Prism tokens. Healthy +states use a small muted green dot and subdued **Healthy** copy. Warnings use +amber; red is reserved for functionality that is configured, required, and +currently broken. `unconfigured` rows use neutral gray. + +The summary hero does not use a decorative gauge, percentage score, pulse, +shimmer, or animated gradient. A desktop is not “82% healthy.” The headline and +issue count are more understandable and do not create false precision. + +Rows keep their height stable while refreshing. The previous snapshot remains +visible with a quiet **Checking…** label rather than replacing the page with a +spinner. Keyboard focus order reaches Refresh, Copy Report, issue rows, repair +actions, and external handoffs. Status is always expressed in text as well as +color. + +Before production components are edited, the page and degraded bar indicator +will be shown in several static mocks using the existing Settings geometry. The +chosen mock must preserve this information architecture and Panama's current +Prism language rather than introduce a new visual system. + +## Failure handling + +- Missing required executables become actionable check results. +- Missing optional applications remain neutral until configured. +- A doctor crash, timeout, or malformed JSON does not clear the last good + snapshot or crash Quickshell. +- Concurrent refresh requests coalesce into one follow-up scan. +- A repair request for an unknown or non-repairable ID is rejected before any + process starts. +- Copy Report uses only the already-redacted snapshot and reports clipboard + failure inline. +- If the Settings window is closed during a scan or repair, the process may + finish; reopening the page shows the settled result. + +## Verification + +- Run the real helper against isolated fake command, config, state, and runtime + directories and prove every status transition deterministically. +- Validate the JSON schema, stable check IDs, deterministic ordering, and + uniqueness of each ID. +- Prove unconfigured integrations remain neutral while configured failures are + degraded. +- Prove reports contain no fixture secrets, clipboard text, calendar data, + addresses, or unparsed environment values. +- Exercise every repair through the allow-list, assert its exact command, and + prove unknown IDs cannot execute anything. +- Test scan generations, malformed snapshots, refresh coalescing, repair + rescans, and preservation of the last valid state in a Quickshell harness. +- Verify Settings routing, search entries, the live sidebar footer, and the + degraded-only bar indicator without QML warnings. +- Validate the Vicinae command and typed IPC surface. +- Run a read-only doctor scan on the real workstation and compare key results to + direct service checks. State-changing live repair tests require an actually + degraded disposable target or explicit user approval. +- Restart the live shell, inspect the fresh log, and visually review healthy, + warning, error, unconfigured, refreshing, and repair-result states. + +## Delivery slices + +1. Diagnostic schema, read-only probes, redaction, and contract tests. +2. `Health.qml`, typed IPC, startup/manual refresh, and fixture harness. +3. System Health Settings page, live sidebar footer, search, and report copy. +4. Degraded-only bar indicator and Vicinae command. +5. Allow-listed repairs, confirmations, post-repair verification, and live audit. + +The slices are one feature and land together. Their order keeps the UI backed by +real diagnostics from its first production render.