diff --git a/.claude/skills/panama/SKILL.md b/.claude/skills/panama/SKILL.md index 2f11633..55db7df 100644 --- a/.claude/skills/panama/SKILL.md +++ b/.claude/skills/panama/SKILL.md @@ -50,13 +50,16 @@ Editing `config/dot/quickshell/**` hot-reloads the live shell on every save. ## The contract discipline -~180 executable contracts under `tests/` pin behavior. The rules: +Every executable contract under `tests/` is classified in `tests/contracts.manifest`. The rules: - `panama contracts ` names the contracts that mention a file; run those after touching it. -- During a desktop session, run `panama test --safe [pattern]` — it skips everything listed in - `tests/desktop-hijacking` (contracts that restart the shell, open real overlays, or write - through the live compositor). Run the full `panama test` only with the user's go-ahead, and say - so first: it visibly hijacks the desktop. +- During a desktop session, run `panama test --safe [pattern]`. `--safe` selects only contracts + classified as `hermetic`. +- A plain full run prompts in a terminal before any selected non-hermetic contract starts. In + automation, grant every required capability with repeatable flags, for example + `panama test --allow live-compositor --allow live-desktop keybinds`. +- Each contract has a 180-second outer timeout by default. Override it with a positive + `PANAMA_TEST_TIMEOUT_SECONDS` value. Failures print the contract's captured stdout and stderr. - Contracts run directly too: `tests/setup/interview-contract`. - After changing `PreferenceSchema.qml` or `services/SettingsRoutes.qml`, regenerate: `config/dot/quickshell/scripts/panama-settings-docs` (writes `docs/settings.md`) and diff --git a/README.md b/README.md index 42de6ff..2dd8492 100644 --- a/README.md +++ b/README.md @@ -198,14 +198,25 @@ docs/ Settings reference, and the design specs behind the work ## Tests -186 of them, under `tests/`. Run the lot, or a subset by pattern: +186 of them, under `tests/`. `tests/contracts.manifest` classifies every +contract by the capabilities it needs. Run the hermetic set, or grant a +specific external capability when automation needs it: ```sh -panama test # everything -panama test dock # just the ones matching "dock" +panama test --safe +panama test --allow live-host updates +panama test --allow live-compositor keybinds +PANAMA_TEST_TIMEOUT_SECONDS=300 panama test --safe tests/setup/interview-contract # or one directly; they are plain executables ``` +`--safe` means hermetic contracts only. A plain full run prompts in a terminal +before it starts any non-hermetic contract. Automation cannot answer that +prompt, so it must grant every required capability with a repeatable `--allow`. +Each contract has a 180-second outer timeout by default. Set +`PANAMA_TEST_TIMEOUT_SECONDS` to a positive integer to override it. When a +contract fails, the runner prints its captured stdout and stderr. + They are called contracts rather than unit tests because that is what they are: each one pins a decision that was expensive to get right and is cheap to undo by accident. Most read or measure the real thing — launching a shell to measure a @@ -243,8 +254,9 @@ panama sync # review, commit and push your changes to this repo panama edit # open it in Neovim panama doctor # what is actually running, not what was installed panama diagnose # hand the health summary and recent errors to your agent -panama test # every contract, or a subset by pattern -panama test --safe # the same, minus the ones that take over the desktop +panama test # every contract, prompting before non-hermetic work +panama test --safe # hermetic contracts only +panama test --allow live-host updates # grant one capability to automation panama contracts # which contracts mention a file, and can they be run panama migrate # apply repairs this machine has not had yet panama upgrade # re-run ./install from anywhere, interview and all diff --git a/bin/panama b/bin/panama index a2b3a18..9b0d76c 100755 --- a/bin/panama +++ b/bin/panama @@ -10,7 +10,7 @@ # edit Open the Panama repo in Neovim # doctor Report what is actually running on this machine # diagnose Hand this machine's health and recent errors to your agent -# test Run contract manifest entries under tests/ (--safe is hermetic only) +# test Run contracts classified by tests/contracts.manifest # contracts Name the contracts that mention a given file # upgrade Re-run the installer from anywhere, interview included # migrate Apply repairs this machine has not had yet @@ -85,10 +85,12 @@ ${BOLD}Commands:${RESET} ${GREEN}diagnose${RESET} Hand the health summary, the recent journal errors and whatever you say is wrong to your coding agent, in a terminal. Needs an agent chosen on Settings › System › Agents. - ${GREEN}test${RESET} Run every contract under tests/. Give it a pattern to run - a subset: 'panama test dock' runs the ones matching 'dock'. - --safe runs hermetic contracts only. External capabilities need - explicit --allow grants when automation invokes them. + ${GREEN}test${RESET} Run contracts classified by tests/contracts.manifest. Give it a + pattern to run a subset. --safe selects hermetic contracts only. + Plain terminal runs prompt before non-hermetic work. Automation + must grant each required capability with a repeatable --allow. + Failures print captured stdout/stderr; the default outer timeout + is 180 seconds. ${GREEN}contracts${RESET} Name the contracts that mention a given file, each labeled with manifest capabilities. A heuristic over the text of tests/, so it answers "what should I run" rather than "what covers this". @@ -121,6 +123,9 @@ ${BOLD}Examples:${RESET} $PROGRAM diagnose the bar disappears after unplugging the monitor $PROGRAM test dock $PROGRAM test --safe + $PROGRAM test --allow live-host updates + $PROGRAM test --allow live-compositor keybinds + PANAMA_TEST_TIMEOUT_SECONDS=300 $PROGRAM test --safe $PROGRAM contracts config/dot/quickshell/services/Displays.qml $PROGRAM upgrade $PROGRAM apps @@ -474,20 +479,19 @@ is_contract_capability() { # 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. +# The contracts are the main safety net in this repository. The manifest is the +# single list of what the runner executes and which external boundaries each +# contract reaches. # # 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. # -# --safe exists because a fair number of these contracts ARE the desktop: they -# open overlays, restart the shell, move your windows. Running the suite while -# sitting in front of the machine used to mean losing the session for a few -# minutes, so the honest options were "run everything" or "run nothing". --safe -# is the third: run only contracts the manifest classifies as hermetic, and say -# which external capability coverage it skipped. +# --safe runs only contracts the manifest classifies as hermetic and reports +# each external capability it skipped. A plain terminal run asks before any +# selected non-hermetic work. Automation must grant every required capability +# with repeatable --allow flags. Each contract gets an outer timeout, 180 +# seconds by default, and failures include the captured stdout and stderr. cmd_test() { local timeout_seconds="${PANAMA_TEST_TIMEOUT_SECONDS:-180}" [[ "$timeout_seconds" =~ ^[1-9][0-9]*$ ]] || { @@ -658,10 +662,8 @@ cmd_test_impl() ( # Command: contracts # ---------------------------------------------------------------------------- # -# "I changed this file -- what should I run?" There are 177 contracts and no -# index, so the honest answers were "all of them" (minutes, and half of them -# take the desktop away) or "the ones whose name sounds related" (which is how -# a covering contract gets skipped). +# "I changed this file -- what should I run?" The suite is large enough that +# running all of it or guessing from contract names are both poor answers. # # This is a grep, and says so. A contract that names the file, or a # parent-trimmed suffix of it, or just its basename, is a contract worth diff --git a/skills/panama-desktop/SKILL.md b/skills/panama-desktop/SKILL.md index af7d696..3da1339 100644 --- a/skills/panama-desktop/SKILL.md +++ b/skills/panama-desktop/SKILL.md @@ -40,7 +40,13 @@ Other tools that beat raw commands: - `panama-launch --class '' -- cmd…` — focus the window if it exists, launch otherwise - `panama-sudo --reason "why" -- cmd…` — root work; load the `panama-sudo` skill first - `panama update` — bring the machine current (pull, repairs, unattended stages); asks nothing -- `panama test --safe` — verify the desktop's contracts without hijacking the session +- `panama test --safe` — run only contracts classified as hermetic in + `tests/contracts.manifest` + +A plain `panama test` prompts in a terminal before it starts non-hermetic contracts. Automation +must grant each required capability with a repeatable `--allow`, such as +`panama test --allow live-host updates`. Each contract has a 180-second outer timeout by default, +and failures print captured stdout and stderr. ## Settings