From 24d8bfd641e3ed29c0c2a3e588bc35e9fe1f30a1 Mon Sep 17 00:00:00 2001 From: Gabriel Brown Date: Tue, 18 Aug 2026 08:28:20 -0400 Subject: [PATCH] Plan Panama health and recovery --- .../2026-08-18-panama-health-recovery.md | 566 ++++++++++++++++++ 1 file changed, 566 insertions(+) create mode 100644 docs/superpowers/plans/2026-08-18-panama-health-recovery.md diff --git a/docs/superpowers/plans/2026-08-18-panama-health-recovery.md b/docs/superpowers/plans/2026-08-18-panama-health-recovery.md new file mode 100644 index 0000000..79433e7 --- /dev/null +++ b/docs/superpowers/plans/2026-08-18-panama-health-recovery.md @@ -0,0 +1,566 @@ +# Panama Health & Recovery Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Build a quiet, trustworthy System Health surface that diagnoses Panama-owned desktop functionality, exposes redacted reports, and offers only narrow allow-listed repairs. + +**Architecture:** An executable Python helper, `panama-doctor`, is the only operating-system boundary and emits one deterministic JSON schema. A `Health.qml` singleton owns accepted snapshots, scan generations, repair state, and report copying; Settings, the bar, IPC, and Vicinae consume that typed state without constructing commands. + +**Tech Stack:** Python 3 standard library, Bash contract tests, Quickshell/QML, QtQuick, Hyprland IPC, Vicinae script commands, Prism design tokens. + +**Spec:** `docs/superpowers/specs/2026-08-18-panama-health-recovery-design.md` + +## Global Constraints + +- Healthy background scans are silent: no notifications, Signal Glass events, animations, or permanent bar ornament. +- Allowed statuses are exactly `ok`, `warning`, `error`, and `unconfigured`; overall status is `healthy`, `warning`, or `error`. +- Optional integrations that have never been configured are `unconfigured`, never warnings. +- The helper never reads or reports secret values, clipboard contents, notification bodies, calendar event data, SSIDs, addresses, or arbitrary command output. +- The helper never installs packages, invokes `sudo`, deletes user data, rewrites arbitrary configuration, or repairs services Panama does not own. +- Probe-derived values may populate observations only; check IDs, groups, titles, actions, commands, and arguments are authored constants. +- All process launches use argument arrays. UI text and report content never become commands. +- Preserve the last valid snapshot on helper failure or malformed JSON. +- Repairs are judged by a fresh observed scan, not by process exit status alone. +- Do not run a state-changing live repair without a genuinely degraded disposable target or explicit user approval. + +## File map and stable interfaces + +- `config/dot/quickshell/scripts/panama-doctor`: Python CLI and sole diagnostic/repair OS boundary. +- `config/dot/quickshell/services/Health.qml`: snapshot state machine, scan/repair processes, report copy, and fixture seams. +- `config/dot/quickshell/health-harness.qml`: deterministic IPC harness for generations, malformed data, coalescing, and repairs. +- `config/dot/quickshell/modules/settings/HealthPage.qml`: System Health page composition. +- `config/dot/quickshell/modules/settings/HealthSummary.qml`: stable-height summary hero and primary controls. +- `config/dot/quickshell/modules/settings/HealthCheckRow.qml`: one accessible check row with one action. +- `config/dot/quickshell/modules/bar/HealthIndicator.qml`: degraded-only bar entry point. +- `config/local/share/vicinae/scripts/check-system-health.sh`: searchable launcher command. +- `tests/quickshell/fixtures/doctor/`: isolated command, config, state, and runtime fixtures containing no real workstation data. +- `tests/quickshell/panama-doctor-contract.sh`: schema, status, redaction, timeout, ordering, and repair allow-list contract. +- `tests/quickshell/health-service-contract.sh`: QML state-machine contract. +- `tests/quickshell/health-ui-contract.sh`: Settings, footer, report, indicator, IPC, and Vicinae integration contract. + +The helper's authored check order is: + +```text +desktop.hyprland +desktop.quickshell +desktop.notifications +desktop.portals +desktop.hyprpaper +desktop.hypridle +desktop.vicinae +input.pipewire +input.clipboard +input.wallpaper +input.capture +input.ocr +input.brightness +integration.nextcloud +integration.rustdesk +integration.kdeconnect +integration.bluebubbles +integration.home-assistant +integration.calendar +panama.runtime-links +panama.vicinae-commands +panama.selected-terminal +panama.selected-launcher +panama.processes +panama.caffeine +``` + +Only these repair IDs are executable in release one: + +```text +desktop.hyprpaper -> systemctl --user restart hyprpaper.service +desktop.hypridle -> systemctl --user restart hypridle.service +desktop.vicinae -> systemctl --user restart vicinae.service +desktop.quickshell -> panama-action restart-shell (confirmation required) +panama.runtime-links -> recreate only known Panama-owned broken symlinks +panama.vicinae-commands -> setup/scripts/link-vicinae-scripts +panama.caffeine -> release duplicate Panama/Caffeine inhibitor PIDs only +``` + +--- + +### Task 1: Prism health mocks and visual approval + +**Files:** +- Create outside tracked source: `.superpowers/mocks/system-health/index.html` +- Create outside tracked source: `.superpowers/mocks/system-health/panama.css` +- Create outside tracked source: `.superpowers/mocks/system-health/mock.js` +- Create outside tracked source: `.superpowers/mocks/system-health/a-ledger.html` +- Create outside tracked source: `.superpowers/mocks/system-health/b-focus.html` +- Create outside tracked source: `.superpowers/mocks/system-health/c-compact.html` + +**Interfaces:** +- Consumes: the existing 272 px Settings sidebar, 48 px titlebar, Tokyo Night Moon Prism tokens, and the approved information architecture. +- Produces: one approved visual composition for healthy, warning, checking, and error states plus the degraded-only bar indicator. + +- [ ] **Step 1: Build three static compositions from real copy** + +Use the same warning fixture in all three: `Vicinae` is stopped with action `Restart Vicinae`; `External monitor brightness` needs permission with action `View setup instructions`; `BlueBubbles` is `Not set up`. Keep every variant inside the real Settings geometry and include the footer and bar indicator. + +```text +A — Diagnostic ledger: one restrained amber issue rail beside calm grouped rows. +B — Focus card: issues receive the visual focus; healthy groups collapse into quieter ledgers below. +C — Compact matrix: dense two-column group cards with the same issue-first ordering. +``` + +- [ ] **Step 2: Serve and visually inspect the mocks** + +Run: + +```bash +python3 -m http.server 52780 --directory .superpowers/mocks/system-health +``` + +Expected: all three variants render at `http://localhost:52780`, keyboard focus is visible, no element overflows at 1360x900, and reduced-motion mode has no continuous animation. + +- [ ] **Step 3: Capture the approved direction in the plan** + +Add a short `Approved visual: ` note beneath this task after user selection. Production UI work in Task 4 must reproduce that composition using existing QML tokens rather than copying browser-only effects. + +### Task 2: Deterministic read-only doctor + +**Files:** +- Create: `config/dot/quickshell/scripts/panama-doctor` +- Create: `tests/quickshell/panama-doctor-contract.sh` +- Create: `tests/quickshell/fixtures/doctor/bin/systemctl` +- Create: `tests/quickshell/fixtures/doctor/bin/pgrep` +- Create: `tests/quickshell/fixtures/doctor/bin/busctl` +- Create: `tests/quickshell/fixtures/doctor/bin/qs` +- Create: `tests/quickshell/fixtures/doctor/bin/vicinae` +- Create: `tests/quickshell/fixtures/doctor/bin/systemd-inhibit` + +**Interfaces:** +- Consumes: `PANAMA_DOCTOR_ROOT`, `PANAMA_DOCTOR_HOME`, `PANAMA_DOCTOR_CONFIG_HOME`, `PANAMA_DOCTOR_STATE_HOME`, `PANAMA_DOCTOR_RUNTIME_DIR`, `PANAMA_DOCTOR_PATH`, and `PANAMA_DOCTOR_TIMEOUT` test seams; production defaults resolve from the real process environment. +- Produces: `panama-doctor --json`, `panama-doctor --summary`, and a versioned schema with `summary` plus the 25 ordered check objects listed above. + +- [ ] **Step 1: Write the failing schema and redaction contract** + +The contract must create an isolated home, tracked source tree, runtime tree, and fake command directory, then assert: + +```bash +snapshot="$($doctor --json)" +jq -e '.schemaVersion == 1 + and (.generatedAt | type == "string") + and (.summary.status | IN("healthy", "warning", "error")) + and (.context.session | IN("hyprland", "other")) + and (.context.versions | type == "array") + and ([.checks[].id] | length == 25) + and ([.checks[].id] | unique | length == 25) + and ([.checks[].status] | all(IN("ok", "warning", "error", "unconfigured")))' <<<"$snapshot" +[[ "$(jq -r '.checks[].id' <<<"$snapshot")" == "$expected_order" ]] +! grep -Fq 'fixture-secret-token' <<<"$snapshot" +! grep -Fq 'fixture clipboard body' <<<"$snapshot" +! grep -Fq 'AA:BB:CC:DD:EE:FF' <<<"$snapshot" +``` + +Cover a healthy required service, a missing required executable, an unconfigured optional integration, a configured-but-stopped integration, an inaccessible DDC bus, a timed-out probe, duplicate Caffeine inhibitors, malformed probe output, and concise `--summary` output. + +- [ ] **Step 2: Run the contract and verify the helper is absent** + +Run: `tests/quickshell/panama-doctor-contract.sh` + +Expected: FAIL because `config/dot/quickshell/scripts/panama-doctor` does not exist. + +- [ ] **Step 3: Implement authored checks and concurrent bounded probes** + +Use Python standard-library types and deterministic assembly: + +```python +@dataclass(frozen=True) +class Action: + kind: Literal["repair", "open", "instructions"] + label: str + confirm: bool = False + +@dataclass(frozen=True) +class Check: + id: str + group: Literal["desktop-foundation", "input-media", "integrations", "panama-tools"] + title: str + status: Literal["ok", "warning", "error", "unconfigured"] + detail: str + action: Action | None = None +``` + +Run independent probes through `ThreadPoolExecutor(max_workers=8)`. Every subprocess call must use a constant argument tuple, `capture_output=True`, `text=True`, and the configured timeout. Convert timeout, non-zero status, and parse failure into a check result. Assemble checks by the authored ID tuple after futures settle; never emit completion order. + +Configuration checks may inspect existence and file type only. Home Assistant is configured when both expected variable names are present, but their values are never retained. Calendar is configured from enabled EDS source count only; event commands are never called. BlueBubbles is configured from the Flatpak installation check. DDC uses only `panama-brightness list` and retains display count plus its authored error classification, never connector names. + +The top-level `context` contains only an authored session class and an ordered array of parsed Hyprland, Quickshell, Fedora, and Panama revision versions. `panama.processes` counts only exact authored process names and flags duplicate Quickshell, Vicinae, Hyprpaper, or Hypridle instances without exposing command lines. Integration actions are authored too: Nextcloud, RustDesk, KDE Connect, and BlueBubbles may offer their exact Open action; Home Assistant and calendar failures route to `home-phone` and `datetime`; never derive an application or page name from probe output. + +- [ ] **Step 4: Run the doctor contract** + +Run: `tests/quickshell/panama-doctor-contract.sh` + +Expected: `panama doctor contract: PASS`. + +- [ ] **Step 5: Commit the read-only engine** + +```bash +git add config/dot/quickshell/scripts/panama-doctor tests/quickshell/panama-doctor-contract.sh tests/quickshell/fixtures/doctor +git commit -m "Add Panama system health diagnostics" +``` + +### Task 3: Health singleton and typed IPC state machine + +**Files:** +- Create: `config/dot/quickshell/services/Health.qml` +- Create: `config/dot/quickshell/health-harness.qml` +- Create: `tests/quickshell/health-service-contract.sh` +- Modify: `config/dot/quickshell/shell.qml` + +**Interfaces:** +- Consumes: `panama-doctor --json` and `panama-doctor --repair CHECK_ID --json`. +- Produces: `Health.snapshot`, `Health.checks`, `Health.summary`, `Health.status`, `Health.actionable`, `Health.busy`, `Health.diagnosticUnavailable`, `Health.lastError`, `Health.repairingId`, `Health.lastRepair`, `Health.lastCopyResult`, `Health.refresh()`, `Health.repair(id, external)`, `Health.copyReport()`, and IPC target `health` with `refresh`, `status`, `open`, and `repair(id)`. + +- [ ] **Step 1: Write the failing QML state contract** + +The harness exposes fixture methods that call the real singleton's pure consumption seams: + +```qml +function accept(text: string, generation: int): bool { return Health.consumeSnapshot(text, generation); } +function queue(): void { Health.refresh(); Health.refresh(); } +function status(): string { return JSON.stringify(Health.diagnostics()); } +``` + +Assert that a valid warning snapshot is accepted, an older generation is ignored, malformed JSON preserves the prior checks and marks the engine unavailable, two refreshes while running schedule exactly one follow-up, a valid repair triggers one rescan, and unknown/non-repairable IDs start no process. + +- [ ] **Step 2: Run the contract and verify it fails** + +Run: `tests/quickshell/health-service-contract.sh` + +Expected: FAIL because `Health.qml` and the harness do not exist. + +- [ ] **Step 3: Implement the singleton state machine** + +Define the stable state shape: + +```qml +property var snapshot: ({}) +property var checks: [] +property var summary: ({ status: "healthy", healthy: 0, warnings: 0, errors: 0, unconfigured: 0 }) +property string status: "healthy" +property bool diagnosticUnavailable: false +property bool queuedRefresh: false +property int generation: 0 +property int acceptedGeneration: 0 +property string repairingId: "" +property var lastRepair: ({}) +property string lastCopyResult: "" +readonly property bool actionable: status === "warning" || status === "error" +readonly property bool busy: scanProcess.running || repairProcess.running +``` + +Use `Process.exec([root.helperPath, "--json"])`; attach the current generation to the collector before launch. `consumeSnapshot(text, generation)` validates schema version, summary keys, context shape, unique IDs, groups, statuses, titles, details, and action shapes before replacing state. A 2200 ms one-shot startup timer requests the initial scan. A running scan sets `queuedRefresh`; exit consumes at most one queued follow-up. `copyReport()` sends only `JSON.stringify(root.snapshot, null, 2)` to `wl-copy` through a `Process` stdin buffer and writes success or failure to `lastCopyResult` without touching the clipboard service's history model. + +The `health` IPC `status()` returns only the already-redacted summary, busy flags, generation, and check IDs/statuses. `open()` calls `ShellState.openSettings("services")` then refreshes. IPC `repair(id)` calls `Health.repair(id, true)` and returns a Boolean acceptance result; Settings calls `Health.repair(id, false)`. A failed externally-originated repair uses an argument-array `notify-send` process with the existing `Panama action failed` title, while Settings failures remain inline. + +- [ ] **Step 4: Run service and IPC contracts** + +Run: + +```bash +tests/quickshell/health-service-contract.sh +tests/quickshell/settings-window-contract.sh +``` + +Expected: both PASS. + +- [ ] **Step 5: Commit the service layer** + +```bash +git add config/dot/quickshell/services/Health.qml config/dot/quickshell/health-harness.qml tests/quickshell/health-service-contract.sh config/dot/quickshell/shell.qml +git commit -m "Add Panama health state service" +``` + +### Task 4: Approved System Health Settings page + +**Files:** +- Create: `config/dot/quickshell/modules/settings/HealthPage.qml` +- Create: `config/dot/quickshell/modules/settings/HealthSummary.qml` +- Create: `config/dot/quickshell/modules/settings/HealthCheckRow.qml` +- Modify: `config/dot/quickshell/modules/settings/SettingsShell.qml` +- Modify: `config/dot/quickshell/modules/settings/SettingsSidebar.qml` +- Modify: `config/dot/quickshell/services/SettingsSearch.qml` +- Delete: `config/dot/quickshell/modules/settings/ServicesPage.qml` +- Create: `tests/quickshell/health-ui-contract.sh` +- Modify: `tests/quickshell/settings-pages-contract.sh` +- Modify: `tests/quickshell/settings-search-contract.sh` + +**Interfaces:** +- Consumes: all read-only state and methods from `Health.qml`; route remains the stable internal name `services`. +- Produces: System Health summary, issues-first cards, four grouped ledgers, live clickable sidebar footer, Copy Report feedback, and confirmation requests for disruptive repairs. + +- [ ] **Step 1: Write failing Settings and accessibility assertions** + +Assert static structure and fixture-rendered state: + +```bash +rg -Fq 'label: "System Health"' config/dot/quickshell/modules/settings/SettingsSidebar.qml +rg -Fq 'onClicked: Health.copyReport()' config/dot/quickshell/modules/settings/HealthSummary.qml +rg -Fq 'onTapped: root.pageRequested("services")' config/dot/quickshell/modules/settings/SettingsSidebar.qml +rg -Fq 'text: "Checking…"' config/dot/quickshell/modules/settings/HealthSummary.qml +rg -Fq 'Health.refresh()' config/dot/quickshell/modules/settings/HealthPage.qml +``` + +The runtime harness must prove warning rows appear before healthy groups, unconfigured is visible as `Not set up`, every status has text in addition to color, refresh preserves row geometry, keyboard focus reaches both hero actions and row actions, and a Quickshell-restart repair opens a confirmation sheet. + +- [ ] **Step 2: Run UI contracts and verify failure** + +Run: + +```bash +tests/quickshell/health-ui-contract.sh +tests/quickshell/settings-pages-contract.sh +tests/quickshell/settings-search-contract.sh +``` + +Expected: FAIL because the approved Health components are absent. + +- [ ] **Step 3: Implement the approved composition** + +Use `SettingsPage`, `SettingsCard`, `SettingsButton`, `Theme`, and `PrismEdge`. Keep the summary hero stable at 126 px and each check row at least 62 px. Derive labels exactly: + +```qml +function statusLabel(status: string): string { + if (status === "ok") return "Healthy"; + if (status === "warning") return "Needs attention"; + if (status === "error") return "Action required"; + return "Not set up"; +} +``` + +`HealthPage.Component.onCompleted` calls `Health.refresh()`. Issues are checks with `warning` or `error`. Group cards preserve helper order. Each row exposes at most one action. `open` actions route to exact Settings pages; `instructions` actions reveal authored inline instructions; `repair` actions call `Health.repair(id, false)` after confirmation only when `action.confirm === true`. + +The sidebar footer is a 54 px `TapHandler` target with status text derived from Health, not a hardcoded string. It opens `services`; when no scan has completed it says `Checking Panama desktop`. A malformed or failed doctor run retains the last rows, changes only the hero to `Health check unavailable`, and exposes one bounded `Retry` action. The page ends with the approved boundary note and an `Open GNOME Settings` action for networking, printers, users, and other Fedora-owned areas. + +- [ ] **Step 4: Run UI contracts and inspect the rendered fixture** + +Run: + +```bash +tests/quickshell/health-ui-contract.sh +tests/quickshell/settings-pages-contract.sh +tests/quickshell/settings-search-contract.sh +``` + +Expected: all PASS with zero QML warnings. + +- [ ] **Step 5: Commit the Settings experience** + +```bash +git add config/dot/quickshell/modules/settings config/dot/quickshell/services/SettingsSearch.qml tests/quickshell/health-ui-contract.sh tests/quickshell/settings-pages-contract.sh tests/quickshell/settings-search-contract.sh +git commit -m "Build the System Health settings page" +``` + +### Task 5: Quiet bar indicator and launcher entry point + +**Files:** +- Create: `config/dot/quickshell/modules/bar/HealthIndicator.qml` +- Modify: `config/dot/quickshell/modules/bar/Bar.qml` +- Create: `config/local/share/vicinae/scripts/check-system-health.sh` +- Modify: `config/dot/quickshell/scripts/panama-action` +- Modify: `tests/quickshell/health-ui-contract.sh` +- Modify: `tests/quickshell/panama-action-contract.sh` +- Modify: `tests/quickshell/panama-commands-contract.sh` + +**Interfaces:** +- Consumes: `Health.actionable`, `Health.status`, and `Health.summary`; existing `panama-action` dispatcher and Settings IPC. +- Produces: one degraded-only bar affordance and Vicinae command `Panama: Check System Health`. + +- [ ] **Step 1: Extend contracts before production files** + +Assert the indicator is absent for healthy/unconfigured-only fixtures, visible amber for warnings, visible red for errors, includes a textual accessible label, and opens `services`. Extend command fixtures so: + +```text +panama-action health -> qs ipc call health open +check-system-health.sh title -> Panama: Check System Health +check-system-health.sh exec -> $HOME/.config/quickshell/scripts/panama-action health +``` + +- [ ] **Step 2: Run focused tests and verify failure** + +Run: + +```bash +tests/quickshell/health-ui-contract.sh +tests/quickshell/panama-action-contract.sh +tests/quickshell/panama-commands-contract.sh +``` + +Expected: FAIL on the missing indicator and command. + +- [ ] **Step 3: Implement the quiet entry points** + +Place `HealthIndicator` in the right-side bar row before `ActivityIndicator`. It has no reserved width while hidden, no animation, and one compact shield/wrench glyph with an issue-count tooltip or accessible description. Use `Theme.warn` only for warnings and `Theme.danger` only for errors. Clicking calls `ShellState.openSettings("services")` and `Health.refresh()`. + +Add this dispatcher case and usage token: + +```bash +health) qs ipc call health open ;; +``` + +Create a Vicinae script with schema version 1, silent mode, Panama Settings icon, keywords `health`, `doctor`, `repair`, `services`, and the stable `panama-action health` execution path. + +- [ ] **Step 4: Run focused tests** + +Run the three commands from Step 2. + +Expected: all PASS; command count increases from 17 to 18. + +- [ ] **Step 5: Commit the entry points** + +```bash +git add config/dot/quickshell/modules/bar config/local/share/vicinae/scripts/check-system-health.sh config/dot/quickshell/scripts/panama-action tests/quickshell +git commit -m "Add quiet System Health entry points" +``` + +### Task 6: Allow-listed repairs and observed recovery + +**Files:** +- Modify: `config/dot/quickshell/scripts/panama-doctor` +- Modify: `tests/quickshell/panama-doctor-contract.sh` +- Modify: `config/dot/quickshell/services/Health.qml` +- Modify: `tests/quickshell/health-service-contract.sh` +- Modify: `config/dot/quickshell/modules/settings/HealthCheckRow.qml` +- Modify: `tests/quickshell/health-ui-contract.sh` + +**Interfaces:** +- Consumes: the fixed repair matrix in this plan and current accepted checks from `Health.qml`. +- Produces: `panama-doctor --repair CHECK_ID --json` result `{schemaVersion, checkId, accepted, exitCode, message}`, inline repair state, and one post-repair scan. + +- [ ] **Step 1: Add exact repair-command tests** + +For every repair ID, use fake commands and isolated paths to assert the exact argv. Assert all of these are rejected before any process or filesystem write: + +```text +unknown.check +integration.home-assistant +input.brightness +desktop.notifications +../../escape +desktop.vicinae;touch injected +``` + +For runtime links, fixtures must prove only these link names are eligible: `hypr`, `quickshell`, `uwsm`, and `vicinae`; a regular user-owned directory is reported but never replaced. For Caffeine, only duplicate rows with application `Panama`, current UID, reason `Caffeine`, and mode `block` may yield numeric PIDs; leave one valid inhibitor alive and release extras. + +- [ ] **Step 2: Run repair contracts and verify failure** + +Run: + +```bash +tests/quickshell/panama-doctor-contract.sh +tests/quickshell/health-service-contract.sh +``` + +Expected: FAIL because `--repair` is not implemented. + +- [ ] **Step 3: Implement the authored repair registry** + +Represent commands as immutable constant tuples or dedicated functions: + +```python +REPAIR_COMMANDS = { + "desktop.hyprpaper": ("systemctl", "--user", "restart", "hyprpaper.service"), + "desktop.hypridle": ("systemctl", "--user", "restart", "hypridle.service"), + "desktop.vicinae": ("systemctl", "--user", "restart", "vicinae.service"), + "desktop.quickshell": ("panama-action", "restart-shell"), +} +``` + +Handle runtime links, Vicinae command linking, and duplicate inhibitors in dedicated functions that accept no caller-controlled path or command. Return JSON on every known failure. Unknown IDs exit 2 with `accepted: false` and do not invoke any runner. + +`Health.repair(id, external)` requires the ID to exist in the current snapshot with `action.kind === "repair"`, records `repairingId`, runs the helper with an argument array, parses the result, clears the busy row, and requests exactly one fresh scan. Keep the row degraded until that scan reports recovery. + +- [ ] **Step 4: Run repair and UI contracts** + +Run: + +```bash +tests/quickshell/panama-doctor-contract.sh +tests/quickshell/health-service-contract.sh +tests/quickshell/health-ui-contract.sh +``` + +Expected: all PASS. + +- [ ] **Step 5: Commit repairs** + +```bash +git add config/dot/quickshell/scripts/panama-doctor config/dot/quickshell/services/Health.qml config/dot/quickshell/modules/settings/HealthCheckRow.qml tests/quickshell +git commit -m "Add bounded Panama recovery actions" +``` + +### Task 7: Full verification, live read-only audit, and documentation + +**Files:** +- Modify: `config/dot/hypr/DESKTOP-PARITY.md` +- Modify: `config/dot/quickshell/modules/settings/README.md` +- Modify: `docs/superpowers/plans/2026-08-18-panama-health-recovery.md` + +**Interfaces:** +- Consumes: the complete feature and existing regression suite. +- Produces: current user documentation, a redacted live health snapshot, and final verification evidence. + +- [ ] **Step 1: Document boundaries and entry points** + +Document `Panama: Check System Health`, Settings → System Health, the degraded-only bar indicator, `panama-doctor --summary`, the no-`sudo`/no-package-install boundary, and the fact that GNOME/Fedora tools remain responsible for generic system configuration. + +- [ ] **Step 2: Run syntax, focused, and full contracts** + +Run: + +```bash +python3 -m py_compile config/dot/quickshell/scripts/panama-doctor +bash -n config/dot/quickshell/scripts/panama-action +tests/quickshell/panama-doctor-contract.sh +tests/quickshell/health-service-contract.sh +tests/quickshell/health-ui-contract.sh +for test in tests/quickshell/*contract.sh; do "$test"; done +for test in tests/hypr/*contract.sh; do "$test"; done +``` + +Expected: every command exits 0; Quickshell tests report 58 contracts after the three new contracts land. + +- [ ] **Step 3: Run a redacted live read-only comparison** + +Run: + +```bash +config/dot/quickshell/scripts/panama-doctor --json >"$(mktemp)" +config/dot/quickshell/scripts/panama-doctor --summary +systemctl --user is-active hyprpaper.service hypridle.service vicinae.service pipewire.service +qs ipc call health refresh +qs ipc call health status | jq '{status, busy, checks: [.checks[] | {id, status}]}' +``` + +Expected: helper and direct service states agree. Do not print details from integrations; copied and IPC reports contain only redacted authored observations. + +- [ ] **Step 4: Reload and inspect the live shell** + +Run: + +```bash +qs reload +sleep 4 +journalctl --user --since '-2 minutes' --no-pager | rg -i 'quickshell|qml|panama' | tail -200 +``` + +Expected: the shell returns, System Health opens, the healthy state is silent, and there are no new QML errors or binding-loop warnings. Do not invoke a repair during this step. + +- [ ] **Step 5: Final diff and commit** + +Run: + +```bash +git diff --check +git status --short +git diff --stat origin/main...HEAD +git add config/dot/hypr/DESKTOP-PARITY.md config/dot/quickshell/modules/settings/README.md docs/superpowers/plans/2026-08-18-panama-health-recovery.md +git commit -m "Document Panama health and recovery" +``` + +Expected: only intentional Health & Recovery files are present and no workstation-specific values appear in the diff.