Drop the extension, and give the test suite a front door

Phase 6, the last of the fresh-install spec.

159 scripts lose their .sh: 110 contracts, 47 Vicinae commands, 2 compositor
contracts. A shebang and the executable bit already select the interpreter. The
extension only ever added something that had to stay in sync, and the rename
proved the point twice over in the space of an hour.

The spec's stated risk was Vicinae's script discovery. One script was renamed and
reloaded on its own before the other 46 followed; it came back as
scripts:panama.capture and all 47 resolve. What the probe turned up instead is
that the extension was never only a filename: Vicinae's command IDs embed it, so
every ID changed. Nothing in this repository refers to them, so nothing breaks.
The only trace is Vicinae's metadata.json, whose visited map had two Panama
entries that are now orphaned -- two commands lost their usage ranking and will
earn it back. Worth knowing before anyone renames these again on a machine that
has a keybind pointing at one.

Rewriting the references by exact filename missed two things it structurally
could not see: a name built from a variable, settings-$page.sh, and a glob,
-name '*.sh'. Both were in the contract that counts the generated commands, which
promptly reported 47 expected and 0 found. The mechanical part of a rename is the
part that looks finished.

The three subcommands. panama doctor fronts a health check that already existed
and already ran at the end of every install but could not be reached from a
terminal. panama upgrade re-runs the installer from anywhere. panama test runs
the suite, which had no entry point at all -- 121 files that were the main safety
net in this repository and were invisible in it.

Writing that runner found three tests nothing was running.
calendar_agenda_bridge_test, home_assistant_bridge_test and kdeconnect_bridge_test
are unittest suites without the executable bit, so no contract invoked them and
the first draft of the runner skipped them silently. All three pass, and have
passed unobserved for weeks. The runner collects *_test.py as well now, because a
runner with a blind spot is worse than no runner for the same reason a dependency
checker with one is: it reports PASS.

Six worktrees pruned. Each was re-checked rather than trusted to the spec's list,
and two needed it: panama-commands is not on feat/panama-commands but on
feat/gnome-tweaks-parity, and fix/panama-displays-review reads [ahead 3] -- ahead
of its remote, not of main, with every commit patch-equivalent to landed work.
roadmap-completion stays; it has five commits that are genuinely unlanded. The
branches are left alone: pruning a worktree costs nothing, deleting a branch is a
decision.

121 contracts pass.

