134 lines
8.3 KiB
Markdown
134 lines
8.3 KiB
Markdown
---
|
|
name: panama
|
|
description: Use when working on the Panama repository itself — editing anything under config/, setup/, bin/, tests/, or the Quickshell shell and Hyprland Lua it ships. Covers the live-desktop hot-reload rules, the contract-test discipline, the fixture seams, and where the real documentation lives.
|
|
---
|
|
|
|
# panama
|
|
|
|
You are editing a running desktop, not a codebase that gets deployed later. Every dotfile in this
|
|
repository is symlinked into `~/.config`, so a save is live the moment it lands. That single fact
|
|
drives every rule below.
|
|
|
|
Read before large work, in this order:
|
|
|
|
- `README.md` — layout, the `panama` command, how installing and updating work
|
|
- `config/dot/hypr/README.md` — the compositor config is **Lua, not hyprlang**; read "The one
|
|
thing to know first" and "Never use `hyprctl keyword`" before touching it
|
|
- `config/dot/quickshell/modules/settings/README.md` — adding a setting, setting ownership,
|
|
"Things that will bite you", and where state lives; the most load-bearing document here
|
|
- `docs/settings.md` — generated reference for every settings key (never edit by hand)
|
|
|
|
## The live-desktop covenant
|
|
|
|
Editing `config/dot/quickshell/**` hot-reloads the live shell on every save.
|
|
|
|
1. Every save must leave valid QML. An intermediate broken save is a broken desktop, not a broken
|
|
build. Convert a component and its body in ONE edit, never two.
|
|
2. After each batch of saves, check the journal for errors AND "Unable to assign" warnings:
|
|
`journalctl --user -u panama-quickshell.service --since '-2 minutes' --no-pager`
|
|
3. Every `.qml` file in `config/dot/quickshell/modules/*` must be registered in that directory's
|
|
`qmldir` in the same save batch. An unregistered component fails the whole configuration and
|
|
takes down the bar, dock, and settings together. `tests/quickshell/qmldir-registration-contract`
|
|
is pure file inspection — run it before the change lands.
|
|
4. Never `qs kill` from a copied configuration: Quickshell derives the shell ID from config
|
|
content, so a content-identical harness can share the live shell's ID and kill the desktop.
|
|
Harnesses use a distinct entry file, `qs -p`, the PID from `qs list --all`, and `kill` that PID.
|
|
5. Never `hyprctl keyword` — Lua-configured Hyprland refuses it, prints to stdout, and exits 0.
|
|
`hyprctl eval` also exits 0 on errors. The only proof a write landed is `hyprctl getoption`
|
|
reading it back. Batch `hyprctl reload` to one per verified change-set, and say when you do it.
|
|
6. IPC: annotate every parameter and return type or Quickshell silently skips registration; never
|
|
duplicate an `IpcHandler` target — one silently shadows the other.
|
|
7. In `config/dot/quickshell/config/PreferenceSchema.qml`, `readAs` describes the compositor's
|
|
ANSWER shape, not the setting's; a wrong one makes every successful write look rejected.
|
|
8. No continuously repainting animations (pulse, shimmer, spinners) — they peg the GPU on
|
|
high-refresh displays.
|
|
9. `hyprlock.conf`, `hypridle.conf`, `hyprpaper.conf`, `hyprtoolkit.conf` never moved to Lua. Do
|
|
not "fix" them. Do not install a notification daemon — the shell is one.
|
|
10. Scripts carry no `.sh` extension (shebang + `chmod +x`), with one deliberate exception:
|
|
`migrations/*.sh`, which `bin/panama-migrate` globs. No secrets under `user/` — it is
|
|
world-readable and `tests/setup/user-content-contract` greps for key material.
|
|
|
|
## The contract discipline
|
|
|
|
Every executable contract under `tests/` is classified in `tests/contracts.manifest`. The rules:
|
|
|
|
- `panama contracts <file>` names the contracts that mention a file; run those after touching it.
|
|
- 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.
|
|
Successful stdout stays quiet. Successful stderr is surfaced as a warning.
|
|
- 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
|
|
`config/dot/quickshell/scripts/panama-settings-commands` (writes the launcher deep links).
|
|
Both take `--check`; `tests/quickshell/settings-docs-contract` fails when stale.
|
|
- `README.md` pins the contract count and the `panama` subcommand list
|
|
(`tests/setup/readme-contract`); adding a contract or subcommand means updating it.
|
|
|
|
## Seams for testing
|
|
|
|
Helpers are built hermetic: validated inputs, JSON out, secrets on stdin only (never argv).
|
|
Contracts reach them through env seams — `PANAMA_NETWORK_HELPER`, `PANAMA_FINGERPRINT_FIXTURE`,
|
|
`PANAMA_EXTRAS_DIR`, and the `PANAMA_*_STATIC_ONLY` family that cuts a contract to its
|
|
file-inspection half. Prefer exercising a helper through its contract's stubbed PATH over running
|
|
it against the real system.
|
|
|
|
## Safety idioms (contract-enforced)
|
|
|
|
- Destructive actions are two-stage: `ConfirmAction` with a unique `actionId`, arbitrated through
|
|
`ShellState.armedConfirm` — one armed confirm app-wide. Danger tone marks only the confirming
|
|
press.
|
|
- Failures render through `ErrorRow`; honest empty states through `NotMeasuredRow` with a
|
|
`because:`; paragraph-length notes through `SettingsNote`.
|
|
- Stored user actions (custom shortcuts, gestures, window rules) are DATA — an enum kind and a
|
|
validated target resolved through whitelist tables in `config/dot/hypr/actions.lua`. Nothing in
|
|
`~/.config/panama/settings.json` may ever be an executable command; the contracts
|
|
(`tests/quickshell/settings-idiom-contract`, `tests/quickshell/keybind-rebind-contract`) pin all
|
|
of this.
|
|
|
|
## Root work
|
|
|
|
Never bare `sudo`. Load the `panama-sudo` skill first. Migrations already follow the rule.
|
|
|
|
## Initial bootstrap trust
|
|
|
|
Use the complete command in `README.md` for a new machine. It downloads `boot`
|
|
from the documented commit URL into a private temporary directory, enforces the
|
|
documented curl time and byte limits, verifies the committed blob with
|
|
`sha256sum -c`, and passes both pins to the verified script. Desktop and server
|
|
bootstrap use the same commit and digest. Never substitute a branch URL, pipe a
|
|
response into Bash, or invent a newer pin from an uncommitted file.
|
|
|
|
`boot` validates the full lowercase commit and SHA-256 before Git or install. A
|
|
fresh destination fetches only that revision and creates a tracked local `main`
|
|
after HEAD matches. An existing checkout must be clean and an ancestor of the
|
|
requested revision; it advances with fast-forward only. Dirty, divergent,
|
|
fetch-failed, or mismatched checkouts stop without reset or install. Once Panama
|
|
exists, use `panama update` for normal updates.
|
|
|
|
`boot --server` is the one exception where a new Fedora VPS may begin as root.
|
|
Before it offers SSH hardening, it copies a safe root key when possible or
|
|
verifies the target key. The target user's `.ssh` must be owned by that user at
|
|
`0700`, and `authorized_keys` must be owned by that user at `0600`. Without a
|
|
verified target key, SSH hardening is unavailable and the bootstrap continues.
|
|
Every non-comment key line must parse with `ssh-keygen`. Root-key destination
|
|
creation and writing run as the target UID, followed by the same owner, mode,
|
|
and key checks. Do not replace that with root writes or assume the user's
|
|
primary group matches the username.
|
|
|
|
Accepted hardening uses atomic same-directory `00-panama.conf` with exactly
|
|
`PermitRootLogin no`, `PasswordAuthentication no`, and
|
|
`KbdInteractiveAuthentication no`. A pre-existing symlink or non-regular
|
|
object makes hardening unavailable, as does a missing SSH unit. Panama runs
|
|
`sshd -t`, then checks effective root and target-user policy with `sshd -T -C`
|
|
before reloading the detected unit. Validation or reload failure restores a
|
|
prior regular file with its metadata before it retries validation and reload.
|
|
Failed recovery stops the handoff with instructions that distinguish a prior
|
|
file from no prior file. The fixture contracts also cover declined hardening
|
|
and interrupted preparation. `panama test --safe` never reloads a live daemon,
|
|
so it is not live-host proof.
|