29 KiB
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, andunconfigured; overall status ishealthy,warning, orerror. - 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:
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:
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
Approved visual: A — Diagnostic Ledger. Preserve its restrained issue rail, stable summary hero, two-column healthy ledgers, live sidebar footer, and degraded-only bar capsule.
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.
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:
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: <variant> 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, andPANAMA_DOCTOR_TIMEOUTtest seams; production defaults resolve from the real process environment. -
Produces:
panama-doctor --json,panama-doctor --summary, and a versioned schema withsummaryplus 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:
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:
@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
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 --jsonandpanama-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 targethealthwithrefresh,status,open, andrepair(id). -
Step 1: Write the failing QML state contract
The harness exposes fixture methods that call the real singleton's pure consumption seams:
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:
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:
tests/quickshell/health-service-contract.sh
tests/quickshell/settings-window-contract.sh
Expected: both PASS.
- Step 5: Commit the service layer
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 nameservices. -
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:
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:
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:
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:
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
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, andHealth.summary; existingpanama-actiondispatcher 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:
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:
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:
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
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 --jsonresult{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:
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:
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:
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:
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
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, controller-deferred live audit, and documentation
Integration note: origin/main added Mouse, Privacy, Region, and Online
Accounts destinations while this feature was in review. Merge commit 4ef2f01
preserves those routes and the newer Settings navigation architecture, keeps
the stable services route rendered by HealthPage, and leaves
ServicesPage.qml retired. Its useful Fedora handoffs for Users, Sharing,
Colour profiles, and Digital wellbeing now live in the boundary-last System
Health card alongside the existing network handoff, with focused static and
isolated runtime coverage.
Live-audit handoff: Per the integration brief, this task does not reload the daily-driver Quickshell, invoke a live repair, or run the read-only live doctor/IPC comparison. Those checks remain for the controller after code review.
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 and final contract evidence. The redacted live health snapshot and live shell audit are deferred to the controller after code review.
-
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:
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. After the latest Settings and installer work, the current inventory is 66 Quickshell contracts and 2 Hyprland contracts (the original pre-merge estimate was 58).
Integration result: syntax and all focused Health/Settings contracts pass. Two complete serial Quickshell runs each passed 63/65, but failed on different order-sensitive contracts. Run one failed Displays and Settings Hyprland Write; run two failed Focus Session and Health Service. Each failed contract passed immediately when rerun alone. Hyprland contracts passed 2/2. No out-of-scope test or service code was changed to hide this suite-order interference.
- Step 3: Controller runs a redacted live read-only comparison
Deferred to the controller after code review; Task 7 does not produce this live output.
Run:
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: Controller reloads and inspects the live shell
Deferred to the controller after code review; Task 7 does not reload or inspect the daily-driver shell.
Run:
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:
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.