Claude-Session: https://claude.ai/code/session_01NvgBuSWB5sE43yWmg21ozj
This commit is contained in:
Gabriel Brown
2026-08-20 21:55:55 -04:00
parent 47f29f9fa9
commit e1faaf7a76
185 changed files with 533 additions and 377 deletions
+19 -4
View File
@@ -78,7 +78,7 @@ Log in as **"Hyprland (uwsm-managed)"**, not plain "Hyprland".
## Layout
```
bin/ Small user-facing commands on PATH
bin/ Small user-facing commands on PATH; `panama` is the entry point
config/
bash/ .bashrc, aliases, env (env is gitignored)
copy/ Files copied verbatim over / (needs sudo)
@@ -96,11 +96,12 @@ docs/ Settings reference, and the design specs behind the work
## Tests
121 of them, under `tests/`, and each is a plain executable you can run on its
own:
121 of them, under `tests/`. Run the lot, or a subset by pattern:
```sh
bash tests/setup/interview-contract
panama test # everything
panama test dock # just the ones matching "dock"
tests/setup/interview-contract # or one directly; they are plain executables
```
They are called contracts rather than unit tests because that is what they are:
@@ -116,3 +117,17 @@ tests/setup/ The installer: the interview, package lists, hardware, extras
tests/quickshell/ The shell and its settings pages
tests/hypr/ The compositor config
```
## The `panama` command
```sh
panama update # review, commit and sync this repo
panama edit # open it in Neovim
panama doctor # what is actually running, not what was installed
panama test # every contract, or a subset by pattern
panama upgrade # re-run ./install from anywhere
```
None of the scripts in this repository carry a `.sh` extension. A shebang and
the executable bit already select the interpreter, and the extension only
becomes something to keep in sync — which it did not stay.
+109
View File
@@ -7,6 +7,9 @@
# Commands:
# update Commit & sync local changes (or just pull if clean)
# edit Open the Panama repo in Neovim
# doctor Report what is actually running on this machine
# test Run every contract under tests/
# upgrade Re-run the installer from anywhere
# help Show this help
#
# Designed to grow: add new subcommands as cmd_<name> functions and
@@ -62,6 +65,12 @@ ${BOLD}Commands:${RESET}
${GREEN}update${RESET} Review, commit & sync local changes. If the working tree is
clean it simply runs 'git pull'.
${GREEN}edit${RESET} Open the Panama repo in Neovim.
${GREEN}doctor${RESET} Report what is actually running on this machine, rather
than what was installed. Takes --summary for one line per check.
${GREEN}test${RESET} Run every contract under tests/. Give it a pattern to run
a subset: 'panama test dock' runs the ones matching 'dock'.
${GREEN}upgrade${RESET} Re-run ./install from anywhere. Safe: every stage is
idempotent and this is the documented upgrade path.
${GREEN}help${RESET} Show this help (also -h, --help).
${BOLD}Options:${RESET}
@@ -71,6 +80,9 @@ ${BOLD}Options:${RESET}
${BOLD}Examples:${RESET}
$PROGRAM update
$PROGRAM edit
$PROGRAM doctor --summary
$PROGRAM test dock
$PROGRAM upgrade
EOF
}
@@ -205,6 +217,100 @@ cmd_edit() {
exec nvim .
}
# ----------------------------------------------------------------------------
# Command: doctor
# ----------------------------------------------------------------------------
#
# The health check already exists and the installer already runs it; what it did
# not have was a way to reach it from a terminal. Everything is passed straight
# through, so --summary and anything added later work without this knowing about
# them.
cmd_doctor() {
local doctor="$PANAMA_DIR/config/dot/quickshell/scripts/panama-doctor"
if [[ ! -x "$doctor" ]]; then
err "panama-doctor is missing from $doctor"
exit 1
fi
exec "$doctor" "$@"
}
# ----------------------------------------------------------------------------
# Command: test
# ----------------------------------------------------------------------------
#
# The contracts are the main safety net in this repository and had no entry
# point: 121 executables with no runner and no mention in the README, which is
# most of the way to not having them.
#
# Each runs in its own process and a failure does not stop the rest, because the
# useful output is the whole list of what is broken rather than the first thing
# that broke. The exit code is what a caller can act on.
cmd_test() {
local pattern="${1:-}"
local -a suite=()
# Executables, plus the Python suites. Those are unittest files rather than
# executables, and collecting only what has the executable bit would skip them
# without saying so -- which is how all three came to be run by nothing at all.
# A runner with a blind spot is worse than no runner, because it reports PASS.
while IFS= read -r path; do
[[ -x "$path" || "$path" == *_test.py ]] || continue
[[ -z "$pattern" || "$path" == *"$pattern"* ]] && suite+=("$path")
done < <(find "$PANAMA_DIR/tests" -type f -not -path '*/fixtures/*' -not -path '*__pycache__*' | sort)
if (( ${#suite[@]} == 0 )); then
err "No contracts match '${pattern}'"
exit 1
fi
info "Running ${#suite[@]} contract(s)"
local -a failed=()
local path name
local -a runner
for path in "${suite[@]}"; do
name="${path#"$PANAMA_DIR"/tests/}"
if [[ "$path" == *_test.py ]]; then
runner=(python3 "$path")
else
runner=("$path")
fi
if "${runner[@]}" >/dev/null 2>&1; then
ok "$name"
else
err "$name"
failed+=("$name")
fi
done
header "Result"
if (( ${#failed[@]} == 0 )); then
ok "${#suite[@]} contract(s) passed"
return 0
fi
err "${#failed[@]} of ${#suite[@]} failed:"
printf ' %s\n' "${failed[@]}" >&2
warn "Run one on its own to see why: ${BOLD}${PANAMA_DIR}/tests/<name>${RESET}"
return 1
}
# ----------------------------------------------------------------------------
# Command: upgrade
# ----------------------------------------------------------------------------
#
# ./install is the upgrade path -- every stage is idempotent and re-running is
# the documented way to repair a machine. This only saves remembering where the
# repository lives.
cmd_upgrade() {
local installer="$PANAMA_DIR/install"
if [[ ! -x "$installer" ]]; then
err "The installer is missing from $installer"
exit 1
fi
info "Re-running ${BOLD}${installer}${RESET}"
cd "$PANAMA_DIR"
exec "$installer" "$@"
}
# ----------------------------------------------------------------------------
# Dispatcher
# ----------------------------------------------------------------------------
@@ -213,6 +319,9 @@ main() {
case "$cmd" in
update) shift; cmd_update "$@" ;;
edit) shift; cmd_edit "$@" ;;
doctor) shift; cmd_doctor "$@" ;;
test) shift; cmd_test "$@" ;;
upgrade) shift; cmd_upgrade "$@" ;;
help|-h|--help|"") usage ;;
--version) printf '%s %s\n' "$PROGRAM" "$VERSION" ;;
*)
+2 -2
View File
@@ -88,7 +88,7 @@ entry.
`prefs.lua` never raises. A missing, empty, truncated, malformed, or
wrong-typed settings file costs you your customizations and nothing else;
`tests/hypr/prefs-fallback-contract.sh` pins that, including that Hyprland still
`tests/hypr/prefs-fallback-contract` pins that, including that Hyprland still
accepts the config in each of those states.
### Adding a keybind: use `bind`, not `hl.bind`
@@ -120,7 +120,7 @@ Every `hl.bind` must pass a `description`. Hyprland reports Lua-defined binds
with dispatcher `__lua` and a bytecode offset as the argument, so a bind without
one has nothing readable beside its chord, and the Settings app drops it from the
Input & Shortcuts page rather than showing a mystery row.
`tests/quickshell/keybinds-contract.sh` fails if any bind lacks a description, so
`tests/quickshell/keybinds-contract` fails if any bind lacks a description, so
this cannot regress silently.
```lua
+1 -1
View File
@@ -1,5 +1,5 @@
// Exercises Migrations.applyWith against fixture steps and prints a verdict per
// case. Run by tests/quickshell/migrations-contract.sh.
// case. Run by tests/quickshell/migrations-contract.
//
// Fixture steps rather than the real list: the real one is empty until the
// first breaking schema change, and a mechanism that has never been run against
@@ -91,7 +91,7 @@ layout.
Mirrors must remain the same schema-backed control, never a second preference
or a copied default. Additions to this table require a concrete discoverability
reason and an update to `tests/quickshell/settings-ownership-contract.sh`.
reason and an update to `tests/quickshell/settings-ownership-contract`.
Window border color follows the same ownership rule. The inactive border is a
**scheme-relative role** owned by `ColorScheme.qml`: it changes only to retain
@@ -127,7 +127,7 @@ store. A row never needs to know which kind it holds.
the value in a different JSON field per type — `int`, `bool`, `float`, `str`,
and `css` for gaps (a four-value box). Declaring the wrong one does not fail
loudly: it makes every write to that key look *rejected*, and the user sees an
error for a change that worked. `tests/quickshell/schema-hypr-shape-contract.sh`
error for a change that worked. `tests/quickshell/schema-hypr-shape-contract`
asks the compositor for the real shape of every mapped option.
**Never trust an exit code from `hyprctl`.** `keyword` refuses to work on a
@@ -150,12 +150,12 @@ def build() -> dict[Path, str]:
files: dict[Path, str] = {}
for page, label in pages():
words = keywords_for(page, routing, schema, extras)
files[OUTPUT_DIR / f"settings-{page}.sh"] = command_for(page, label, words)
files[OUTPUT_DIR / f"settings-{page}"] = command_for(page, label, words)
return files
def existing() -> set[Path]:
return {path for path in OUTPUT_DIR.glob("settings-*.sh")}
return {path for path in OUTPUT_DIR.glob("settings-*")}
def main(arguments: list[str]) -> int:
+1 -1
View File
@@ -226,7 +226,7 @@ Singleton {
// A bind with no description cannot be presented usefully --
// the dispatcher is "__lua" and the argument is a bytecode
// offset. Showing the chord alone would be worse than omitting
// it, and tests/quickshell/keybinds-contract.sh fails the build
// it, and tests/quickshell/keybinds-contract fails the build
// if any exist, so this should never be reached in practice.
if (description === "")
continue;
@@ -33,8 +33,8 @@
- `config/dot/quickshell/scripts/calendar-agenda` — executable Python bridge; the only code that imports EDS libraries.
- `config/dot/quickshell/services/CalendarAgenda.qml` — singleton state consumed by shell UI; supervises the bridge and owns date-derived selectors.
- `tests/quickshell/calendar_agenda_bridge_test.py` — pure normalization and URL-policy tests using synthetic components only.
- `tests/quickshell/calendar-agenda-helper-contract.sh` — executable/probe/live-query contract that redacts live content.
- `tests/quickshell/calendar-agenda-contract.sh` — live Quickshell IPC/state contract using synthetic in-memory fixtures.
- `tests/quickshell/calendar-agenda-helper-contract` — executable/probe/live-query contract that redacts live content.
- `tests/quickshell/calendar-agenda-contract` — live Quickshell IPC/state contract using synthetic in-memory fixtures.
### Daybook presentation
@@ -67,7 +67,7 @@
**Files:**
- Create: `config/dot/quickshell/scripts/calendar-agenda`
- Create: `tests/quickshell/calendar_agenda_bridge_test.py`
- Create: `tests/quickshell/calendar-agenda-helper-contract.sh`
- Create: `tests/quickshell/calendar-agenda-helper-contract`
**Interfaces:**
- Consumes: enabled sources returned by `EDataServer.SourceRegistry.list_enabled(EDataServer.SOURCE_EXTENSION_CALENDAR)`.
@@ -229,7 +229,7 @@ Expected: four tests PASS.
- [x] **Step 5: Add the redacted live helper contract**
Create `tests/quickshell/calendar-agenda-helper-contract.sh` with:
Create `tests/quickshell/calendar-agenda-helper-contract` with:
```bash
#!/usr/bin/env bash
@@ -265,7 +265,7 @@ Make it executable and run it. Expected: PASS with counts only; no source names,
```bash
git add config/dot/quickshell/scripts/calendar-agenda \
tests/quickshell/calendar_agenda_bridge_test.py \
tests/quickshell/calendar-agenda-helper-contract.sh
tests/quickshell/calendar-agenda-helper-contract
git commit -m "Add the EDS calendar bridge"
```
@@ -275,7 +275,7 @@ git commit -m "Add the EDS calendar bridge"
**Files:**
- Create: `config/dot/quickshell/services/CalendarAgenda.qml`
- Create: `tests/quickshell/calendar-agenda-contract.sh`
- Create: `tests/quickshell/calendar-agenda-contract`
- Modify: `config/dot/quickshell/shell.qml`
**Interfaces:**
@@ -286,7 +286,7 @@ git commit -m "Add the EDS calendar bridge"
- [x] **Step 1: Write the failing live service contract**
Create `tests/quickshell/calendar-agenda-contract.sh` that first asserts the IPC target, loads fixture `daybook`, and validates only synthetic state:
Create `tests/quickshell/calendar-agenda-contract` that first asserts the IPC target, loads fixture `daybook`, and validates only synthetic state:
```bash
#!/usr/bin/env bash
@@ -317,7 +317,7 @@ printf 'calendar agenda contract: PASS\n'
- [x] **Step 2: Run the contract and verify RED**
Run `tests/quickshell/calendar-agenda-contract.sh`.
Run `tests/quickshell/calendar-agenda-contract`.
Expected: FAIL with `calendar IPC target is missing`.
@@ -385,8 +385,8 @@ Do not include titles, source names, locations, identifiers, or URLs in status o
Allow Quickshell to hot reload, then run:
```bash
tests/quickshell/calendar-agenda-contract.sh
tests/quickshell/calendar-agenda-helper-contract.sh
tests/quickshell/calendar-agenda-contract
tests/quickshell/calendar-agenda-helper-contract
qs log -n -t 80 --no-color | rg -i 'calendar|error|warn'
```
@@ -397,7 +397,7 @@ Expected: both contracts PASS; no calendar QML error or bridge restart loop.
```bash
git add config/dot/quickshell/services/CalendarAgenda.qml \
config/dot/quickshell/shell.qml \
tests/quickshell/calendar-agenda-contract.sh
tests/quickshell/calendar-agenda-contract
git commit -m "Add live calendar state to Quickshell"
```
@@ -410,7 +410,7 @@ git commit -m "Add live calendar state to Quickshell"
- Modify: `config/dot/quickshell/modules/bar/Clock.qml`
- Modify: `config/dot/quickshell/shell.qml`
- Modify: `config/dot/quickshell/modules/datemenu/CalendarGrid.qml`
- Modify: `tests/quickshell/calendar-agenda-contract.sh`
- Modify: `tests/quickshell/calendar-agenda-contract`
**Interfaces:**
- Consumes: `CalendarAgenda.selectDate(date)` and `CalendarAgenda.markersForDate(date)`.
@@ -489,7 +489,7 @@ Month changes call `visibleMonthChanged(viewYear, viewMonth)`. Adjacent-month da
Run:
```bash
tests/quickshell/calendar-agenda-contract.sh
tests/quickshell/calendar-agenda-contract
rg -q 'markersForDate' config/dot/quickshell/modules/datemenu/CalendarGrid.qml
rg -q 'dateActivated' config/dot/quickshell/modules/datemenu/CalendarGrid.qml
```
@@ -503,7 +503,7 @@ git add config/dot/quickshell/services/ShellState.qml \
config/dot/quickshell/modules/bar/Clock.qml \
config/dot/quickshell/shell.qml \
config/dot/quickshell/modules/datemenu/CalendarGrid.qml \
tests/quickshell/calendar-agenda-contract.sh
tests/quickshell/calendar-agenda-contract
git commit -m "Route the interactive Panama date menu"
```
@@ -519,7 +519,7 @@ git commit -m "Route the interactive Panama date menu"
- Modify: `config/dot/quickshell/modules/datemenu/DateMenu.qml`
- Modify: `config/dot/quickshell/modules/datemenu/MediaCard.qml`
- Modify: `config/dot/quickshell/modules/datemenu/qmldir`
- Modify: `tests/quickshell/calendar-agenda-contract.sh`
- Modify: `tests/quickshell/calendar-agenda-contract`
**Interfaces:**
- Consumes: `CalendarAgenda.selectedEvents`, `nextEventForSelectedDate`, `phase`, and action functions.
@@ -623,7 +623,7 @@ Run:
```bash
qs ipc call calendar-agenda fixture daybook
qs ipc call calendar-agenda open
tests/quickshell/calendar-agenda-contract.sh
tests/quickshell/calendar-agenda-contract
```
Capture a temporary full-screen screenshot with `grim`, inspect the Daybook at original detail, and verify:
@@ -641,7 +641,7 @@ Close the panel and reset fixture mode after inspection. Do not add screenshots
```bash
git add config/dot/quickshell/modules/datemenu \
tests/quickshell/calendar-agenda-contract.sh
tests/quickshell/calendar-agenda-contract
git commit -m "Build the Prism calendar Daybook"
```
@@ -653,7 +653,7 @@ git commit -m "Build the Prism calendar Daybook"
- Create: `config/dot/quickshell/modules/bar/CalendarIndicator.qml`
- Modify: `config/dot/quickshell/modules/bar/Bar.qml`
- Modify: `config/dot/quickshell/services/CalendarAgenda.qml`
- Modify: `tests/quickshell/calendar-agenda-contract.sh`
- Modify: `tests/quickshell/calendar-agenda-contract`
**Interfaces:**
- Consumes: `CalendarAgenda.capsuleVisible`, `capsuleText`, and `nextEvent`.
@@ -693,8 +693,8 @@ Use a single 120 ms opacity/width entrance tied to visibility. No looping animat
- [x] **Step 4: Run capsule and full shell contracts**
```bash
tests/quickshell/calendar-agenda-contract.sh
for test in tests/quickshell/*.sh; do "$test"; done
tests/quickshell/calendar-agenda-contract
for test in tests/quickshell/*; do "$test"; done
```
Expected: calendar fixture boundaries PASS and every existing Quickshell contract remains green.
@@ -705,7 +705,7 @@ Expected: calendar fixture boundaries PASS and every existing Quickshell contrac
git add config/dot/quickshell/modules/bar/CalendarIndicator.qml \
config/dot/quickshell/modules/bar/Bar.qml \
config/dot/quickshell/services/CalendarAgenda.qml \
tests/quickshell/calendar-agenda-contract.sh
tests/quickshell/calendar-agenda-contract
git commit -m "Add the quiet calendar capsule"
```
@@ -745,7 +745,7 @@ Remove `qrencode` from `setup/packages/hyprland-packages` only if `rg -n qrencod
- [x] **Step 2: Run static verification**
```bash
bash -n tests/quickshell/*.sh config/dot/quickshell/scripts/screen-intelligence
bash -n tests/quickshell/* config/dot/quickshell/scripts/screen-intelligence
python3 -c 'compile(open("config/dot/quickshell/scripts/calendar-agenda", encoding="utf-8").read(), "calendar-agenda", "exec")'
python3 tests/quickshell/calendar_agenda_bridge_test.py
desktop-file-validate config/local/share/applications/*.desktop
@@ -758,7 +758,7 @@ Expected: every command exits 0 and Hyprland reports `config ok`.
- [x] **Step 3: Run every Quickshell contract**
```bash
for test in tests/quickshell/*.sh; do
for test in tests/quickshell/*; do
"$test"
done
```
@@ -24,7 +24,7 @@
**Files:**
- Create: `config/dot/quickshell/services/StatusEvents.qml`
- Modify: `config/dot/quickshell/shell.qml`
- Test: `tests/quickshell/status-events-contract.sh`
- Test: `tests/quickshell/status-events-contract`
**Interfaces:**
- Produces: `publish(event: var)`, `dismiss(): void`, `invoke(): void`, `activeEvent`, `active`, and IPC diagnostics.
@@ -61,7 +61,7 @@
- Modify: `config/dot/quickshell/services/Capture.qml`
- Modify: `config/dot/quickshell/services/NightLight.qml`
- Modify: `config/dot/quickshell/services/FocusSession.qml`
- Test: `tests/quickshell/activity-state-contract.sh`
- Test: `tests/quickshell/activity-state-contract`
**Interfaces:**
- Produces: `PrivacyState.microphoneActive`, `cameraActive`, `screenSharingActive`, `recordingActive`, `activeKinds`, and transition events.
@@ -23,7 +23,7 @@
**Files:**
- Modify: `config/dot/quickshell/modules/overview/OverviewBody.qml`
- Test: `tests/quickshell/overview-window-actions-contract.sh`
- Test: `tests/quickshell/overview-window-actions-contract`
**Interfaces:**
- Produces: `addressOf(toplevel)`, `closeToplevel(toplevel)`, `moveToplevel(toplevel, workspaceName)`, and `restoreToplevel(toplevel)`.
@@ -53,7 +53,7 @@
**Files:**
- Create: `config/dot/quickshell/modules/overview/ScratchpadShelf.qml`
- Modify: `config/dot/quickshell/modules/overview/OverviewBody.qml`
- Test: `tests/quickshell/scratchpad-shelf-contract.sh`
- Test: `tests/quickshell/scratchpad-shelf-contract`
**Interfaces:**
- Consumes: Hyprland workspace named `special:scratch` and OverviewBody move/restore callbacks.
@@ -31,14 +31,14 @@
- `config/dot/quickshell/scripts/panama-home-assistant` — credential-safe catalog, action authorization, brightness parsing, and Home Assistant REST calls.
- `tests/quickshell/home_assistant_bridge_test.py` — fake-server unit tests for filtering, normalization, authorization, payloads, and redaction.
- `tests/quickshell/home-assistant-helper-contract.sh` — live read-only probe/catalog shape check; it never invokes an action command.
- `tests/quickshell/home-assistant-helper-contract` — live read-only probe/catalog shape check; it never invokes an action command.
- `config/dot/quickshell/config/HomePreferences.qml` — sole durable owner of initialization state and ordered `{id, alias}` favorites.
- `config/dot/quickshell/config/qmldir` — registers `HomePreferences` as a singleton.
- `config/dot/quickshell/home-preferences-harness.qml` — isolated IPC surface for preference mutation and restart tests.
- `tests/quickshell/home-preferences-contract.sh` — first-run, empty-state, alias, reorder, remove, and restart-persistence contract.
- `tests/quickshell/home-preferences-contract` — first-run, empty-state, alias, reorder, remove, and restart-persistence contract.
- `config/dot/quickshell/services/HomeAssistant.qml` — complete catalog, preference resolution, four-item shelf, fixtures, sequential action queue, and per-entity pending/error maps.
- `config/dot/quickshell/shell.qml` — typed Home Assistant diagnostics/actions for fixture-only testing and Home & Phone routing.
- `tests/quickshell/control-center-services-contract.sh` — service-model and per-light action-state contract using fixtures only.
- `tests/quickshell/control-center-services-contract` — service-model and per-light action-state contract using fixtures only.
- `config/dot/quickshell/services/SystemSettings.qml` — BlueBubbles installed-state query and fixed allow-listed launch vector.
- `config/dot/quickshell/modules/settings/HomePhonePage.qml` — page composition, connection health, search, selected/available sections, save error, and phone continuity.
- `config/dot/quickshell/modules/settings/HomeFavoriteCard.qml` — editable alias, source name, first-four badge, remove action, and drag handle.
@@ -47,14 +47,14 @@
- `config/dot/quickshell/modules/settings/SettingsShell.qml` — page loader registration.
- `config/dot/quickshell/modules/settings/qmldir` — component registrations.
- `config/dot/quickshell/services/ShellState.qml``home-phone` settings-page allow-list entry.
- `tests/quickshell/settings-pages-contract.sh` — route and single-window behavior.
- `tests/quickshell/home-phone-settings-contract.sh` — static and fixture-driven settings-page behavior without writing the user's real preferences.
- `tests/quickshell/settings-pages-contract` — route and single-window behavior.
- `tests/quickshell/home-phone-settings-contract` — static and fixture-driven settings-page behavior without writing the user's real preferences.
- `config/dot/quickshell/modules/quicksettings/HomeBrightnessSlider.qml` — local preview and one-shot commit interaction.
- `config/dot/quickshell/modules/quicksettings/HomeTile.qml` — polished power, state, percent, dimmer, busy, and inline-error presentation.
- `config/dot/quickshell/modules/quicksettings/HomeControls.qml` — resting/expanded shelf, setup state, stale state, and Manage in Settings row.
- `config/dot/quickshell/modules/quicksettings/PhoneControls.qml` — four equal actions and independent Messages enablement.
- `tests/quickshell/control-center-contract.sh` — mapped panel, exclusive expansion, component presence, and approved shelf structure.
- `tests/quickshell/phone-messages-contract.sh` — BlueBubbles detection/allow-list/independent-enable contract; it never invokes the action.
- `tests/quickshell/control-center-contract` — mapped panel, exclusive expansion, component presence, and approved shelf structure.
- `tests/quickshell/phone-messages-contract` — BlueBubbles detection/allow-list/independent-enable contract; it never invokes the action.
---
@@ -63,7 +63,7 @@
**Files:**
- Modify: `config/dot/quickshell/scripts/panama-home-assistant:44-434`
- Modify: `tests/quickshell/home_assistant_bridge_test.py:25-182`
- Modify: `tests/quickshell/home-assistant-helper-contract.sh:1-29`
- Modify: `tests/quickshell/home-assistant-helper-contract:1-29`
**Interfaces:**
- Consumes: `Config(base_url: str, token: str, entity_ids: tuple[str, ...])`, `request_json(config, method, path, payload)` and current URL/token/legacy resolution.
@@ -225,7 +225,7 @@ Do not print the discovery response, request body, URL, or token on action failu
- [x] **Step 6: Make unit and live read-only contracts GREEN**
Update `home-assistant-helper-contract.sh` to call `catalog`, assert the exact seven entity keys, assert `legacyEntityIds` is an array, and report only the count:
Update `home-assistant-helper-contract` to call `catalog`, assert the exact seven entity keys, assert `legacyEntityIds` is an array, and report only the count:
```bash
catalog="$($helper catalog)"
@@ -242,7 +242,7 @@ Run:
```bash
python3 tests/quickshell/home_assistant_bridge_test.py -v
tests/quickshell/home-assistant-helper-contract.sh
tests/quickshell/home-assistant-helper-contract
```
Expected: all unit tests PASS; the live contract prints a redacted light count and performs GET requests only.
@@ -252,7 +252,7 @@ Expected: all unit tests PASS; the live contract prints a redacted light count a
```bash
git add config/dot/quickshell/scripts/panama-home-assistant \
tests/quickshell/home_assistant_bridge_test.py \
tests/quickshell/home-assistant-helper-contract.sh
tests/quickshell/home-assistant-helper-contract
git commit -m "Add Home Assistant light catalog and dimming"
```
@@ -264,7 +264,7 @@ git commit -m "Add Home Assistant light catalog and dimming"
- Create: `config/dot/quickshell/config/HomePreferences.qml`
- Modify: `config/dot/quickshell/config/qmldir:1-4`
- Create: `config/dot/quickshell/home-preferences-harness.qml`
- Create: `tests/quickshell/home-preferences-contract.sh`
- Create: `tests/quickshell/home-preferences-contract`
**Interfaces:**
- Consumes: top-level helper field `legacyEntityIds: string[]` after the first successful catalog.
@@ -307,7 +307,7 @@ Then remove both records, restart again, call `initialize` with a different lega
Run:
```bash
tests/quickshell/home-preferences-contract.sh
tests/quickshell/home-preferences-contract
```
Expected: FAIL because the singleton and harness do not exist.
@@ -344,7 +344,7 @@ Use a 180 ms single-shot persistence timer. `initialize()` filters IDs through `
Run:
```bash
tests/quickshell/home-preferences-contract.sh
tests/quickshell/home-preferences-contract
```
Expected: PASS for initial migration, trim, reorder, remove, restart persistence, and initialized-empty behavior. The temporary file is valid JSON and contains no credential-like fields.
@@ -355,7 +355,7 @@ Expected: PASS for initial migration, trim, reorder, remove, restart persistence
git add config/dot/quickshell/config/HomePreferences.qml \
config/dot/quickshell/config/qmldir \
config/dot/quickshell/home-preferences-harness.qml \
tests/quickshell/home-preferences-contract.sh
tests/quickshell/home-preferences-contract
git commit -m "Persist Home accessory preferences"
```
@@ -366,7 +366,7 @@ git commit -m "Persist Home accessory preferences"
**Files:**
- Modify: `config/dot/quickshell/services/HomeAssistant.qml:1-185`
- Modify: `config/dot/quickshell/shell.qml:252-272`
- Modify: `tests/quickshell/control-center-services-contract.sh:10-90`
- Modify: `tests/quickshell/control-center-services-contract:10-90`
**Interfaces:**
- Consumes: helper `catalog`, `toggle ENTITY_ID`, and `brightness ENTITY_ID PERCENT`; all `HomePreferences` interfaces from Task 2.
@@ -394,7 +394,7 @@ Add `missing-selected` and `action-error` fixtures. `missing-selected` retains o
Run:
```bash
tests/quickshell/control-center-services-contract.sh
tests/quickshell/control-center-services-contract
```
Expected: the new catalog counts, selected IDs, brightness fixture action, and per-entity errors are absent.
@@ -480,8 +480,8 @@ Fixture actions update only in-memory fixture catalog. `clearFixture()` clears f
Run:
```bash
tests/quickshell/home-preferences-contract.sh
tests/quickshell/control-center-services-contract.sh
tests/quickshell/home-preferences-contract
tests/quickshell/control-center-services-contract
```
Expected: both PASS; fixture cleanup returns live mode and the durable preference contract remains unchanged.
@@ -491,7 +491,7 @@ Expected: both PASS; fixture cleanup returns live mode and the durable preferenc
```bash
git add config/dot/quickshell/services/HomeAssistant.qml \
config/dot/quickshell/shell.qml \
tests/quickshell/control-center-services-contract.sh
tests/quickshell/control-center-services-contract
git commit -m "Compose Home catalog with accessory preferences"
```
@@ -509,8 +509,8 @@ git commit -m "Compose Home catalog with accessory preferences"
- Modify: `config/dot/quickshell/modules/settings/qmldir:1-19`
- Modify: `config/dot/quickshell/services/ShellState.qml:94-99`
- Modify: `config/dot/quickshell/shell.qml:274-299`
- Modify: `tests/quickshell/settings-pages-contract.sh:15-28`
- Create: `tests/quickshell/home-phone-settings-contract.sh`
- Modify: `tests/quickshell/settings-pages-contract:15-28`
- Create: `tests/quickshell/home-phone-settings-contract`
**Interfaces:**
- Consumes: `HomeAssistant.catalog`, `selectedEntities`, `discoveredCount`, phase/stale/error, `refresh()`, `open()`; all `HomePreferences` mutators; `SystemSettings.bluebubblesAvailable` and `openApplication("bluebubbles")`.
@@ -539,8 +539,8 @@ Using the ready fixture, route Settings to `home-phone` and assert one tiled `Pa
Run:
```bash
tests/quickshell/settings-pages-contract.sh
tests/quickshell/home-phone-settings-contract.sh
tests/quickshell/settings-pages-contract
tests/quickshell/home-phone-settings-contract
```
Expected: `home-phone` falls back to Home and the new components are missing.
@@ -629,10 +629,10 @@ Extend settings diagnostics with read-only counts:
Run:
```bash
tests/quickshell/settings-system-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/home-phone-settings-contract.sh
tests/quickshell/home-preferences-contract.sh
tests/quickshell/settings-system-contract
tests/quickshell/settings-pages-contract
tests/quickshell/home-phone-settings-contract
tests/quickshell/home-preferences-contract
```
Expected: all PASS; Panama Settings remains one normal tiled client, fixture tests leave real Home preferences unchanged, and no BlueBubbles process starts.
@@ -649,8 +649,8 @@ git add config/dot/quickshell/services/SystemSettings.qml \
config/dot/quickshell/modules/settings/qmldir \
config/dot/quickshell/services/ShellState.qml \
config/dot/quickshell/shell.qml \
tests/quickshell/settings-pages-contract.sh \
tests/quickshell/home-phone-settings-contract.sh
tests/quickshell/settings-pages-contract \
tests/quickshell/home-phone-settings-contract
git commit -m "Add Home and Phone settings"
```
@@ -663,7 +663,7 @@ git commit -m "Add Home and Phone settings"
- Modify: `config/dot/quickshell/modules/quicksettings/HomeTile.qml:1-73`
- Modify: `config/dot/quickshell/modules/quicksettings/HomeControls.qml:1-280`
- Modify: `config/dot/quickshell/modules/quicksettings/qmldir`
- Modify: `tests/quickshell/control-center-contract.sh:19-72`
- Modify: `tests/quickshell/control-center-contract:19-72`
**Interfaces:**
- Consumes: `HomeAssistant.visibleEntities`, `selectedEntities`, `isBusy(id)`, `pendingFor(id)`, `errorFor(id)`, `toggleEntity(id)`, `setBrightness(id, percent)`, phase/stale, refresh/open; `ShellState.openSettings("home-phone")`.
@@ -689,7 +689,7 @@ Keep the live panel mapping and exclusive expansion assertions. Add ready-fixtur
Run:
```bash
tests/quickshell/control-center-contract.sh
tests/quickshell/control-center-contract
```
Expected: the two-column shelf, slider, and Home & Phone management route are absent.
@@ -733,8 +733,8 @@ At the expanded list footer add `Manage in Settings`, which closes Control Cente
Run:
```bash
tests/quickshell/control-center-services-contract.sh
tests/quickshell/control-center-contract.sh
tests/quickshell/control-center-services-contract
tests/quickshell/control-center-contract
```
Expected: PASS. Opening and expanding Home maps one panel, displays the fixture shelf, and does not invoke the real Home Assistant API.
@@ -746,7 +746,7 @@ git add config/dot/quickshell/modules/quicksettings/HomeBrightnessSlider.qml \
config/dot/quickshell/modules/quicksettings/HomeTile.qml \
config/dot/quickshell/modules/quicksettings/HomeControls.qml \
config/dot/quickshell/modules/quicksettings/qmldir \
tests/quickshell/control-center-contract.sh
tests/quickshell/control-center-contract
git commit -m "Build the Home accessory shelf"
```
@@ -756,8 +756,8 @@ git commit -m "Build the Home accessory shelf"
**Files:**
- Modify: `config/dot/quickshell/modules/quicksettings/PhoneControls.qml:1-273`
- Create: `tests/quickshell/phone-messages-contract.sh`
- Modify: `tests/quickshell/control-center-contract.sh:41-72`
- Create: `tests/quickshell/phone-messages-contract`
- Modify: `tests/quickshell/control-center-contract:41-72`
**Interfaces:**
- Consumes: `SystemSettings.bluebubblesAvailable`, `SystemSettings.openApplication("bluebubbles")`, and existing KDE Connect capability/reachability/action interfaces.
@@ -774,7 +774,7 @@ Add a guard that fails if the script contains `openApplication` in an executed `
Run:
```bash
tests/quickshell/phone-messages-contract.sh
tests/quickshell/phone-messages-contract
```
Expected: FAIL because PhoneControls still has three KDE-only actions.
@@ -803,9 +803,9 @@ When BlueBubbles is absent, append one quiet detail row: `BlueBubbles is not ins
Run:
```bash
tests/quickshell/phone-messages-contract.sh
tests/quickshell/control-center-contract.sh
tests/quickshell/control-center-services-contract.sh
tests/quickshell/phone-messages-contract
tests/quickshell/control-center-contract
tests/quickshell/control-center-services-contract
```
Expected: PASS; the offline KDE fixture still exposes an enabled Messages action when BlueBubbles is installed, and no client launches during testing.
@@ -814,8 +814,8 @@ Expected: PASS; the offline KDE fixture still exposes an enabled Messages action
```bash
git add config/dot/quickshell/modules/quicksettings/PhoneControls.qml \
tests/quickshell/phone-messages-contract.sh \
tests/quickshell/control-center-contract.sh
tests/quickshell/phone-messages-contract \
tests/quickshell/control-center-contract
git commit -m "Add BlueBubbles to Phone controls"
```
@@ -850,14 +850,14 @@ Run:
```bash
python3 tests/quickshell/home_assistant_bridge_test.py -v
tests/quickshell/home-assistant-helper-contract.sh
tests/quickshell/home-preferences-contract.sh
tests/quickshell/control-center-services-contract.sh
tests/quickshell/home-phone-settings-contract.sh
tests/quickshell/phone-messages-contract.sh
tests/quickshell/control-center-contract.sh
tests/quickshell/settings-system-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/home-assistant-helper-contract
tests/quickshell/home-preferences-contract
tests/quickshell/control-center-services-contract
tests/quickshell/home-phone-settings-contract
tests/quickshell/phone-messages-contract
tests/quickshell/control-center-contract
tests/quickshell/settings-system-contract
tests/quickshell/settings-pages-contract
```
Expected: every command exits 0. The helper contract performs read-only GETs; fixtures perform no real light action; BlueBubbles remains closed unless it was already open.
@@ -867,7 +867,7 @@ Expected: every command exits 0. The helper contract performs read-only GETs; fi
Run:
```bash
for test in tests/quickshell/*contract.sh; do
for test in tests/quickshell/*contract; do
printf 'Running %s\n' "$test"
"$test"
done
@@ -34,7 +34,7 @@ correctness bug in shipped behavior and does not depend on any of the
architecture below.
**Files:** Modify `config/dot/quickshell/services/SystemSettings.qml`;
Test `tests/quickshell/settings-hyprland-write-contract.sh`
Test `tests/quickshell/settings-hyprland-write-contract`
- [x] Write a contract that sets a display policy through `SystemSettings`, then
asserts via `hyprctl getoption` that the compositor value actually changed —
@@ -58,9 +58,9 @@ holds the group/key/option path and allow-list per option, so the UI never names
an option or supplies an unchecked value. Policy is applied as one batch, so the
shell cannot come up half-configured.
New: `tests/quickshell/settings-hyprland-write-contract.sh` — flips each policy
New: `tests/quickshell/settings-hyprland-write-contract` — flips each policy
to a value it does not hold and reads it back, so a no-op write cannot pass.
The pre-existing `settings-system-contract.sh` re-applied the values already in
The pre-existing `settings-system-contract` re-applied the values already in
place, which is why it passed throughout the outage.
---
@@ -70,7 +70,7 @@ place, which is why it passed throughout the outage.
**Files:** Create `config/dot/quickshell/config/PreferenceSchema.qml`;
Modify `config/dot/quickshell/config/DesktopPreferences.qml`,
`config/dot/quickshell/config/Settings.qml`;
Test `tests/quickshell/preference-schema-contract.sh`
Test `tests/quickshell/preference-schema-contract`
Schema entry shape:
@@ -93,8 +93,8 @@ Schema entry shape:
file from `Quickshell.stateDir` on first run if present.
- [x] Keep `Settings.qml` as the stable public read surface; existing consumers
must not change.
- [x] Run the new contract plus `settings-preferences-contract.sh` and
`settings-pages-contract.sh` to green.
- [x] Run the new contract plus `settings-preferences-contract` and
`settings-pages-contract` to green.
**Exit criteria:** adding a setting is one schema line; reset is complete by
construction; the store lives at a stable, user-visible path.
@@ -116,7 +116,7 @@ absent, and never deletes the original. Verified live: the running shell adopted
all 17 values into `~/.config/panama/settings.json` with the legacy files intact.
New: `config/PreferenceSchema.qml`, `preference-schema-harness.qml`,
`tests/quickshell/preference-schema-contract.sh`. Full suite green — 6 settings
`tests/quickshell/preference-schema-contract`. Full suite green — 6 settings
contracts, 22 other Quickshell contracts, 3 Python bridge tests.
---
@@ -125,7 +125,7 @@ contracts, 22 other Quickshell contracts, 3 Python bridge tests.
**Files:** Create `config/dot/hypr/prefs.lua`;
Modify `config/dot/hypr/hyprland.lua`, `looks.lua`, `input.lua`, `monitors.lua`;
Test `tests/hypr/prefs-fallback-contract.sh`
Test `tests/hypr/prefs-fallback-contract`
- [x] Write a contract that verifies `Hyprland --verify-config` passes with the
file absent, empty, truncated mid-object, and containing wrong-typed values —
@@ -228,7 +228,7 @@ Four things found by building it:
what getoption answers with, not what the setting means, and getting it wrong
does not fail loudly — it makes every write to that key look rejected. The user
saw "Hyprland did not apply Hide pointer after" for a change that worked.
`tests/quickshell/schema-hypr-shape-contract.sh` now asks the compositor for
`tests/quickshell/schema-hypr-shape-contract` now asks the compositor for
the real shape of all 23 mapped options.
* The Settings window is a normal tiled window, so `implicitWidth: 1120` is only
a hint and rows must survive ~400px. `SliderRow` stacks its control under the
@@ -244,7 +244,7 @@ Four things found by building it:
## Stage 4 — Shortcuts from the compositor
**Files:** Create `services/Keybinds.qml`; Modify `modules/settings/ShortcutsPage.qml`,
`config/dot/hypr/keybinds.lua`; Test `tests/quickshell/keybinds-contract.sh`
`config/dot/hypr/keybinds.lua`; Test `tests/quickshell/keybinds-contract`
- [x] Write a contract asserting the page's bind count matches `hyprctl binds -j`
exactly, so it can never drift again.
@@ -266,7 +266,7 @@ Grouping is derived from each bind's own description rather than a table here, s
adding a bind puts it in the right section automatically. Hyprland reports
Lua-defined binds with dispatcher `__lua` and a bytecode offset as the argument,
so a bind without a description has nothing readable beside its chord; the
service drops those, and `tests/quickshell/keybinds-contract.sh` fails if any
service drops those, and `tests/quickshell/keybinds-contract` fails if any
exist so that dropping can never be silent.
Input settings are on the same page and are now real controls: keyboard repeat,
@@ -33,14 +33,14 @@
- `config/dot/quickshell/scripts/panama-kdeconnect` — validates device/file inputs, normalizes device/plugin status, and invokes allow-listed actions.
- `tests/quickshell/kdeconnect_bridge_test.py` — pure parser, capability, validation, and command tests with fake runners.
- `tests/quickshell/kdeconnect-helper-contract.sh` — live read-only status contract with names and IDs redacted.
- `tests/quickshell/kdeconnect-helper-contract` — live read-only status contract with names and IDs redacted.
- `config/dot/quickshell/services/KdeConnect.qml` — singleton device, action, transfer, fixture, and recent-exchange state.
### Home Assistant boundary
- `config/dot/quickshell/scripts/panama-home-assistant` — configuration resolution, normalized REST reads, allow-listed toggles, and URL handoff.
- `tests/quickshell/home_assistant_bridge_test.py` — local fake API and credential/configuration precedence tests.
- `tests/quickshell/home-assistant-helper-contract.sh` — live read-only probe/snapshot contract with entity content redacted.
- `tests/quickshell/home-assistant-helper-contract` — live read-only probe/snapshot contract with entity content redacted.
- `config/dot/quickshell/services/HomeAssistant.qml` — singleton entities, stale state, per-entity action state, fixture, and inline errors.
### Control Center presentation and integration
@@ -58,8 +58,8 @@
- `config/dot/quickshell/services/Ongoing.qml` — append and control one running phone transfer.
- `config/dot/quickshell/services/StatusEvents.qml` — open a completed received/sent path through the existing allow-listed action.
- `config/dot/quickshell/shell.qml` — diagnostics/fixture IPC for the two services.
- `tests/quickshell/control-center-services-contract.sh` — deterministic service, activity, and event contract.
- `tests/quickshell/control-center-contract.sh` — panel geometry, routing, components, and live layer contract.
- `tests/quickshell/control-center-services-contract` — deterministic service, activity, and event contract.
- `tests/quickshell/control-center-contract` — panel geometry, routing, components, and live layer contract.
### Documentation
@@ -73,7 +73,7 @@
**Files:**
- Create: `config/dot/quickshell/scripts/panama-kdeconnect`
- Create: `tests/quickshell/kdeconnect_bridge_test.py`
- Create: `tests/quickshell/kdeconnect-helper-contract.sh`
- Create: `tests/quickshell/kdeconnect-helper-contract`
**Interfaces:**
- Produces: `panama-kdeconnect status` JSON with `available` and `devices`.
@@ -185,7 +185,7 @@ Expected: all cases PASS with no device name, address, or file path printed by t
- [ ] **Step 5: Add and run the redacted live contract**
Create `tests/quickshell/kdeconnect-helper-contract.sh` that runs `status` and asserts:
Create `tests/quickshell/kdeconnect-helper-contract` that runs `status` and asserts:
```bash
jq -e '
@@ -203,7 +203,7 @@ Print only `PASS (N paired, N reachable; identities redacted)`.
```bash
git add config/dot/quickshell/scripts/panama-kdeconnect \
tests/quickshell/kdeconnect_bridge_test.py \
tests/quickshell/kdeconnect-helper-contract.sh
tests/quickshell/kdeconnect-helper-contract
git commit -m "Add the Panama KDE Connect bridge"
```
@@ -214,7 +214,7 @@ git commit -m "Add the Panama KDE Connect bridge"
**Files:**
- Create: `config/dot/quickshell/scripts/panama-home-assistant`
- Create: `tests/quickshell/home_assistant_bridge_test.py`
- Create: `tests/quickshell/home-assistant-helper-contract.sh`
- Create: `tests/quickshell/home-assistant-helper-contract`
**Interfaces:**
- Produces: `probe`, `snapshot`, `toggle ENTITY_ID`, and `open`.
@@ -348,7 +348,7 @@ The contract runs `probe` and `snapshot`, validates the schema, and prints only
```bash
git add config/dot/quickshell/scripts/panama-home-assistant \
tests/quickshell/home_assistant_bridge_test.py \
tests/quickshell/home-assistant-helper-contract.sh
tests/quickshell/home-assistant-helper-contract
git commit -m "Add the Panama Home Assistant bridge"
```
@@ -359,7 +359,7 @@ git commit -m "Add the Panama Home Assistant bridge"
**Files:**
- Create: `config/dot/quickshell/services/KdeConnect.qml`
- Create: `config/dot/quickshell/services/HomeAssistant.qml`
- Create: `tests/quickshell/control-center-services-contract.sh`
- Create: `tests/quickshell/control-center-services-contract`
- Modify: `config/dot/quickshell/services/DeviceEvents.qml`
- Modify: `config/dot/quickshell/services/Ongoing.qml`
- Modify: `config/dot/quickshell/shell.qml`
@@ -396,7 +396,7 @@ Cleanup resets both fixture modes and closes Quick Settings.
- [ ] **Step 2: Run the contract and verify RED**
Run `tests/quickshell/control-center-services-contract.sh`.
Run `tests/quickshell/control-center-services-contract`.
Expected: FAIL because the IPC targets do not exist.
@@ -456,7 +456,7 @@ Run the repository's established shell reload command, wait for the current
instance to report IPC, then run:
```bash
tests/quickshell/control-center-services-contract.sh
tests/quickshell/control-center-services-contract
```
Expected: PASS with fixture state only and no QML warnings in the fresh journal.
@@ -469,7 +469,7 @@ git add config/dot/quickshell/services/KdeConnect.qml \
config/dot/quickshell/services/DeviceEvents.qml \
config/dot/quickshell/services/Ongoing.qml \
config/dot/quickshell/shell.qml \
tests/quickshell/control-center-services-contract.sh
tests/quickshell/control-center-services-contract
git commit -m "Add Control Center integration services"
```
@@ -483,7 +483,7 @@ git commit -m "Add Control Center integration services"
- Create: `config/dot/quickshell/modules/quicksettings/HomeTile.qml`
- Create: `config/dot/quickshell/modules/quicksettings/PhoneControls.qml`
- Create: `config/dot/quickshell/modules/quicksettings/RecentExchange.qml`
- Create: `tests/quickshell/control-center-contract.sh`
- Create: `tests/quickshell/control-center-contract`
- Modify: `config/dot/quickshell/config/Theme.qml`
- Modify: `config/dot/quickshell/modules/quicksettings/QuickSettings.qml`
- Modify: `config/dot/quickshell/modules/quicksettings/QuickSettingsPanel.qml`
@@ -514,7 +514,7 @@ Phone leaves only Phone expanded.
- [ ] **Step 2: Run the contract and verify RED**
Run `tests/quickshell/control-center-contract.sh`.
Run `tests/quickshell/control-center-contract`.
Expected: FAIL on the missing geometry tokens and components.
@@ -568,7 +568,7 @@ animation.
- [ ] **Step 7: Restart Quickshell and run the panel contract GREEN**
Run `tests/quickshell/control-center-contract.sh` and inspect the fresh shell
Run `tests/quickshell/control-center-contract` and inspect the fresh shell
journal for `error`, `warning`, `ReferenceError`, and `TypeError` entries from
the current Quickshell start.
@@ -581,7 +581,7 @@ fixture screenshots to `/tmp`; do not commit screenshots.
git add config/dot/quickshell/config/Theme.qml \
config/dot/quickshell/modules/quicksettings \
config/dot/quickshell/modules/bar/StatusCluster.qml \
tests/quickshell/control-center-contract.sh
tests/quickshell/control-center-contract
git commit -m "Build the Panama Control Center"
```
@@ -610,10 +610,10 @@ retaining printers and the external RustDesk lock-screen test.
```bash
python3 tests/quickshell/kdeconnect_bridge_test.py
python3 tests/quickshell/home_assistant_bridge_test.py
tests/quickshell/kdeconnect-helper-contract.sh
tests/quickshell/home-assistant-helper-contract.sh
tests/quickshell/control-center-services-contract.sh
tests/quickshell/control-center-contract.sh
tests/quickshell/kdeconnect-helper-contract
tests/quickshell/home-assistant-helper-contract
tests/quickshell/control-center-services-contract
tests/quickshell/control-center-contract
```
Expected: every command exits 0; live contracts print counts only.
@@ -621,7 +621,7 @@ Expected: every command exits 0; live contracts print counts only.
- [ ] **Step 3: Run full Panama verification**
Run `hyprctl configerrors` and require empty output. Run every executable
`tests/quickshell/*contract.sh` in sorted order and require zero failures.
`tests/quickshell/*contract` in sorted order and require zero failures.
Restart Quickshell from a clean process, verify all IPC targets return, and
inspect only the new process's journal for QML errors or warnings.
@@ -26,7 +26,7 @@
**Files:**
- Create: `config/dot/quickshell/config/DesktopPreferences.qml`
- Modify: `config/dot/quickshell/config/Settings.qml`
- Test: `tests/quickshell/settings-preferences-contract.sh`
- Test: `tests/quickshell/settings-preferences-contract`
**Interfaces:**
- Produces: writable `use24Hour`, `showSeconds`, `showWeekday`, `showCpu`, `showMemory`, `showGpu`, `dockAutohide`, `dockRevealDelayMs`, `dockHideDelayMs`, `focusDurationMinutes`, `autoHdr`, `vrrPolicy`, `directScanoutPolicy`, and `lastPage` properties plus `resetDesktopDefaults(): void`.
@@ -41,7 +41,7 @@
**Files:**
- Create: `config/dot/quickshell/services/SystemSettings.qml`
- Test: `tests/quickshell/settings-system-contract.sh`
- Test: `tests/quickshell/settings-system-contract`
**Interfaces:**
- Consumes: `DesktopPreferences`, `NightLight`, `Notifs`, `Caffeine`, `hyprctl`, `systemctl`, and `pgrep`.
@@ -66,7 +66,7 @@
- Create: `config/dot/quickshell/modules/settings/DisplaysPage.qml`
- Create: `config/dot/quickshell/modules/settings/DesktopPage.qml`
- Create: `config/dot/quickshell/modules/settings/qmldir`
- Test: `tests/quickshell/settings-window-contract.sh`
- Test: `tests/quickshell/settings-window-contract`
**Interfaces:**
- Consumes: `DesktopPreferences`, `SystemSettings`, `NightLight`, and `ShellState.settingsPage`.
@@ -87,7 +87,7 @@
- Create: `config/dot/quickshell/modules/settings/ServicesPage.qml`
- Create: `config/dot/quickshell/modules/settings/AboutPage.qml`
- Modify: `config/dot/quickshell/modules/settings/SettingsShell.qml`
- Test: `tests/quickshell/settings-pages-contract.sh`
- Test: `tests/quickshell/settings-pages-contract`
**Interfaces:**
- Consumes: existing PipeWire controls, `Notifs`, `FocusSession`, service status from Task 2, and fixed GNOME panel handoffs.
@@ -25,7 +25,7 @@
**Files:**
- Create: `config/dot/quickshell/scripts/screen-intelligence`
- Create: `tests/quickshell/screen-intelligence-helper-contract.sh`
- Create: `tests/quickshell/screen-intelligence-helper-contract`
- Modify: `setup/packages/hyprland-packages`
**Interfaces:**
@@ -42,7 +42,7 @@
**Files:**
- Create: `config/dot/quickshell/services/ScreenIntelligence.qml`
- Test: `tests/quickshell/screen-intelligence-contract.sh`
- Test: `tests/quickshell/screen-intelligence-contract`
**Interfaces:**
- Produces: readiness properties, `phase`, `text`, detected-code data, `analyzeRegion`, `analyzeFile`, copy/search/translate/open actions, and `close`.
@@ -85,7 +85,7 @@
- Create: `config/local/share/applications/panama-screen-intelligence.desktop`
- Modify: `config/dot/hypr/README.md`
- Modify: `README.md`
- Modify: `tests/quickshell/settings-pages-contract.sh`
- Modify: `tests/quickshell/settings-pages-contract`
**Interfaces:**
- Produces: Settings destination `screen-intelligence`, `Super+Shift+S`, and a searchable desktop entry.
@@ -32,11 +32,11 @@
- `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.
- `config/local/share/vicinae/scripts/check-system-health`: 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.
- `tests/quickshell/panama-doctor-contract`: schema, status, redaction, timeout, ordering, and repair allow-list contract.
- `tests/quickshell/health-service-contract`: QML state-machine contract.
- `tests/quickshell/health-ui-contract`: Settings, footer, report, indicator, IPC, and Vicinae integration contract.
The helper's authored check order is:
@@ -126,7 +126,7 @@ Add a short `Approved visual: <variant>` note beneath this task after user selec
**Files:**
- Create: `config/dot/quickshell/scripts/panama-doctor`
- Create: `tests/quickshell/panama-doctor-contract.sh`
- Create: `tests/quickshell/panama-doctor-contract`
- Create: `tests/quickshell/fixtures/doctor/bin/systemctl`
- Create: `tests/quickshell/fixtures/doctor/bin/pgrep`
- Create: `tests/quickshell/fixtures/doctor/bin/busctl`
@@ -162,7 +162,7 @@ Cover a healthy required service, a missing required executable, an unconfigured
- [ ] **Step 2: Run the contract and verify the helper is absent**
Run: `tests/quickshell/panama-doctor-contract.sh`
Run: `tests/quickshell/panama-doctor-contract`
Expected: FAIL because `config/dot/quickshell/scripts/panama-doctor` does not exist.
@@ -195,14 +195,14 @@ The top-level `context` contains only an authored session class and an ordered a
- [ ] **Step 4: Run the doctor contract**
Run: `tests/quickshell/panama-doctor-contract.sh`
Run: `tests/quickshell/panama-doctor-contract`
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 add config/dot/quickshell/scripts/panama-doctor tests/quickshell/panama-doctor-contract tests/quickshell/fixtures/doctor
git commit -m "Add Panama system health diagnostics"
```
@@ -211,7 +211,7 @@ git commit -m "Add Panama system health diagnostics"
**Files:**
- Create: `config/dot/quickshell/services/Health.qml`
- Create: `config/dot/quickshell/health-harness.qml`
- Create: `tests/quickshell/health-service-contract.sh`
- Create: `tests/quickshell/health-service-contract`
- Modify: `config/dot/quickshell/shell.qml`
**Interfaces:**
@@ -232,7 +232,7 @@ Assert that a valid warning snapshot is accepted, an older generation is ignored
- [ ] **Step 2: Run the contract and verify it fails**
Run: `tests/quickshell/health-service-contract.sh`
Run: `tests/quickshell/health-service-contract`
Expected: FAIL because `Health.qml` and the harness do not exist.
@@ -265,8 +265,8 @@ The `health` IPC `status()` returns only the already-redacted summary, busy flag
Run:
```bash
tests/quickshell/health-service-contract.sh
tests/quickshell/settings-window-contract.sh
tests/quickshell/health-service-contract
tests/quickshell/settings-window-contract
```
Expected: both PASS.
@@ -274,7 +274,7 @@ 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 add config/dot/quickshell/services/Health.qml config/dot/quickshell/health-harness.qml tests/quickshell/health-service-contract config/dot/quickshell/shell.qml
git commit -m "Add Panama health state service"
```
@@ -288,9 +288,9 @@ git commit -m "Add Panama health state service"
- 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`
- Create: `tests/quickshell/health-ui-contract`
- Modify: `tests/quickshell/settings-pages-contract`
- Modify: `tests/quickshell/settings-search-contract`
**Interfaces:**
- Consumes: all read-only state and methods from `Health.qml`; route remains the stable internal name `services`.
@@ -315,9 +315,9 @@ The runtime harness must prove warning rows appear before healthy groups, unconf
Run:
```bash
tests/quickshell/health-ui-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/settings-search-contract.sh
tests/quickshell/health-ui-contract
tests/quickshell/settings-pages-contract
tests/quickshell/settings-search-contract
```
Expected: FAIL because the approved Health components are absent.
@@ -344,9 +344,9 @@ The sidebar footer is a 54 px `TapHandler` target with status text derived from
Run:
```bash
tests/quickshell/health-ui-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/settings-search-contract.sh
tests/quickshell/health-ui-contract
tests/quickshell/settings-pages-contract
tests/quickshell/settings-search-contract
```
Expected: all PASS with zero QML warnings.
@@ -354,7 +354,7 @@ 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 add config/dot/quickshell/modules/settings config/dot/quickshell/services/SettingsSearch.qml tests/quickshell/health-ui-contract tests/quickshell/settings-pages-contract tests/quickshell/settings-search-contract
git commit -m "Build the System Health settings page"
```
@@ -363,11 +363,11 @@ git commit -m "Build the System Health settings page"
**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`
- Create: `config/local/share/vicinae/scripts/check-system-health`
- 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`
- Modify: `tests/quickshell/health-ui-contract`
- Modify: `tests/quickshell/panama-action-contract`
- Modify: `tests/quickshell/panama-commands-contract`
**Interfaces:**
- Consumes: `Health.actionable`, `Health.status`, and `Health.summary`; existing `panama-action` dispatcher and Settings IPC.
@@ -379,8 +379,8 @@ Assert the indicator is absent for healthy/unconfigured-only fixtures, visible a
```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
check-system-health title -> Panama: Check System Health
check-system-health exec -> $HOME/.config/quickshell/scripts/panama-action health
```
- [ ] **Step 2: Run focused tests and verify failure**
@@ -388,9 +388,9 @@ check-system-health.sh exec -> $HOME/.config/quickshell/scripts/panama-action he
Run:
```bash
tests/quickshell/health-ui-contract.sh
tests/quickshell/panama-action-contract.sh
tests/quickshell/panama-commands-contract.sh
tests/quickshell/health-ui-contract
tests/quickshell/panama-action-contract
tests/quickshell/panama-commands-contract
```
Expected: FAIL on the missing indicator and command.
@@ -416,7 +416,7 @@ 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 add config/dot/quickshell/modules/bar config/local/share/vicinae/scripts/check-system-health config/dot/quickshell/scripts/panama-action tests/quickshell
git commit -m "Add quiet System Health entry points"
```
@@ -424,11 +424,11 @@ git commit -m "Add quiet System Health entry points"
**Files:**
- Modify: `config/dot/quickshell/scripts/panama-doctor`
- Modify: `tests/quickshell/panama-doctor-contract.sh`
- Modify: `tests/quickshell/panama-doctor-contract`
- Modify: `config/dot/quickshell/services/Health.qml`
- Modify: `tests/quickshell/health-service-contract.sh`
- Modify: `tests/quickshell/health-service-contract`
- Modify: `config/dot/quickshell/modules/settings/HealthCheckRow.qml`
- Modify: `tests/quickshell/health-ui-contract.sh`
- Modify: `tests/quickshell/health-ui-contract`
**Interfaces:**
- Consumes: the fixed repair matrix in this plan and current accepted checks from `Health.qml`.
@@ -454,8 +454,8 @@ For runtime links, fixtures must prove only these link names are eligible: `hypr
Run:
```bash
tests/quickshell/panama-doctor-contract.sh
tests/quickshell/health-service-contract.sh
tests/quickshell/panama-doctor-contract
tests/quickshell/health-service-contract
```
Expected: FAIL because `--repair` is not implemented.
@@ -482,9 +482,9 @@ Handle runtime links, Vicinae command linking, and duplicate inhibitors in dedic
Run:
```bash
tests/quickshell/panama-doctor-contract.sh
tests/quickshell/health-service-contract.sh
tests/quickshell/health-ui-contract.sh
tests/quickshell/panama-doctor-contract
tests/quickshell/health-service-contract
tests/quickshell/health-ui-contract
```
Expected: all PASS.
@@ -533,11 +533,11 @@ 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
tests/quickshell/panama-doctor-contract
tests/quickshell/health-service-contract
tests/quickshell/health-ui-contract
for test in tests/quickshell/*contract; do "$test"; done
for test in tests/hypr/*contract; do "$test"; done
```
Expected: every command exits 0. After the latest Settings and installer work,
@@ -25,7 +25,7 @@
**Files:**
- Create: `config/dot/quickshell/services/AudioStreams.js`
- Create: `config/dot/quickshell/audio-streams-harness.qml`
- Create: `tests/quickshell/application-volume-contract.sh`
- Create: `tests/quickshell/application-volume-contract`
**Interfaces:**
- Consumes: PipeWire-shaped nodes with `id`, `ready`, `type`, `properties`, and `audio`.
@@ -47,7 +47,7 @@ Also assert Chromium volume `0.6` from fixture values `0.4` and `0.8`, mixed mut
- [ ] **Step 2: Run the contract and verify RED**
Run: `tests/quickshell/application-volume-contract.sh`
Run: `tests/quickshell/application-volume-contract`
Expected: FAIL because `AudioStreams.js` and the IPC target do not exist.
@@ -134,14 +134,14 @@ Use literal property lookups and `Number.isFinite`; do not import PipeWire into
- [ ] **Step 4: Run the contract and verify GREEN**
Run: `tests/quickshell/application-volume-contract.sh`
Run: `tests/quickshell/application-volume-contract`
Expected: PASS for grouping, fallback metadata, aggregate volume, mixed mute, and writes.
- [ ] **Step 5: Commit the model**
```bash
git add config/dot/quickshell/services/AudioStreams.js config/dot/quickshell/audio-streams-harness.qml tests/quickshell/application-volume-contract.sh
git add config/dot/quickshell/services/AudioStreams.js config/dot/quickshell/audio-streams-harness.qml tests/quickshell/application-volume-contract
git commit -m "Model live application audio streams"
```
@@ -150,7 +150,7 @@ git commit -m "Model live application audio streams"
**Files:**
- Modify: `config/dot/quickshell/services/AudioDevices.qml`
- Modify: `config/dot/quickshell/audio-streams-harness.qml`
- Modify: `tests/quickshell/application-volume-contract.sh`
- Modify: `tests/quickshell/application-volume-contract`
**Interfaces:**
- Consumes: `AudioStreams.group(nodes, PwNodeType.AudioOutStream)`.
@@ -162,7 +162,7 @@ Assert the harness can report real `AudioDevices.applications` without starting
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/application-volume-contract.sh`
Run: `tests/quickshell/application-volume-contract`
Expected: FAIL because `AudioDevices.applications` is undefined.
@@ -181,14 +181,14 @@ Delegate aggregate reads and writes to the pure model. Preserve `outputs`, `inpu
- [ ] **Step 4: Run and verify GREEN**
Run: `tests/quickshell/application-volume-contract.sh`
Run: `tests/quickshell/application-volume-contract`
Expected: PASS with zero or more real live applications and no mutation of the live streams.
- [ ] **Step 5: Commit the service boundary**
```bash
git add config/dot/quickshell/services/AudioDevices.qml config/dot/quickshell/audio-streams-harness.qml tests/quickshell/application-volume-contract.sh
git add config/dot/quickshell/services/AudioDevices.qml config/dot/quickshell/audio-streams-harness.qml tests/quickshell/application-volume-contract
git commit -m "Expose live application audio groups"
```
@@ -198,8 +198,8 @@ git commit -m "Expose live application audio groups"
- Create: `config/dot/quickshell/modules/settings/ApplicationVolumeRow.qml`
- Create: `config/dot/quickshell/modules/settings/ApplicationMixer.qml`
- Modify: `config/dot/quickshell/modules/settings/SoundPage.qml`
- Modify: `tests/quickshell/application-volume-contract.sh`
- Modify: `tests/quickshell/sound-page-contract.sh`
- Modify: `tests/quickshell/application-volume-contract`
- Modify: `tests/quickshell/sound-page-contract`
**Interfaces:**
- Consumes: one `AudioDevices.applications` group per row.
@@ -211,7 +211,7 @@ Construct `SoundPage.qml` in the existing isolated Settings harness. Assert no Q
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/application-volume-contract.sh && tests/quickshell/sound-page-contract.sh`
Run: `tests/quickshell/application-volume-contract && tests/quickshell/sound-page-contract`
Expected: FAIL because the mixer components and Applications card are absent.
@@ -221,14 +221,14 @@ Expected: FAIL because the mixer components and Applications card are absent.
- [ ] **Step 4: Run and verify GREEN**
Run: `tests/quickshell/application-volume-contract.sh && tests/quickshell/sound-page-contract.sh`
Run: `tests/quickshell/application-volume-contract && tests/quickshell/sound-page-contract`
Expected: PASS with no QML warnings.
- [ ] **Step 5: Commit the finished application mixer**
```bash
git add config/dot/quickshell/modules/settings/ApplicationVolumeRow.qml config/dot/quickshell/modules/settings/ApplicationMixer.qml config/dot/quickshell/modules/settings/SoundPage.qml tests/quickshell/application-volume-contract.sh tests/quickshell/sound-page-contract.sh
git add config/dot/quickshell/modules/settings/ApplicationVolumeRow.qml config/dot/quickshell/modules/settings/ApplicationMixer.qml config/dot/quickshell/modules/settings/SoundPage.qml tests/quickshell/application-volume-contract tests/quickshell/sound-page-contract
git commit -m "Add application volume mixer"
```
@@ -242,9 +242,9 @@ git commit -m "Add application volume mixer"
Run:
```bash
tests/quickshell/application-volume-contract.sh
tests/quickshell/sound-page-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/application-volume-contract
tests/quickshell/sound-page-contract
tests/quickshell/settings-pages-contract
```
Expected: all PASS; runtime enumeration may report zero applications without failing.
@@ -26,7 +26,7 @@
**Files:**
- Create: `config/dot/quickshell/services/DisplayLayout.js`
- Create: `config/dot/quickshell/display-layout-harness.qml`
- Create: `tests/quickshell/display-layout-contract.sh`
- Create: `tests/quickshell/display-layout-contract`
**Interfaces:**
- Consumes: records `{name,width,height,scale,transform,x,y,primary}`.
@@ -47,7 +47,7 @@ Assert transformed logical sizes, normalized DP-2 position `0,0`, normalized HDM
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/display-layout-contract.sh`
Run: `tests/quickshell/display-layout-contract`
Expected: FAIL because the geometry module and harness do not exist.
@@ -71,14 +71,14 @@ Assert rejection of duplicate outputs, zero or two primaries, fractional coordin
- [ ] **Step 5: Run and verify GREEN**
Run: `tests/quickshell/display-layout-contract.sh`
Run: `tests/quickshell/display-layout-contract`
Expected: PASS for geometry, deterministic snapping, normalization, and invalid cases.
- [ ] **Step 6: Commit layout geometry**
```bash
git add config/dot/quickshell/services/DisplayLayout.js config/dot/quickshell/display-layout-harness.qml tests/quickshell/display-layout-contract.sh
git add config/dot/quickshell/services/DisplayLayout.js config/dot/quickshell/display-layout-harness.qml tests/quickshell/display-layout-contract
git commit -m "Model multi-monitor layout geometry"
```
@@ -89,8 +89,8 @@ git commit -m "Model multi-monitor layout geometry"
- Modify: `config/dot/quickshell/displays-harness.qml`
- Modify: `config/dot/hypr/monitors.lua`
- Modify: `config/dot/quickshell/config/PreferenceSchema.qml`
- Modify: `tests/quickshell/displays-contract.sh`
- Modify: `tests/quickshell/settings-preferences-contract.sh`
- Modify: `tests/quickshell/displays-contract`
- Modify: `tests/quickshell/settings-preferences-contract`
**Interfaces:**
- Consumes: `hyprctl -j monitors` x/y values and backward-compatible persisted entries.
@@ -111,7 +111,7 @@ Assert only one valid persisted primary is honored and DP-2's 10-bit/color polic
- [ ] **Step 2: Run and verify RED**
Run: `PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract.sh`
Run: `PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract`
Expected: FAIL because x/y/primary are neither parsed nor replayed.
@@ -129,14 +129,14 @@ Change the internal `displays` detail to **Resolution, scale, rotation, position
- [ ] **Step 6: Run and verify GREEN**
Run: `PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract.sh && tests/quickshell/settings-preferences-contract.sh`
Run: `PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract && tests/quickshell/settings-preferences-contract`
Expected: PASS for old and new records.
- [ ] **Step 7: Commit extended persistence**
```bash
git add config/dot/quickshell/services/Displays.qml config/dot/quickshell/displays-harness.qml config/dot/hypr/monitors.lua config/dot/quickshell/config/PreferenceSchema.qml tests/quickshell/displays-contract.sh tests/quickshell/settings-preferences-contract.sh
git add config/dot/quickshell/services/Displays.qml config/dot/quickshell/displays-harness.qml config/dot/hypr/monitors.lua config/dot/quickshell/config/PreferenceSchema.qml tests/quickshell/displays-contract tests/quickshell/settings-preferences-contract
git commit -m "Persist complete monitor layouts"
```
@@ -145,8 +145,8 @@ git commit -m "Persist complete monitor layouts"
**Files:**
- Modify: `config/dot/quickshell/services/Displays.qml`
- Modify: `config/dot/quickshell/displays-harness.qml`
- Modify: `tests/quickshell/displays-contract.sh`
- Create: `tests/quickshell/display-transaction-contract.sh`
- Modify: `tests/quickshell/displays-contract`
- Create: `tests/quickshell/display-transaction-contract`
**Interfaces:**
- Consumes: `DisplayLayout.validate/normalize` and complete current monitor records.
@@ -162,7 +162,7 @@ Assert timeout, explicit revert, non-zero apply exit, wrong readback, and a disc
- [ ] **Step 3: Run and verify RED**
Run: `tests/quickshell/display-transaction-contract.sh`
Run: `tests/quickshell/display-transaction-contract`
Expected: FAIL because `Displays.qml` tracks only one output per operation.
@@ -195,14 +195,14 @@ Keep `apply(output, mode, scale, transform)` by cloning `currentLayout()`, repla
- [ ] **Step 7: Run and verify GREEN**
Run: `tests/quickshell/display-transaction-contract.sh && PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract.sh`
Run: `tests/quickshell/display-transaction-contract && PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract`
Expected: PASS for apply, confirm, timeout, all revert paths, disconnect, and stale generations.
- [ ] **Step 8: Commit safe transactions**
```bash
git add config/dot/quickshell/services/Displays.qml config/dot/quickshell/displays-harness.qml tests/quickshell/displays-contract.sh tests/quickshell/display-transaction-contract.sh
git add config/dot/quickshell/services/Displays.qml config/dot/quickshell/displays-harness.qml tests/quickshell/displays-contract tests/quickshell/display-transaction-contract
git commit -m "Apply monitor layouts transactionally"
```
@@ -211,8 +211,8 @@ git commit -m "Apply monitor layouts transactionally"
**Files:**
- Create: `config/dot/quickshell/modules/settings/DisplayArrangement.qml`
- Modify: `config/dot/quickshell/modules/settings/DisplaysPage.qml`
- Create: `tests/quickshell/display-arrangement-contract.sh`
- Modify: `tests/quickshell/settings-pages-contract.sh`
- Create: `tests/quickshell/display-arrangement-contract`
- Modify: `tests/quickshell/settings-pages-contract`
**Interfaces:**
- Consumes: `Displays.currentLayout()`, `Displays.applyLayout()`, `Displays.makePrimary()`, and `DisplayLayout.canvasRects/snap`.
@@ -224,7 +224,7 @@ Render two literal monitors at wide and 500 px content widths. Through harness I
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/display-arrangement-contract.sh`
Run: `tests/quickshell/display-arrangement-contract`
Expected: FAIL because no arrangement component exists.
@@ -242,14 +242,14 @@ Show the card only for two or more monitors. Keep the existing connected-display
- [ ] **Step 6: Run and verify GREEN**
Run: `tests/quickshell/display-arrangement-contract.sh && PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract.sh && tests/quickshell/settings-pages-contract.sh`
Run: `tests/quickshell/display-arrangement-contract && PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract && tests/quickshell/settings-pages-contract`
Expected: PASS at both widths with no QML warnings.
- [ ] **Step 7: Commit the canvas**
```bash
git add config/dot/quickshell/modules/settings/DisplayArrangement.qml config/dot/quickshell/modules/settings/DisplaysPage.qml tests/quickshell/display-arrangement-contract.sh tests/quickshell/settings-pages-contract.sh
git add config/dot/quickshell/modules/settings/DisplayArrangement.qml config/dot/quickshell/modules/settings/DisplaysPage.qml tests/quickshell/display-arrangement-contract tests/quickshell/settings-pages-contract
git commit -m "Add monitor arrangement canvas"
```
@@ -259,7 +259,7 @@ git commit -m "Add monitor arrangement canvas"
- Create: `config/dot/quickshell/modules/settings/DisplayIdentify.qml`
- Modify: `config/dot/quickshell/modules/settings/DisplayArrangement.qml`
- Modify: `config/dot/quickshell/shell.qml`
- Modify: `tests/quickshell/display-arrangement-contract.sh`
- Modify: `tests/quickshell/display-arrangement-contract`
**Interfaces:**
- Consumes: `Displays.identifying` and each `Quickshell.screens` entry.
@@ -271,7 +271,7 @@ Invoke identify through the fixture harness. Assert screen 1 renders connector/n
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/display-arrangement-contract.sh`
Run: `tests/quickshell/display-arrangement-contract`
Expected: FAIL because identify state and overlays do not exist.
@@ -281,14 +281,14 @@ Expected: FAIL because identify state and overlays do not exist.
- [ ] **Step 4: Run and verify GREEN**
Run: `tests/quickshell/display-arrangement-contract.sh`
Run: `tests/quickshell/display-arrangement-contract`
Expected: PASS with a fixed window count and no focus-grab warnings.
- [ ] **Step 5: Commit identification**
```bash
git add config/dot/quickshell/modules/settings/DisplayIdentify.qml config/dot/quickshell/modules/settings/DisplayArrangement.qml config/dot/quickshell/shell.qml tests/quickshell/display-arrangement-contract.sh
git add config/dot/quickshell/modules/settings/DisplayIdentify.qml config/dot/quickshell/modules/settings/DisplayArrangement.qml config/dot/quickshell/shell.qml tests/quickshell/display-arrangement-contract
git commit -m "Add display identification overlays"
```
@@ -298,10 +298,10 @@ git commit -m "Add display identification overlays"
- Modify: `config/dot/quickshell/services/SettingsSearch.qml`
- Modify: `config/dot/quickshell/services/SettingsBackup.qml`
- Modify: `config/dot/quickshell/modules/settings/README.md`
- Modify: `tests/quickshell/settings-search-contract.sh`
- Modify: `tests/quickshell/settings-backup-live-contract.sh`
- Modify: `tests/quickshell/settings-commit-reset-contract.sh`
- Modify: `tests/quickshell/settings-ownership-contract.sh`
- Modify: `tests/quickshell/settings-search-contract`
- Modify: `tests/quickshell/settings-backup-live-contract`
- Modify: `tests/quickshell/settings-commit-reset-contract`
- Modify: `tests/quickshell/settings-ownership-contract`
**Interfaces:**
- Consumes: the existing internal `displays` preference and complete-layout transaction.
@@ -313,7 +313,7 @@ Assert **arrange displays**, **monitor position**, and **primary display** route
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/settings-search-contract.sh && tests/quickshell/settings-backup-live-contract.sh && tests/quickshell/settings-commit-reset-contract.sh`
Run: `tests/quickshell/settings-search-contract && tests/quickshell/settings-backup-live-contract && tests/quickshell/settings-commit-reset-contract`
Expected: FAIL for missing terms and one-output restore assumptions.
@@ -327,14 +327,14 @@ Document Displays as the sole owner of mode, scale, rotation, arrangement, and p
- [ ] **Step 5: Run and verify GREEN**
Run: `tests/quickshell/settings-search-contract.sh && tests/quickshell/settings-backup-live-contract.sh && tests/quickshell/settings-commit-reset-contract.sh && tests/quickshell/settings-ownership-contract.sh`
Run: `tests/quickshell/settings-search-contract && tests/quickshell/settings-backup-live-contract && tests/quickshell/settings-commit-reset-contract && tests/quickshell/settings-ownership-contract`
Expected: PASS with no new duplicated controls.
- [ ] **Step 6: Commit integration**
```bash
git add config/dot/quickshell/services/SettingsSearch.qml config/dot/quickshell/services/SettingsBackup.qml config/dot/quickshell/modules/settings/README.md tests/quickshell/settings-search-contract.sh tests/quickshell/settings-backup-live-contract.sh tests/quickshell/settings-commit-reset-contract.sh tests/quickshell/settings-ownership-contract.sh
git add config/dot/quickshell/services/SettingsSearch.qml config/dot/quickshell/services/SettingsBackup.qml config/dot/quickshell/modules/settings/README.md tests/quickshell/settings-search-contract tests/quickshell/settings-backup-live-contract tests/quickshell/settings-commit-reset-contract tests/quickshell/settings-ownership-contract
git commit -m "Integrate complete display layouts"
```
@@ -343,12 +343,12 @@ git commit -m "Integrate complete display layouts"
- [ ] **Step 1: Run all static display contracts**
```bash
tests/quickshell/display-layout-contract.sh
tests/quickshell/display-transaction-contract.sh
tests/quickshell/display-arrangement-contract.sh
PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract.sh
tests/quickshell/settings-search-contract.sh
tests/quickshell/settings-backup-live-contract.sh
tests/quickshell/display-layout-contract
tests/quickshell/display-transaction-contract
tests/quickshell/display-arrangement-contract
PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract
tests/quickshell/settings-search-contract
tests/quickshell/settings-backup-live-contract
```
Expected: all PASS without touching the physical display.
@@ -361,7 +361,7 @@ Expected: `config ok`.
- [ ] **Step 3: Defer the live display test**
Do not run the state-changing portion of `tests/quickshell/displays-contract.sh` here. The master Phase 2 completion gate runs it once after every slice is stable and restores the observed mode, scale, transform, and position.
Do not run the state-changing portion of `tests/quickshell/displays-contract` here. The master Phase 2 completion gate runs it once after every slice is stable and restores the observed mode, scale, transform, and position.
- [ ] **Step 4: Review branch state**
@@ -58,7 +58,7 @@ Use strict red-green-refactor cycles and the exact commit boundaries in that pla
- [ ] **Step 3: Confirm the slice head**
Run: `tests/quickshell/application-volume-contract.sh && tests/quickshell/sound-page-contract.sh && git status --short`
Run: `tests/quickshell/application-volume-contract && tests/quickshell/sound-page-contract && git status --short`
Expected: both PASS and no uncommitted files.
@@ -80,7 +80,7 @@ Never invoke `panama-lock run` outside its fake-hyprlock fixture.
- [ ] **Step 3: Confirm the slice head**
Run: `tests/quickshell/lock-screen-helper-contract.sh && tests/quickshell/lock-screen-service-contract.sh && tests/quickshell/lock-screen-settings-contract.sh && git status --short`
Run: `tests/quickshell/lock-screen-helper-contract && tests/quickshell/lock-screen-service-contract && tests/quickshell/lock-screen-settings-contract && git status --short`
Expected: all PASS, no live `hyprlock` test process, and no uncommitted files.
@@ -102,7 +102,7 @@ All apply tests use fake hyprpaper IPC and temporary image files.
- [ ] **Step 3: Confirm the slice head**
Run: `tests/quickshell/wallpaper-policy-contract.sh && tests/quickshell/wallpaper-service-contract.sh && tests/quickshell/wallpaper-settings-contract.sh && git status --short`
Run: `tests/quickshell/wallpaper-policy-contract && tests/quickshell/wallpaper-service-contract && tests/quickshell/wallpaper-settings-contract && git status --short`
Expected: all PASS and no uncommitted files.
@@ -124,7 +124,7 @@ Use fixture monitor JSON for all multi-monitor cases.
- [ ] **Step 3: Confirm the static slice head**
Run: `tests/quickshell/display-layout-contract.sh && tests/quickshell/display-transaction-contract.sh && tests/quickshell/display-arrangement-contract.sh && PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract.sh && git status --short`
Run: `tests/quickshell/display-layout-contract && tests/quickshell/display-transaction-contract && tests/quickshell/display-arrangement-contract && PANAMA_DISPLAYS_STATIC_ONLY=1 tests/quickshell/displays-contract && git status --short`
Expected: all PASS and no uncommitted files.
@@ -143,11 +143,11 @@ Expected: all PASS and no uncommitted files.
- [ ] **Step 1: Expand the combined restore fixture before the final audit**
The slice plans already extend `tests/quickshell/settings-backup-live-contract.sh` test-first. Confirm its final fixture now contains lock, slideshow, and two-output layout values and asserts this exact order: preferences reload, display apply/verify, idle apply, lock generate, wallpaper apply/verify, keybind/compositor settle, shell reload. It must also assert bounded failure remains in service state and shell reload waits for the settle cap.
The slice plans already extend `tests/quickshell/settings-backup-live-contract` test-first. Confirm its final fixture now contains lock, slideshow, and two-output layout values and asserts this exact order: preferences reload, display apply/verify, idle apply, lock generate, wallpaper apply/verify, keybind/compositor settle, shell reload. It must also assert bounded failure remains in service state and shell reload waits for the settle cap.
- [ ] **Step 2: Run the combined audit**
Run: `tests/quickshell/settings-backup-live-contract.sh`
Run: `tests/quickshell/settings-backup-live-contract`
Expected: PASS. A failure means the independently green hooks conflict and must be debugged before any consolidation.
@@ -161,7 +161,7 @@ Run the ownership contract against final pages. Manual search entries may exist
- [ ] **Step 5: Run and verify GREEN**
Run: `tests/quickshell/settings-backup-live-contract.sh && tests/quickshell/settings-search-contract.sh && tests/quickshell/settings-ownership-contract.sh`
Run: `tests/quickshell/settings-backup-live-contract && tests/quickshell/settings-search-contract && tests/quickshell/settings-ownership-contract`
Expected: all PASS.
@@ -177,16 +177,16 @@ If Step 2 or Step 5 required corrections, stage only those files and commit them
- [ ] **Step 1: Run new contracts**
```bash
tests/quickshell/application-volume-contract.sh
tests/quickshell/lock-screen-helper-contract.sh
tests/quickshell/lock-screen-service-contract.sh
tests/quickshell/lock-screen-settings-contract.sh
tests/quickshell/wallpaper-policy-contract.sh
tests/quickshell/wallpaper-service-contract.sh
tests/quickshell/wallpaper-settings-contract.sh
tests/quickshell/display-layout-contract.sh
tests/quickshell/display-transaction-contract.sh
tests/quickshell/display-arrangement-contract.sh
tests/quickshell/application-volume-contract
tests/quickshell/lock-screen-helper-contract
tests/quickshell/lock-screen-service-contract
tests/quickshell/lock-screen-settings-contract
tests/quickshell/wallpaper-policy-contract
tests/quickshell/wallpaper-service-contract
tests/quickshell/wallpaper-settings-contract
tests/quickshell/display-layout-contract
tests/quickshell/display-transaction-contract
tests/quickshell/display-arrangement-contract
```
Expected: all PASS.
@@ -194,23 +194,23 @@ Expected: all PASS.
- [ ] **Step 2: Run affected existing contracts**
```bash
tests/quickshell/sound-page-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/settings-search-contract.sh
tests/quickshell/settings-ownership-contract.sh
tests/quickshell/settings-preferences-contract.sh
tests/quickshell/settings-commit-reset-contract.sh
tests/quickshell/settings-backup-live-contract.sh
tests/quickshell/migrations-contract.sh
tests/quickshell/panama-doctor-contract.sh
tests/quickshell/schema-hypr-shape-contract.sh
tests/quickshell/sound-page-contract
tests/quickshell/settings-pages-contract
tests/quickshell/settings-search-contract
tests/quickshell/settings-ownership-contract
tests/quickshell/settings-preferences-contract
tests/quickshell/settings-commit-reset-contract
tests/quickshell/settings-backup-live-contract
tests/quickshell/migrations-contract
tests/quickshell/panama-doctor-contract
tests/quickshell/schema-hypr-shape-contract
```
Expected: all PASS.
- [ ] **Step 3: Run the one state-changing display contract**
Run: `tests/quickshell/displays-contract.sh`
Run: `tests/quickshell/displays-contract`
Expected: PASS and cleanup proves the physical monitor returns to its captured original mode, scale, transform, x, and y. Stop immediately if the preflight reports a dirty display baseline.
@@ -26,7 +26,7 @@
**Files:**
- Modify: `config/dot/quickshell/config/PreferenceSchema.qml`
- Create: `config/dot/quickshell/scripts/panama-lock`
- Create: `tests/quickshell/lock-screen-helper-contract.sh`
- Create: `tests/quickshell/lock-screen-helper-contract`
**Interfaces:**
- Consumes: `lockBackgroundMode`, `lockBlurLevel`, `lockShowClock`, `lockShowDate`, `lockShowUser`, `lockFadeOnEmpty`, `use24Hour`, `colorScheme`, and wallpaper policy from `settings.json`.
@@ -50,7 +50,7 @@ For light solid mode assert `rgba(245, 246, 250, 1.0)`. For wallpaper mode with
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/lock-screen-helper-contract.sh`
Run: `tests/quickshell/lock-screen-helper-contract`
Expected: FAIL because `panama-lock` does not exist.
@@ -109,14 +109,14 @@ Seed a valid generated file, force generation failure through an unwritable fixt
- [ ] **Step 6: Run and verify GREEN**
Run: `tests/quickshell/lock-screen-helper-contract.sh`
Run: `tests/quickshell/lock-screen-helper-contract`
Expected: PASS for modes, visibility, clock format, validation, atomicity, and fallback.
- [ ] **Step 7: Commit the generator**
```bash
git add config/dot/quickshell/config/PreferenceSchema.qml config/dot/quickshell/scripts/panama-lock tests/quickshell/lock-screen-helper-contract.sh
git add config/dot/quickshell/config/PreferenceSchema.qml config/dot/quickshell/scripts/panama-lock tests/quickshell/lock-screen-helper-contract
git commit -m "Generate managed lock screen configuration"
```
@@ -127,8 +127,8 @@ git commit -m "Generate managed lock screen configuration"
- Modify: `config/dot/quickshell/scripts/panama-idle`
- Create: `config/dot/quickshell/services/LockScreen.qml`
- Create: `config/dot/quickshell/lock-screen-harness.qml`
- Create: `tests/quickshell/lock-screen-service-contract.sh`
- Modify: `tests/quickshell/lock-screen-helper-contract.sh`
- Create: `tests/quickshell/lock-screen-service-contract`
- Modify: `tests/quickshell/lock-screen-helper-contract`
**Interfaces:**
- Consumes: `panama-lock generate/status` and `DesktopPreferences.revision`.
@@ -146,13 +146,13 @@ Through the QML harness, change one lock preference three times inside 250 ms an
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/lock-screen-service-contract.sh`
Run: `tests/quickshell/lock-screen-service-contract`
Expected: FAIL because the idle paths still invoke `hyprlock` directly and the service is absent.
- [ ] **Step 3: Update shipped and generated hypridle commands**
Change only `lock_cmd`; preserve blanking, sleep, and lock timing behavior. Keep both shipped/generated idle-command assertions in `tests/quickshell/lock-screen-service-contract.sh`; this repository has no separate idle-lock contract.
Change only `lock_cmd`; preserve blanking, sleep, and lock timing behavior. Keep both shipped/generated idle-command assertions in `tests/quickshell/lock-screen-service-contract`; this repository has no separate idle-lock contract.
- [ ] **Step 4: Implement `LockScreen.qml`**
@@ -160,14 +160,14 @@ Use one `Process` for generation and one for status. Coalesce `DesktopPreference
- [ ] **Step 5: Run and verify GREEN**
Run: `tests/quickshell/lock-screen-helper-contract.sh && tests/quickshell/lock-screen-service-contract.sh`
Run: `tests/quickshell/lock-screen-helper-contract && tests/quickshell/lock-screen-service-contract`
Expected: PASS with one coalesced generation and no live locker process.
- [ ] **Step 6: Commit lock invocation and service state**
```bash
git add config/dot/hypr/hypridle.conf config/dot/quickshell/scripts/panama-idle config/dot/quickshell/services/LockScreen.qml config/dot/quickshell/lock-screen-harness.qml tests/quickshell/lock-screen-helper-contract.sh tests/quickshell/lock-screen-service-contract.sh
git add config/dot/hypr/hypridle.conf config/dot/quickshell/scripts/panama-idle config/dot/quickshell/services/LockScreen.qml config/dot/quickshell/lock-screen-harness.qml tests/quickshell/lock-screen-helper-contract tests/quickshell/lock-screen-service-contract
git commit -m "Route session locking through Panama"
```
@@ -177,8 +177,8 @@ git commit -m "Route session locking through Panama"
- Create: `config/dot/quickshell/modules/settings/LockScreenPreview.qml`
- Modify: `config/dot/quickshell/modules/settings/AppearancePage.qml`
- Modify: `config/dot/quickshell/services/SettingsSearch.qml`
- Create: `tests/quickshell/lock-screen-settings-contract.sh`
- Modify: `tests/quickshell/settings-search-contract.sh`
- Create: `tests/quickshell/lock-screen-settings-contract`
- Modify: `tests/quickshell/settings-search-contract`
- Modify: `config/dot/quickshell/modules/settings/README.md`
**Interfaces:**
@@ -191,7 +191,7 @@ Construct the real Appearance page in an isolated QML harness for screenshot, wa
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/lock-screen-settings-contract.sh && tests/quickshell/settings-search-contract.sh && tests/quickshell/settings-ownership-contract.sh`
Run: `tests/quickshell/lock-screen-settings-contract && tests/quickshell/settings-search-contract && tests/quickshell/settings-ownership-contract`
Expected: FAIL because the preview, card, and group route are absent.
@@ -209,14 +209,14 @@ Map `lockAppearance` to `appearance`; add manual terms **lock screen background*
- [ ] **Step 6: Run and verify GREEN**
Run: `tests/quickshell/lock-screen-settings-contract.sh && tests/quickshell/settings-search-contract.sh && tests/quickshell/settings-ownership-contract.sh`
Run: `tests/quickshell/lock-screen-settings-contract && tests/quickshell/settings-search-contract && tests/quickshell/settings-ownership-contract`
Expected: PASS with zero QML warnings and no additional mirrors.
- [ ] **Step 7: Commit the lock-screen Settings experience**
```bash
git add config/dot/quickshell/modules/settings/LockScreenPreview.qml config/dot/quickshell/modules/settings/AppearancePage.qml config/dot/quickshell/services/SettingsSearch.qml config/dot/quickshell/modules/settings/README.md tests/quickshell/lock-screen-settings-contract.sh tests/quickshell/settings-search-contract.sh
git add config/dot/quickshell/modules/settings/LockScreenPreview.qml config/dot/quickshell/modules/settings/AppearancePage.qml config/dot/quickshell/services/SettingsSearch.qml config/dot/quickshell/modules/settings/README.md tests/quickshell/lock-screen-settings-contract tests/quickshell/settings-search-contract
git commit -m "Add lock screen appearance settings"
```
@@ -225,10 +225,10 @@ git commit -m "Add lock screen appearance settings"
**Files:**
- Modify: `config/dot/quickshell/services/SettingsBackup.qml`
- Modify: `config/dot/quickshell/scripts/panama-doctor`
- Modify: `tests/quickshell/settings-backup-live-contract.sh`
- Modify: `tests/quickshell/settings-commit-reset-contract.sh`
- Modify: `tests/quickshell/panama-doctor-contract.sh`
- Modify: `tests/quickshell/lock-screen-service-contract.sh`
- Modify: `tests/quickshell/settings-backup-live-contract`
- Modify: `tests/quickshell/settings-commit-reset-contract`
- Modify: `tests/quickshell/panama-doctor-contract`
- Modify: `tests/quickshell/lock-screen-service-contract`
**Interfaces:**
- Consumes: `LockScreen.regenerate()` and `panama-lock status`.
@@ -240,7 +240,7 @@ Restore a fixture snapshot with non-default lock values and assert regeneration
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/settings-backup-live-contract.sh && tests/quickshell/settings-commit-reset-contract.sh && tests/quickshell/panama-doctor-contract.sh`
Run: `tests/quickshell/settings-backup-live-contract && tests/quickshell/settings-commit-reset-contract && tests/quickshell/panama-doctor-contract`
Expected: FAIL because restore and Health do not know the lock generator.
@@ -250,14 +250,14 @@ Inject `regenerateLock` into `SettingsBackup.qml`, start it after preference rel
- [ ] **Step 4: Run and verify GREEN**
Run: `tests/quickshell/settings-backup-live-contract.sh && tests/quickshell/settings-commit-reset-contract.sh && tests/quickshell/panama-doctor-contract.sh && tests/quickshell/lock-screen-service-contract.sh`
Run: `tests/quickshell/settings-backup-live-contract && tests/quickshell/settings-commit-reset-contract && tests/quickshell/panama-doctor-contract && tests/quickshell/lock-screen-service-contract`
Expected: PASS with restore ordering and redacted status.
- [ ] **Step 5: Commit integration**
```bash
git add config/dot/quickshell/services/SettingsBackup.qml config/dot/quickshell/scripts/panama-doctor tests/quickshell/settings-backup-live-contract.sh tests/quickshell/settings-commit-reset-contract.sh tests/quickshell/panama-doctor-contract.sh tests/quickshell/lock-screen-service-contract.sh
git add config/dot/quickshell/services/SettingsBackup.qml config/dot/quickshell/scripts/panama-doctor tests/quickshell/settings-backup-live-contract tests/quickshell/settings-commit-reset-contract tests/quickshell/panama-doctor-contract tests/quickshell/lock-screen-service-contract
git commit -m "Integrate managed lock screen recovery"
```
@@ -266,14 +266,14 @@ git commit -m "Integrate managed lock screen recovery"
- [ ] **Step 1: Run all lock contracts once**
```bash
tests/quickshell/lock-screen-helper-contract.sh
tests/quickshell/lock-screen-service-contract.sh
tests/quickshell/lock-screen-settings-contract.sh
tests/quickshell/settings-search-contract.sh
tests/quickshell/settings-ownership-contract.sh
tests/quickshell/settings-backup-live-contract.sh
tests/quickshell/settings-commit-reset-contract.sh
tests/quickshell/panama-doctor-contract.sh
tests/quickshell/lock-screen-helper-contract
tests/quickshell/lock-screen-service-contract
tests/quickshell/lock-screen-settings-contract
tests/quickshell/settings-search-contract
tests/quickshell/settings-ownership-contract
tests/quickshell/settings-backup-live-contract
tests/quickshell/settings-commit-reset-contract
tests/quickshell/panama-doctor-contract
```
Expected: all PASS and no process named `hyprlock` is started by the tests.
@@ -26,7 +26,7 @@
- Modify: `config/dot/quickshell/config/PreferenceSchema.qml`
- Create: `config/dot/quickshell/services/WallpaperPolicy.js`
- Create: `config/dot/quickshell/wallpaper-policy-harness.qml`
- Create: `tests/quickshell/wallpaper-policy-contract.sh`
- Create: `tests/quickshell/wallpaper-policy-contract`
**Interfaces:**
- Consumes: mode, global path, collection, per-monitor map, connected outputs, valid candidates, and shuffle bag.
@@ -46,7 +46,7 @@ Assert missing assignments fall back to the global path, invalid collection entr
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/wallpaper-policy-contract.sh`
Run: `tests/quickshell/wallpaper-policy-contract`
Expected: FAIL because the policy module and harness are missing.
@@ -90,14 +90,14 @@ Use `group: "wallpaper"` for every key. Keep the existing `wallpaperPath` patter
- [ ] **Step 5: Run and verify GREEN**
Run: `tests/quickshell/wallpaper-policy-contract.sh`
Run: `tests/quickshell/wallpaper-policy-contract`
Expected: PASS for validation, fallback maps, ordered wrap, and shuffle-without-repeat.
- [ ] **Step 6: Commit policy model**
```bash
git add config/dot/quickshell/config/PreferenceSchema.qml config/dot/quickshell/services/WallpaperPolicy.js config/dot/quickshell/wallpaper-policy-harness.qml tests/quickshell/wallpaper-policy-contract.sh
git add config/dot/quickshell/config/PreferenceSchema.qml config/dot/quickshell/services/WallpaperPolicy.js config/dot/quickshell/wallpaper-policy-harness.qml tests/quickshell/wallpaper-policy-contract
git commit -m "Model wallpaper display policies"
```
@@ -106,8 +106,8 @@ git commit -m "Model wallpaper display policies"
**Files:**
- Modify: `config/dot/quickshell/services/Wallpaper.qml`
- Create: `config/dot/quickshell/wallpaper-service-harness.qml`
- Create: `tests/quickshell/wallpaper-service-contract.sh`
- Modify: `tests/quickshell/settings-pages-contract.sh`
- Create: `tests/quickshell/wallpaper-service-contract`
- Modify: `tests/quickshell/settings-pages-contract`
**Interfaces:**
- Consumes: `WallpaperPolicy.effectiveMap(...)` and hyprpaper `listactive` output.
@@ -127,7 +127,7 @@ Assert preferences are written only after exact readback, wrong readback leaves
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/wallpaper-service-contract.sh`
Run: `tests/quickshell/wallpaper-service-contract`
Expected: FAIL because `Wallpaper.qml` only tracks one active path and persists after exit status.
@@ -157,14 +157,14 @@ Keep `set(path)` as `return root.setSingle(path)` so SettingsBackup and existing
- [ ] **Step 6: Run and verify GREEN**
Run: `tests/quickshell/wallpaper-service-contract.sh && tests/quickshell/settings-pages-contract.sh`
Run: `tests/quickshell/wallpaper-service-contract && tests/quickshell/settings-pages-contract`
Expected: PASS for exact argv, readback gating, old API compatibility, and failure copy.
- [ ] **Step 7: Commit verified application**
```bash
git add config/dot/quickshell/services/Wallpaper.qml config/dot/quickshell/wallpaper-service-harness.qml tests/quickshell/wallpaper-service-contract.sh tests/quickshell/settings-pages-contract.sh
git add config/dot/quickshell/services/Wallpaper.qml config/dot/quickshell/wallpaper-service-harness.qml tests/quickshell/wallpaper-service-contract tests/quickshell/settings-pages-contract
git commit -m "Verify wallpaper policy application"
```
@@ -174,8 +174,8 @@ git commit -m "Verify wallpaper policy application"
- Modify: `config/dot/quickshell/services/Wallpaper.qml`
- Modify: `config/dot/quickshell/services/WallpaperPolicy.js`
- Modify: `config/dot/quickshell/wallpaper-service-harness.qml`
- Modify: `tests/quickshell/wallpaper-policy-contract.sh`
- Modify: `tests/quickshell/wallpaper-service-contract.sh`
- Modify: `tests/quickshell/wallpaper-policy-contract`
- Modify: `tests/quickshell/wallpaper-service-contract`
**Interfaces:**
- Consumes: validated slideshow collection, interval, shuffle flag, and `Quickshell.screens`.
@@ -187,7 +187,7 @@ Use a harness-adjustable interval measured in milliseconds while production deri
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/wallpaper-policy-contract.sh && tests/quickshell/wallpaper-service-contract.sh`
Run: `tests/quickshell/wallpaper-policy-contract && tests/quickshell/wallpaper-service-contract`
Expected: FAIL because no slideshow state or screen-set coalescing exists.
@@ -201,14 +201,14 @@ Bind a sorted screen-name signature and restart a 350 ms single-shot Timer when
- [ ] **Step 5: Run and verify GREEN**
Run: `tests/quickshell/wallpaper-policy-contract.sh && tests/quickshell/wallpaper-service-contract.sh`
Run: `tests/quickshell/wallpaper-policy-contract && tests/quickshell/wallpaper-service-contract`
Expected: PASS without rapid retry or durable writes during rotation.
- [ ] **Step 6: Commit runtime policy**
```bash
git add config/dot/quickshell/services/Wallpaper.qml config/dot/quickshell/services/WallpaperPolicy.js config/dot/quickshell/wallpaper-service-harness.qml tests/quickshell/wallpaper-policy-contract.sh tests/quickshell/wallpaper-service-contract.sh
git add config/dot/quickshell/services/Wallpaper.qml config/dot/quickshell/services/WallpaperPolicy.js config/dot/quickshell/wallpaper-service-harness.qml tests/quickshell/wallpaper-policy-contract tests/quickshell/wallpaper-service-contract
git commit -m "Add event-driven wallpaper rotation"
```
@@ -219,8 +219,8 @@ git commit -m "Add event-driven wallpaper rotation"
- Modify: `config/dot/quickshell/modules/settings/WallpaperPicker.qml`
- Modify: `config/dot/quickshell/modules/settings/AppearancePage.qml`
- Modify: `config/dot/quickshell/services/SettingsSearch.qml`
- Create: `tests/quickshell/wallpaper-settings-contract.sh`
- Modify: `tests/quickshell/settings-search-contract.sh`
- Create: `tests/quickshell/wallpaper-settings-contract`
- Modify: `tests/quickshell/settings-search-contract`
**Interfaces:**
- Consumes: Wallpaper modes, connected displays, collection membership, assignments, and transaction state.
@@ -232,7 +232,7 @@ Render Appearance in all three modes. Assert Single tile activation calls `setSi
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/wallpaper-settings-contract.sh && tests/quickshell/settings-search-contract.sh`
Run: `tests/quickshell/wallpaper-settings-contract && tests/quickshell/settings-search-contract`
Expected: FAIL because only single-image tile activation exists.
@@ -250,14 +250,14 @@ Place `WallpaperControls` in the existing wallpaper card above `WallpaperPicker`
- [ ] **Step 6: Run and verify GREEN**
Run: `tests/quickshell/wallpaper-settings-contract.sh && tests/quickshell/settings-search-contract.sh && tests/quickshell/settings-ownership-contract.sh`
Run: `tests/quickshell/wallpaper-settings-contract && tests/quickshell/settings-search-contract && tests/quickshell/settings-ownership-contract`
Expected: PASS with no new mirrors or QML warnings.
- [ ] **Step 7: Commit the wallpaper UI**
```bash
git add config/dot/quickshell/modules/settings/WallpaperControls.qml config/dot/quickshell/modules/settings/WallpaperPicker.qml config/dot/quickshell/modules/settings/AppearancePage.qml config/dot/quickshell/services/SettingsSearch.qml tests/quickshell/wallpaper-settings-contract.sh tests/quickshell/settings-search-contract.sh
git add config/dot/quickshell/modules/settings/WallpaperControls.qml config/dot/quickshell/modules/settings/WallpaperPicker.qml config/dot/quickshell/modules/settings/AppearancePage.qml config/dot/quickshell/services/SettingsSearch.qml tests/quickshell/wallpaper-settings-contract tests/quickshell/settings-search-contract
git commit -m "Add wallpaper mode controls"
```
@@ -265,8 +265,8 @@ git commit -m "Add wallpaper mode controls"
**Files:**
- Modify: `config/dot/quickshell/services/SettingsBackup.qml`
- Modify: `tests/quickshell/settings-backup-live-contract.sh`
- Modify: `tests/quickshell/settings-commit-reset-contract.sh`
- Modify: `tests/quickshell/settings-backup-live-contract`
- Modify: `tests/quickshell/settings-commit-reset-contract`
**Interfaces:**
- Consumes: `Wallpaper.applyCurrentPolicy(false)`.
@@ -278,7 +278,7 @@ Restore slideshow and per-monitor fixture snapshots. Assert the restored policy
- [ ] **Step 2: Run and verify RED**
Run: `tests/quickshell/settings-backup-live-contract.sh && tests/quickshell/settings-commit-reset-contract.sh`
Run: `tests/quickshell/settings-backup-live-contract && tests/quickshell/settings-commit-reset-contract`
Expected: FAIL because restore calls `Wallpaper.set(path)` only.
@@ -288,14 +288,14 @@ Inject `applyWallpaperPolicy: function() { return Wallpaper.applyCurrentPolicy(f
- [ ] **Step 4: Run and verify GREEN**
Run: `tests/quickshell/settings-backup-live-contract.sh && tests/quickshell/settings-commit-reset-contract.sh && tests/quickshell/wallpaper-service-contract.sh`
Run: `tests/quickshell/settings-backup-live-contract && tests/quickshell/settings-commit-reset-contract && tests/quickshell/wallpaper-service-contract`
Expected: PASS for both policy modes and shipped reset.
- [ ] **Step 5: Commit restore integration**
```bash
git add config/dot/quickshell/services/SettingsBackup.qml tests/quickshell/settings-backup-live-contract.sh tests/quickshell/settings-commit-reset-contract.sh
git add config/dot/quickshell/services/SettingsBackup.qml tests/quickshell/settings-backup-live-contract tests/quickshell/settings-commit-reset-contract
git commit -m "Restore complete wallpaper policies"
```
@@ -304,12 +304,12 @@ git commit -m "Restore complete wallpaper policies"
- [ ] **Step 1: Run all wallpaper contracts once**
```bash
tests/quickshell/wallpaper-policy-contract.sh
tests/quickshell/wallpaper-service-contract.sh
tests/quickshell/wallpaper-settings-contract.sh
tests/quickshell/settings-backup-live-contract.sh
tests/quickshell/settings-commit-reset-contract.sh
tests/quickshell/settings-search-contract.sh
tests/quickshell/wallpaper-policy-contract
tests/quickshell/wallpaper-service-contract
tests/quickshell/wallpaper-settings-contract
tests/quickshell/settings-backup-live-contract
tests/quickshell/settings-commit-reset-contract
tests/quickshell/settings-search-contract
```
Expected: all PASS. The live desktop wallpaper is never changed by fixture tests.
@@ -31,8 +31,8 @@ verification gate is recorded in the integrating commit history.
- Create: `config/dot/quickshell/services/DefaultApps.qml`
- Create: `config/dot/quickshell/modules/settings/ApplicationsPage.qml`
- Create only if needed for a safe parser/writer boundary: `config/dot/quickshell/scripts/panama-default-apps`
- Create: `tests/quickshell/default-apps-contract.sh`
- Create: `tests/quickshell/applications-settings-contract.sh`
- Create: `tests/quickshell/default-apps-contract`
- Create: `tests/quickshell/applications-settings-contract`
**Interfaces:**
- Consumes: `DesktopEntries.applications.values`, `SettingsPage`, `SettingsCard`, `SettingRow.activatable`, `ActionRow`, `TextRow`, and Claude-owned routing for page id `applications`.
@@ -47,8 +47,8 @@ The page contract must require `DesktopEntries.applications.values`, page id/obj
- [x] **Step 2: Run focused contracts to verify RED**
```bash
tests/quickshell/default-apps-contract.sh
tests/quickshell/applications-settings-contract.sh
tests/quickshell/default-apps-contract
tests/quickshell/applications-settings-contract
```
Expected: fail because the service/page and behavior do not exist.
@@ -60,9 +60,9 @@ All process commands use argument arrays. Validate roles against a fixed map and
- [x] **Step 4: Verify and commit**
```bash
tests/quickshell/default-apps-contract.sh
tests/quickshell/applications-settings-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/default-apps-contract
tests/quickshell/applications-settings-contract
tests/quickshell/settings-pages-contract
```
Commit subject: `Add application and autostart settings`.
@@ -81,8 +81,8 @@ Commit subject: `Add application and autostart settings`.
- Modify: `config/dot/quickshell/modules/settings/ScreenIntelligencePage.qml`
- Modify: `config/dot/quickshell/modules/settings/ServicesPage.qml`
- Modify: `config/dot/quickshell/modules/settings/AboutPage.qml`
- Modify: `tests/quickshell/settings-pages-contract.sh`
- Create: `tests/quickshell/settings-hardcoded-values-contract.sh`
- Modify: `tests/quickshell/settings-pages-contract`
- Create: `tests/quickshell/settings-hardcoded-values-contract`
**Interfaces:**
- Consumes: Claude-owned schema keys `temperatureUnit`, `weatherRefreshMinutes`, `vitalsIntervalMs`, `notificationTimeoutMs`, `notificationTimeoutCriticalMs`, `notificationHistoryLimit`, `maxVisibleToasts`, `screenshotDir`, `recordingDir`, and `recorderArgs`; shared Settings rows; existing services and system handoffs.
@@ -95,8 +95,8 @@ Require all ten `Settings.qml` properties to use `DesktopPreferences.get()` exac
- [x] **Step 2: Run contracts to verify RED**
```bash
tests/quickshell/settings-hardcoded-values-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/settings-hardcoded-values-contract
tests/quickshell/settings-pages-contract
```
Expected: fail on hardcoded properties and copied page scaffolds.
@@ -108,12 +108,12 @@ Use `ChoiceRow` for `temperatureUnit`, `screenshotDir`, `recordingDir`, and `rec
- [x] **Step 4: Run focused and full suite, then commit**
```bash
tests/quickshell/settings-hardcoded-values-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/settings-preferences-contract.sh
tests/quickshell/settings-search-contract.sh
tests/quickshell/settings-hardcoded-values-contract
tests/quickshell/settings-pages-contract
tests/quickshell/settings-preferences-contract
tests/quickshell/settings-search-contract
```
Then run every `tests/quickshell/*.sh`, every `tests/hypr/*.sh`, and all three `tests/quickshell/*_test.py` files sequentially.
Then run every `tests/quickshell/*`, every `tests/hypr/*`, and all three `tests/quickshell/*_test.py` files sequentially.
Commit subject: `Complete Panama settings controls`.
@@ -28,8 +28,8 @@
- Modify: `config/dot/quickshell/modules/settings/HomePhonePage.qml`
- Modify only if required for shared vocabulary compatibility: `config/dot/quickshell/modules/settings/HomeFavoriteCard.qml`
- Modify only if required for shared vocabulary compatibility: `config/dot/quickshell/modules/settings/AvailableLightRow.qml`
- Modify: `tests/quickshell/home-preferences-contract.sh`
- Modify: `tests/quickshell/home-phone-settings-contract.sh`
- Modify: `tests/quickshell/home-preferences-contract`
- Modify: `tests/quickshell/home-phone-settings-contract`
**Interfaces:**
- Consumes: `SettingsPage { title; lede; default content }`, existing `SettingsCard`, `SettingRow`, `ActionRow`, `TextRow`, `HomeAssistant`, `SystemSettings.bluebubblesAvailable`, and writable `HomePreferences` adapter state.
@@ -37,13 +37,13 @@
- [ ] **Step 1: Write failing contracts**
Add `reset()` to the isolated `home-pref-test` IPC harness. Extend `home-preferences-contract.sh` to seed aliases/order, invoke reset, and require both IPC state and `panama-home.json` to become exactly `{"initialized":false,"favorites":[]}` without waiting for the 180 ms debounce interval. Extend `home-phone-settings-contract.sh` to require `SettingsPage {`, `title: "Home & Phone"`, and the existing lede through `lede:`, while rejecting the copied root `Flickable` scaffold.
Add `reset()` to the isolated `home-pref-test` IPC harness. Extend `home-preferences-contract` to seed aliases/order, invoke reset, and require both IPC state and `panama-home.json` to become exactly `{"initialized":false,"favorites":[]}` without waiting for the 180 ms debounce interval. Extend `home-phone-settings-contract` to require `SettingsPage {`, `title: "Home & Phone"`, and the existing lede through `lede:`, while rejecting the copied root `Flickable` scaffold.
- [ ] **Step 2: Run contracts to verify RED**
```bash
tests/quickshell/home-preferences-contract.sh
tests/quickshell/home-phone-settings-contract.sh
tests/quickshell/home-preferences-contract
tests/quickshell/home-phone-settings-contract
```
Expected: the preference contract fails because `reset` is missing; the page contract fails because the page still owns a copied `Flickable` scaffold.
@@ -79,11 +79,11 @@ Use shared `ActionRow` or `TextRow` only where their single-action/read-only con
- [ ] **Step 4: Run focused contracts to GREEN**
```bash
tests/quickshell/home-preferences-contract.sh
tests/quickshell/home-phone-settings-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/home-preferences-contract
tests/quickshell/home-phone-settings-contract
tests/quickshell/settings-pages-contract
tests/quickshell/settings-rows-contract.sh
tests/quickshell/settings-commit-reset-contract.sh
tests/quickshell/settings-commit-reset-contract
```
Expected: every command exits 0; no test launches BlueBubbles or changes a real Home Assistant entity.
@@ -96,8 +96,8 @@ git add config/dot/quickshell/config/HomePreferences.qml \
config/dot/quickshell/modules/settings/HomePhonePage.qml \
config/dot/quickshell/modules/settings/HomeFavoriteCard.qml \
config/dot/quickshell/modules/settings/AvailableLightRow.qml \
tests/quickshell/home-preferences-contract.sh \
tests/quickshell/home-phone-settings-contract.sh \
tests/quickshell/home-preferences-contract \
tests/quickshell/home-phone-settings-contract \
docs/superpowers/plans/2026-08-18-settings-home-phone-completion.md
git commit -m "Finish Home and Phone settings cohesion"
```
@@ -16,7 +16,7 @@ notification server, and a Settings application with thirty-odd pages. Almost al
of it was verified against a running system. Almost none of it was verified against
a system where Panama had just been installed for the first time.
The existing `tests/quickshell/declared-dependencies-contract.sh` was written for
The existing `tests/quickshell/declared-dependencies-contract` was written for
exactly this class of bug and reports PASS, because it checks only commands that
scripts invoke. Fonts, cursor themes, wallpapers, and packages consumed by GUI
handoffs are invisible to it. A dependency checker with a blind spot is worse than
@@ -314,8 +314,17 @@ this way:
- `panama doctor` — front `panama-doctor` from a terminal, not only from Settings
- `panama test` — run every contract under `tests/`, with a pass/fail summary. The
suite is 119 files with no entry point and no mention in the README; it is the
main safety net and it is currently invisible.
suite had no entry point and no mention in the README; it is the main safety net
and it was invisible.
Building the runner found three tests that nothing was running.
`calendar_agenda_bridge_test.py`, `home_assistant_bridge_test.py` and
`kdeconnect_bridge_test.py` are `unittest` suites without the executable bit, so
no contract invoked them and the first draft of this runner skipped them in
silence. All three pass, and have presumably passed unobserved for weeks. The
runner now collects `*_test.py` as well, because a runner with a blind spot is
worse than no runner for the same reason a dependency checker with one is: it
reports PASS.
- `panama upgrade` — re-run `./install` from anywhere
### Dropping the `.sh` extension
@@ -324,7 +333,7 @@ this way:
`config/local/share/vicinae/scripts`, 2 under `tests/hypr`. All are already
executable and all already carry a bash shebang, so the rename is `git mv` plus
three comment references and two lines in `panama-settings-commands`, which
generates the Vicinae command files and globs for `settings-*.sh`.
generates the Vicinae command files and globs for `settings-*`.
The one real risk is Vicinae's script discovery. Its documentation states a script
command needs a plain text file, the three `@vicinae.*` directives, a shebang, and
@@ -334,6 +343,19 @@ to act on, but not close enough to skip verifying: after the rename, reload with
before the change is considered done. If discovery does key off the extension, the
Vicinae directory is exempted and the reason recorded here.
**Verified, and discovery does not.** One script was renamed first and reloaded on
its own; it came back as `scripts:panama.capture`, so the whole set followed and
all 47 resolve.
What the probe did turn up is that the extension was never only a filename:
Vicinae's command IDs embed it, so every ID changed — `scripts:panama.capture.sh`
became `scripts:panama.capture`. Nothing in this repository refers to those IDs,
so nothing breaks. The only trace is Vicinae's own `metadata.json`, whose
`visited` map had two Panama entries that are now orphaned; the effect is that two
commands lost their usage ranking and will earn it back. Worth knowing before
renaming these files again, and worth checking for a keybind or deeplink first on
a machine that has one.
### Machine-specific configuration
Monitor layout, keybinds and input differences stay in gitignored local state —
@@ -422,10 +444,17 @@ installer. They remain recoverable from sunhat's git history.
hardening, with its own spec and plan. It does not conflict with this work — it
*depends* on it, since its lock generator falls back to the shipped wallpaper this
spec makes exist. Rebasing it is its own task.
- Six worktrees remain on branches already merged to `main`
- **Done.** Six worktrees remained on branches already merged to `main`
(`home-accessories-customization`, `panama-commands`, `panama-displays-review`,
`panama-settings-home-phone`, `settings-notification-rules`, `settings-ownership`).
They are clutter, not risk; pruning them stays in phase 6.
`panama-settings-home-phone`, `settings-notification-rules`, `settings-ownership`),
and all six are pruned. Each was re-checked rather than trusted to this list:
`git cherry main <branch>` reported nothing unique and every working tree was
clean. Two needed the check. `panama-commands` is not on `feat/panama-commands`
at all but on `feat/gnome-tweaks-parity` — the directory name and the branch had
drifted apart. And `fix/panama-displays-review` reads `[ahead 3]`, which is ahead
of its *remote*, not of `main`; all three commits are patch-equivalent to work
already landed. The branches themselves are left alone: pruning a worktree costs
nothing, and deleting a branch is somebody's decision rather than tidying.
- Guard the `.cargo/env` source in `config/bash/.bashrc` and remove the Codex block.
- Rewrite the README: one desktop, the real install stages, and the test suite.
- **Done, and it needed nothing.** `docs/settings.md` is generated from
+1 -1
View File
@@ -2,7 +2,7 @@
# Every asset Panama's desktop names must be something Panama installs.
#
# This is the sibling of declared-dependencies-contract.sh, and it exists because
# This is the sibling of declared-dependencies-contract, and it exists because
# that contract has a structural blind spot. It checks commands that scripts
# invoke -- so it reports PASS on a machine where the shell's icon font, the
# pointer theme, the wallpaper and four GUI applications are all missing, because

Some files were not shown because too many files have changed in this diff Show More