Files
Panama/docs/superpowers/specs/2026-08-18-panama-health-recovery-design.md

11 KiB

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:

{
  "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.