Files
Panama/docs/superpowers/specs/2026-08-25-agent-integration.md

12 KiB

Agent integration: the machine carries its own manual for AI hands

Approved direction (2026-08-25 interview): three Claude-Code skills, delivery approach A (per-skill symlinks under a real ~/.claude/skills), a ledger-backed panama test --safe, and panama contracts <file>. Factual content only — Gabriel's personal preferences stay in his own CLAUDE.md and are out of scope. Everything the skills claim is contract-pinned, because an agent believes the manual verbatim.

Decisions log

Decision Choice
Audience Claude Code skills; no AGENTS.md (YAGNI until another tool is in use)
Skill count Three: panama (develop), panama-desktop (operate), panama-sudo (privilege)
Gating Shipped to every machine, un-gated; personal content stays gated as today
Dev-skill home In-repo .claude/skills/panama/ (project-level, auto-discovered in the checkout)
Global delivery Approach A: real ~/.claude/skills dir + per-skill symlinks; new linkdir manifest kind for personal skills
CLI expansion Moderate: panama contracts <file> + panama test --safe; doctor already speaks JSON
Test safety tests/desktop-hijacking ledger + --safe flag + honesty contract
Coverage lookup Heuristic grep, tier-marked from the ledger, honest when empty
Skill claims Pinned by a new skills-contract

The three skills

House format per user/agents/skills/writing-for-agents/: frontmatter is name + description only, H1 matches the name, ~100-column wrap, sibling files via relative links. The rule for all three: point, don't duplicate. A skill orients and warns; the facts live in the documents and commands the repo already maintains, so the rot surface is the pointer, not the prose. Skills are written by the orchestrator (not fanned out) — they are the heart of the feature and draw on session knowledge.

.claude/skills/panama/ — developing Panama (project-level)

Discovered automatically for any session inside the checkout; needs no delivery machinery and works in forks. Description triggers on working in the Panama repo. Contents:

  1. Orientation — one paragraph on what Panama is; pointers: README.md (layout, the panama command), config/dot/hypr/README.md (Lua-not-hyprlang, the one thing to know first), config/dot/quickshell/modules/settings/README.md (adding a setting, ownership, "things that will bite you", where state lives), docs/settings.md (generated reference).
  2. The live-desktop covenant — the distilled never-list, each item one line with its source pointer: every save of config/dot/quickshell/** hot-reloads the live shell, so every save must leave valid QML; check the journal for errors AND "Unable to assign" after each batch (command form included); components in modules/* require same-save qmldir registration; never qs kill from a copied configuration; never hyprctl keyword — and eval exits 0 on error, so read back with getoption; no duplicate IPC targets; annotate every IPC parameter and return type; no continuously-repainting animations; batch compositor reloads and announce them; readAs describes the answer, not the setting; don't touch the hyprlang configs that never moved to Lua; no new notification daemon; scripts carry no .sh extension except migrations/*.sh; no secrets under user/.
  3. The contract discipline — contracts live under tests/, run via panama test [pattern] or directly; run the covering contracts for what you touched (panama contracts <file> names them); during a desktop session run panama test --safe — the tests/desktop-hijacking ledger is the list of what it skips and why; regenerate docs/settings.md and the settings commands after schema/route changes (panama-settings-docs, panama-settings-commands, both --check-able); the README pins the contract count and subcommand list.
  4. Seams for testing — fixture env vars (PANAMA_*_HELPER, PANAMA_*_FIXTURE, PANAMA_*_STATIC_ONLY), the harness discipline (distinct semantic entry file, qs -p, PID from qs list --all, kill only that PID), hermetic-by-construction helpers (validated inputs, JSON out, stdin-only secrets).
  5. Safety idioms — ConfirmAction/ErrorRow/NotMeasuredRow/SettingsNote exist; destructive actions are two-stage; stored actions are data resolved through whitelists, never commands (settings-idiom-contract, keybind-rebind-contract pin these).

skills/panama-desktop/ — operating the desktop (global)

For an agent doing any task on a Panama machine: how to drive the desktop honestly. Description triggers on desktop interaction (opening settings, checking system health, screenshots, notifications, audio/network/display questions) on a Panama machine. Contents:

  1. panama doctor — JSON by default (schemaVersion 1), --summary, check <id>, --repair <id>; the 30 check ids by group.
  2. panama-action <verb> as the stable boundary for desktop actions (the verb list), and qs ipc call <target> <fn> beneath it for what panama-action doesn't cover — pointer to shell.qml for the target table rather than duplicating it.
  3. Settings: open pages via panama-action settings-page <id>; change values through the Settings UI or IPC, not by editing ~/.config/panama/settings.json (the shell's in-memory model wins for keys it has touched); where state lives (the state-paths table pointer).
  4. panama-launch --class for focus-or-launch; panama test --safe if asked to verify the desktop; panama update for keeping the machine current.
  5. Privilege: one line — load panama-sudo before anything needing root.

skills/panama-sudo/ — privilege etiquette (global)

Small. Description triggers on any need for root/sudo/pkexec on a Panama machine. Contents: never bare sudo/pkexec; use panama-sudo --reason "why" -- cmd args; --reason must be first; the reason appears beside (never instead of) polkitd's own action text; degrades to plain pkexec with no shell running; migrations already follow this rule (bin/panama-migrate). Include the one-line trust model so agents phrase reasons honestly: state what the command does, not why it is safe.

Delivery: approach A

New root skills/

skills/panama-desktop/SKILL.md, skills/panama-sudo/SKILL.md (+ sibling files if needed). Repo-root README.md layout table gains the row (readme-contract pins the layout block).

Un-gated. Behavior:

  1. If ~/.claude/skills is a symlink (today: → user/agents/skills), remove it (symlink removal never displaces to config/old, matching link-user's rule) and mkdir -p a real directory.
  2. For each child of $PANAMA_PATH/skills/, displace any existing real entry at ~/.claude/skills/<name> to config/old/ (house displace semantics; symlinks just removed) and link ~/.claude/skills/<name>$PANAMA_PATH/skills/<name>.
  3. Report Agent skills: N linked.

install STAGES gains link-skills after link-dotfiles, before link-user (personal must win name collisions by linking last, mirroring Claude Code's personal-over-project precedence), in both the full list and upgrade_stages. tests/setup/update-command-contract pins STAGE_NAMES — its list gets the new entry as part of this work.

user/manifest line link agents/skills ~/.claude/skills becomes linkdir agents/skills ~/.claude/skills: for each child of the source, displace and link it as a direct child of the destination (creating the destination as a real directory if needed). Whole-dir link entries (~/.agents/skills, CLAUDE.md, rules) are untouched. user/README.md documents the new kind. Known behavior, recorded not fixed: a personal skill named like a shipped one shadows it (deliberate — personal wins); a new personal skill needs a re-link (panama update or setup/scripts/link-user) to appear, where the old whole-dir link showed it instantly.

CLI additions (bin/panama)

House three-touchpoint rule: header comment, usage(), main() — plus the README subcommand list (readme-contract cross-checks it).

panama contracts <file>

Heuristic: resolve the argument to a repo-relative path; scan tests/ (excluding fixtures/, __pycache__) for contracts whose text contains the path, any parent-trimmed suffix of it, or the basename. Output one line per hit: tests/<name> [safe|desktop], tier read from the ledger. No hits → No contract mentions <path> — coverage may be indirect (a harness or a generated artifact); nothing verified. and exit 1. No options.

panama test --safe [pattern]

--safe (position-independent, before or after the pattern): filter out every contract listed in tests/desktop-hijacking, run the rest exactly as today, and end the summary with Skipped N desktop-hijacking contract(s) (tests/desktop-hijacking). Plain panama test is unchanged.

The ledger: tests/desktop-hijacking

Package-list style: one repo-relative contract path per line, # comments; each entry's comment says what it does to the session (restarts the shell; latches caffeine; opens live overlays; writes every schema key against the real compositor; touches real xdg-mime defaults; …). Seeded from the tier-3 inventory in the exploration (focus-session-restart, focus-session-expiry, settings-window, overview-live-actions, switcher, welcome, cheatsheet, status-events, activity-, accessibility, calendar-agenda, screen-intelligence, panama-action-ipc, panama-commands, panama-doctor, polkit-reason, signal-glass, settings-write-sweep, settings-system, default-apps-, gnome-handoff — verified individually during the build, not copied blind).

New contracts

tests/setup/skills-contract

  1. The two shipped skills and .claude/skills/panama exist with valid frontmatter (name matches the directory, non-empty description, nothing else required).
  2. Claim pinning: every `panama <sub>` subcommand a skill names exists in bin/panama's dispatcher; every `panama-<tool>` exists in bin/ or the quickshell scripts dir; every backticked repo path exists; every PANAMA_* env var it names appears somewhere in the tree; every panama-action verb it names is in panama-action's dispatch. (Convention this imposes on skill prose: commands, paths and variables are always backticked and exact — which is how they should be written anyway.)
  3. link-skills exists, is in STAGES and upgrade_stages ordered after link-dotfiles and before link-user; the manifest uses linkdir for agents/skills; link-user implements linkdir.

tests/setup/desktop-hijacking-contract

  1. Every ledger entry names an existing contract.
  2. Honesty sweep: every contract under tests/ that drives the live shell — matches qs ipc call without booting its own qs -p harness, or restarts panama-quickshell.service, or calls qs kill — must be listed; the sweep's heuristics live in this contract so a new hijacking contract cannot stay unlisted.
  3. cmd_test honors the ledger: static check that --safe reads the file.

README test count: +2 (the "N of them" line — orchestrator's, updated at the end).

Build plan and ownership

  • Orchestrator: this spec; the three skills' content; final seam audit; README count.
  • Agent A: bin/panama (cmd_contracts, --safe), tests/desktop-hijacking (verifying each seeded entry by reading the contract), tests/setup/desktop-hijacking-contract, README subcommand-list rows.
  • Agent B: setup/scripts/link-skills, linkdir in setup/scripts/link-user, user/manifest, user/README.md, install STAGES + upgrade_stages, tests/setup/skills-contract, updates to tests/setup/update-command-contract and tests/setup/user-content-contract where their pins move, README layout row.

Disjoint by construction; the skills (orchestrator) reference what A and B build, so the skills land last and skills-contract runs after both.

Out of scope (recorded)

Generic AGENTS.md; a Claude Code plugin; panama map/agent namespace; JSON output for panama test; shipping any of Gabriel's personal preferences; per-contract header annotations (the ledger supersedes); auto-relink on personal-skill creation.