Files
Panama/docs/superpowers/plans/2026-08-26-verification-gate-remediation.md
T

30 KiB

Verification Gate Remediation Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan.

Goal: Make Panama's contract gate honest, safe by default when requested, diagnostic on failure, and capable of proving the later repository-audit fixes.

Architecture: Replace the incomplete desktop-hijacking ledger with one explicit manifest covering every collected contract. bin/panama remains the public runner: it parses that manifest, applies capability policy, executes each selected contract under a bounded timeout, and preserves its diagnostics. Contracts that currently depend on the calendar, tracked files, the live settings store, or source-text inspection are changed to exercise disposable fixtures and real public commands.

Tech Stack: Bash 5, Python 3 standard library, Git fixture repositories, existing Panama contract executables, Quickshell test harnesses.

Spec: docs/superpowers/specs/2026-08-26-repository-audit-remediation-design.md, Package 1: Verification gate.

Global Constraints

  • Preserve the user's existing config/bash/.bashrc changes. Do not stage or edit that file.
  • Do not run plain panama test during implementation. It is intentionally interactive once this plan lands and several entries manipulate the live desktop.
  • Do not start or restart the production Quickshell, Hyprland, or system services.
  • Use apply_patch for every repository edit.
  • Test public behavior. Source inspection may enforce a narrow declarative invariant, but must not substitute for executing bin/panama or a helper.
  • Keep every contract self-cleaning on success, failure, signal, and timeout.
  • Commit after each task with only that task's files staged.

Task 1: Replace the desktop ledger with a complete contract manifest

Files:

  • Create: tests/contracts.manifest
  • Create: tests/setup/contract-manifest-contract
  • Delete: tests/setup/desktop-hijacking-contract
  • Delete: tests/desktop-hijacking
  • Modify: README.md

Step 1: Write the failing manifest contract

Create tests/setup/contract-manifest-contract as an executable Bash contract. It must independently discover contracts exactly as the runner does:

while IFS= read -r path; do
    [[ -x "$path" || "$path" == *_test.py ]] || continue
    printf 'tests/%s\n' "${path#"$repo_dir/tests/"}"
done < <(find "$repo_dir/tests" -type f \
    -not -path '*/fixtures/*' -not -path '*__pycache__*' | sort)

Parse non-comment manifest lines as two whitespace-separated fields:

<comma-separated-capabilities> <repo-relative-contract-path>

Assert all of the following:

  • every discovered contract appears exactly once;
  • every manifest path is discovered by the runner;
  • paths are sorted lexicographically;
  • hermetic appears alone;
  • non-hermetic entries use only live-host, live-compositor, live-desktop, network, and privileged;
  • every non-hermetic entry has a directly preceding comment explaining the external effect;
  • no path or capability is duplicated on one line;
  • the manifest contains at least one entry for each capability except privileged, which is supported but not currently required by a contract.

Include a parser-fixture section in the same contract. Copy the manifest parser logic into a temporary malformed manifest for each rejection case (missing contract, stale path, duplicate path, unknown capability, hermetic,network, unsorted paths, and uncommented non-hermetic entry) and assert each fixture fails with a message naming the defect.

Run:

chmod +x tests/setup/contract-manifest-contract
tests/setup/contract-manifest-contract

Expected: FAIL because tests/contracts.manifest does not exist.

Step 2: Add the complete manifest

Add one line for each contract discovered by the command in Step 1. Start every path not named below as hermetic. Apply this audited non-hermetic classification exactly:

Capabilities Contract
live-compositor,live-desktop tests/quickshell/activity-indicator-contract
live-desktop tests/quickshell/activity-state-contract
live-host tests/quickshell/adwaita-accent-contract
live-host tests/quickshell/application-volume-contract
live-compositor,live-desktop tests/quickshell/calendar-agenda-contract
live-host tests/quickshell/calendar-agenda-helper-contract
live-compositor,live-desktop tests/quickshell/cheatsheet-contract
live-host tests/quickshell/connectivity-contract
live-compositor,live-desktop tests/quickshell/control-center-contract
live-compositor,live-desktop tests/quickshell/control-center-services-contract
live-desktop tests/quickshell/default-apps-roles-contract
live-host tests/quickshell/default-apps-family-contract
live-desktop tests/quickshell/display-arrangement-contract
live-compositor,live-desktop tests/quickshell/displays-contract
live-host tests/quickshell/disks-contract
live-desktop tests/quickshell/dock-position-contract
live-compositor tests/quickshell/enum-hypr-map-contract
network tests/setup/extras-contract
live-compositor,live-desktop tests/quickshell/focus-session-contract
live-desktop tests/quickshell/focus-session-expiry
live-desktop tests/quickshell/focus-session-restart
live-host tests/quickshell/firewall-contract
live-host tests/quickshell/gaming-contract
live-desktop tests/quickshell/health-ui-contract
live-compositor tests/hypr/keybind-categories-contract
live-compositor tests/quickshell/keybind-rebind-contract
live-compositor tests/quickshell/keybinds-contract
network tests/quickshell/home-assistant-helper-contract
live-compositor,live-desktop tests/quickshell/my-home-settings-contract
live-host tests/quickshell/overview-window-actions-contract
live-compositor,live-desktop tests/quickshell/overview-live-actions
live-compositor,live-desktop tests/quickshell/overview-search-contract
live-desktop tests/quickshell/panama-action-ipc-contract
live-compositor,live-desktop tests/quickshell/phone-page-contract
live-host tests/quickshell/polkit-agent-contract
live-host tests/quickshell/printers-contract
live-compositor,live-desktop tests/quickshell/scratchpad-shelf-contract
live-compositor tests/quickshell/schema-hypr-shape-contract
live-desktop tests/quickshell/screen-intelligence-contract
live-compositor,live-desktop tests/quickshell/settings-hyprland-write-contract
live-compositor,live-desktop tests/quickshell/settings-pages-contract
live-compositor,live-desktop tests/quickshell/settings-system-contract
live-compositor,live-desktop tests/quickshell/settings-window-contract
live-compositor,live-desktop tests/quickshell/settings-write-sweep-contract
live-host tests/quickshell/sharing-contract
live-compositor,live-desktop tests/quickshell/signal-glass-contract
live-host tests/quickshell/snapshots-contract
live-host tests/quickshell/sound-page-contract
live-host tests/quickshell/ssh-keys-contract
live-desktop tests/quickshell/status-events-contract
live-compositor,live-desktop tests/quickshell/switcher-contract
live-host tests/quickshell/updates-contract
live-host tests/quickshell/user-accounts-contract
live-host tests/setup/hardware-predicates-contract
live-compositor,live-desktop tests/quickshell/welcome-contract

For each non-hermetic line, move the useful explanation from tests/desktop-hijacking directly above the entry. Add concise comments for the newly discovered entries describing the exact network, compositor-read, or window-mapping behavior.

Run:

tests/setup/contract-manifest-contract

Expected: PASS with the discovered and manifested counts equal.

Step 3: Remove the old ledger and update the documented count

Delete tests/desktop-hijacking and tests/setup/desktop-hijacking-contract. Update the exact contract count in README.md; removing one executable and adding one executable keeps the current count at 185 at this point.

Run:

tests/setup/readme-contract
git diff --check

Expected: both PASS.

Step 4: Commit

git add tests/contracts.manifest tests/setup/contract-manifest-contract \
    tests/setup/desktop-hijacking-contract tests/desktop-hijacking README.md
git commit -m "Test: Classify every contract capability"

Task 2: Make panama test enforce the manifest and preserve diagnostics

Files:

  • Create: tests/setup/test-runner-contract
  • Modify: bin/panama
  • Modify: tests/contracts.manifest
  • Modify: README.md

Step 1: Write a public runner contract

Create tests/setup/test-runner-contract. Build a temporary repository containing a copy of bin/panama, a minimal tests/contracts.manifest, and executable fixture contracts named pass-contract, fail-contract, stderr-contract, hang-contract, host-contract, desktop-contract, and network-contract. Initialize it as a Git repository so the copied CLI behaves like the real installation.

The fixtures must record executions beneath the temporary directory and produce these behaviors:

# pass-contract
printf 'pass stdout\n'

# fail-contract
printf 'failure stdout\n'
printf 'failure stderr\n' >&2
exit 7

# stderr-contract
printf 'warning on success\n' >&2

# hang-contract
trap 'printf terminated >"$PANAMA_TEST_FIXTURE/terminated"; exit 124' TERM
while :; do sleep 1; done

Assert the copied panama executable provides these public behaviors:

  1. panama test --safe runs only hermetic fixtures and reports each skipped capability count, including live-host.
  2. panama test desktop in a non-TTY fails without running the fixture and tells automation to pass --allow live-desktop.
  3. panama test --allow live-desktop desktop runs it without a prompt.
  4. Multiple --allow flags are repeatable and capability-specific; allowing desktop does not allow network.
  5. An unknown flag, a second pattern, an unknown capability, and --safe --allow live-desktop are usage errors.
  6. PANAMA_TEST_TIMEOUT_SECONDS=1 panama test hang terminates the fixture, reports a timeout, and exits nonzero.
  7. A failed contract prints both captured stdout and captured stderr.
  8. A successful contract with stderr prints a warning and the captured stderr.
  9. Successful stdout stays hidden to keep the normal run scannable.
  10. A pattern matching only skipped contracts is a distinct error from no pattern match.
  11. Capture files are removed after success and failure.
  12. panama contracts <file> labels hits with all manifest capabilities.

Run:

chmod +x tests/setup/test-runner-contract
tests/setup/test-runner-contract

Expected: FAIL against the current runner at the first manifest-policy assertion.

Step 2: Replace ledger parsing with manifest parsing

In bin/panama, replace DESKTOP_HIJACKING_LEDGER and hijacking_entries with:

CONTRACT_MANIFEST="tests/contracts.manifest"
CONTRACT_CAPABILITIES=(hermetic live-host live-compositor live-desktop network privileged)

contract_manifest_entries() {
  local line capabilities path
  while IFS= read -r line || [[ -n "$line" ]]; do
    line="${line%%#*}"
    read -r capabilities path _ <<<"$line"
    [[ -n "${capabilities:-}" && -n "${path:-}" ]] || continue
    printf '%s\t%s\n' "$path" "$capabilities"
  done < "$PANAMA_DIR/$CONTRACT_MANIFEST"
}

Do not make a missing or malformed manifest mean “everything is safe.” Before either cmd_test or cmd_contracts consumes manifest entries, the public CLI independently validates the complete actual manifest: exactly two fields, known/non-empty/non-duplicate capabilities, exclusive hermetic, unique sorted paths, the executable/*_test.py fixture-excluded discovery set, and a non-empty directly preceding comment for every non-hermetic entry. Missing discovered contracts and stale manifest paths are fatal before selection or execution. Keep tests/setup/contract-manifest-contract as an independent validator rather than sourcing runtime code; a later contract cannot protect earlier execution.

Step 3: Implement argument and capability policy

Parse position-independent arguments with one optional pattern and repeatable --allow <capability>. Apply these rules:

  • --safe means only hermetic entries;
  • --safe and any --allow together are a usage error;
  • --allow hermetic is a usage error because hermetic contracts need no grant;
  • plain panama test selects all matching manifest entries;
  • selected non-hermetic capabilities missing from --allow require confirmation only when stdin and stderr are TTYs;
  • non-TTY execution fails before running anything and names every missing capability;
  • the prompt lists selected contract count and each external capability; default is no;
  • there is no --allow-all path.

Use associative arrays for selected grants, manifest capabilities, and skipped counts so ordering stays deterministic.

Step 4: Bound execution and retain output

At the beginning of cmd_test, validate:

local timeout_seconds="${PANAMA_TEST_TIMEOUT_SECONDS:-180}"
[[ "$timeout_seconds" =~ ^[1-9][0-9]*$ ]] || {
  err 'PANAMA_TEST_TIMEOUT_SECONDS must be a positive integer.'
  return 2
}

The public CLI process must own contract supervision. Check that mktemp -d succeeds before constructing any capture path, then install top-level EXIT, INT, and TERM cleanup around the checked directory. Launch the active timeout asynchronously and retain its PID/process-group ownership. On INT or TERM sent to the exact CLI PID, signal the active timeout/process group, wait for it, remove capture storage, and exit 130 or 143. On normal completion, remove capture storage and clear the temporary traps without changing the aggregate test status. For each contract, run either python3 path or the executable through:

timeout --signal=TERM --kill-after=5 "$timeout_seconds" \
  "${runner[@]}" >"$stdout_file" 2>"$stderr_file"

Capture the exit status explicitly instead of relying on set -e. Treat status 124 or 137 as timeout. On failure, print a labeled stdout section when nonempty and a labeled stderr section when nonempty. On success, suppress stdout; if stderr is nonempty, call warn and print it. Continue through the selected suite and return nonzero if any contract failed or timed out.

Step 5: Update panama contracts

Load the same manifest mapping and render labels such as:

tests/quickshell/settings-pages-contract  [live-compositor,live-desktop]
tests/setup/readme-contract               [hermetic]

The grep-based relationship search remains unchanged. Its capability label must come only from the manifest.

Step 6: Make the tests pass and update the count

Add hermetic tests/setup/test-runner-contract to tests/contracts.manifest. Update the README count from 185 to 186.

Run:

tests/setup/contract-manifest-contract
tests/setup/test-runner-contract
tests/setup/readme-contract
./bin/panama test --safe test-runner

Expected: all PASS. The final command reports one passing contract and does not request permission.

Step 7: Commit

git add bin/panama tests/contracts.manifest tests/setup/test-runner-contract README.md
git commit -m "Fix: Make contract execution safe and diagnostic"

Task 3: Remove the calendar-pinned agent usage failure

Files:

  • Modify: tests/quickshell/agent-usage-contract

Step 1: Prove the current fixture is date-dependent

Run:

tests/quickshell/agent-usage-contract

Expected before the change: FAIL on todayTotalTokens when the current day is not 2026-08-25.

Step 2: Generate the session path and timestamps dynamically

Replace the fixed 2026/08/25 directory and timestamps with local-day fixture values, matching the collector's datetime.now() and astimezone() behavior:

session_day="$(date +%Y/%m/%d)"
session_date="$(date +%Y-%m-%d)"
session_offset="$(date +%:z)"
mkdir -p "$work/codex/sessions/$session_day"

jq -nc --arg timestamp "${session_date}T10:00:00${session_offset}" \
  '{type:"token_count",timestamp:$timestamp,payload:{type:"token_count",info:{total_token_usage:{input_tokens:999999,output_tokens:999999},last_token_usage:{input_tokens:1200,cached_input_tokens:1000,output_tokens:300}}}}'

Write two records at local 10:00:00 and 10:05:00 with session_offset, preserving the existing expectation of 3,000 last-turn tokens. Do not add a production clock override: only the fixture was wrong.

Step 3: Verify and commit

Run:

tests/quickshell/agent-usage-contract
./bin/panama test --safe agent-usage

Expected: both PASS with todayTotalTokens == 3000.

git add tests/quickshell/agent-usage-contract
git commit -m "Test: Make agent usage fixtures date independent"

Task 4: Replace regex secret scanning with semantic fixtures

Files:

  • Create: tests/server/scan-tracked-secrets.py
  • Create: tests/server/fixtures/secrets/clean/compose.yml
  • Create: tests/server/fixtures/secrets/clean/.env.example
  • Create: tests/server/fixtures/secrets/clean/README.md
  • Create: tests/server/fixtures/secrets/leaked/compose.yml
  • Create: tests/server/fixtures/secrets/leaked/.env.example
  • Modify: tests/server/compose-secrets-contract

Step 1: Add false-positive and true-positive fixtures

The clean fixture must include:

  • Compose interpolation such as POSTGRES_PASSWORD: ${POSTGRES_PASSWORD};
  • CHANGE_ME, empty values, and boolean switches in .env.example;
  • prose containing password: example, secret key, and the current server README sentence that triggered the audit.

The leaked fixture must include:

  • a literal YAML credential POSTGRES_PASSWORD: fixture-should-be-rejected;
  • a literal env credential API_TOKEN=fixture-should-be-rejected.
  • a plain-text PEM private-key header with an exact path:line: private key finding;
  • plain-text synthetic sk-ant-, minimum-supported-length ghp_, and xoxb- signatures, each with an exact path:line: provider token finding.

Add clean plain-text near-misses for each signature. Keep semantic fixture credentials intentionally invalid and signature fixtures clearly synthetic while still matching the supported signature shapes.

Step 2: Write the scanner with only the Python standard library

tests/server/scan-tracked-secrets.py takes a root directory followed by tracked paths on argv. It must:

  • parse .env and .env.example lines as key/value records;
  • parse YAML Compose files by indentation-aware KEY: VALUE / - KEY=VALUE environment entries and top-level secret-bearing scalar assignments;
  • treat ${VAR}, ${VAR:-default}, empty strings, CHANGE_ME, and booleans as non-secret;
  • ignore keys ending _FILE, _PATH, _NAME, or _KEY_NAME;
  • scan all text file types only for PEM private-key headers and known provider-token signatures;
  • never interpret Markdown credential-shaped prose as a YAML assignment;
  • print path:line: key for semantic leaks and return 1 when any are found.

Keep the parser deliberately scoped to Compose and env syntax; do not add a general YAML dependency that the installer does not provide.

Step 3: Make the contract prove both directions

Before scanning the real tracked server/ paths, have tests/server/compose-secrets-contract call the scanner on the clean fixture and require success, then on each leaked fixture and require failure with the expected key named. Finally pass the actual paths from:

git -C "$repo_dir" ls-files 'server/**' 'server/*'

Keep the existing .gitignore and tracked-.env assertions.

Run:

tests/server/compose-secrets-contract

Expected: PASS; the README prose is accepted while both literal fixture secrets are rejected.

Step 4: Commit

git add tests/server/scan-tracked-secrets.py tests/server/fixtures/secrets \
    tests/server/compose-secrets-contract
git commit -m "Test: Scan compose secrets by data shape"

Task 5: Make the update contract execute the real CLI

Files:

  • Modify: tests/setup/update-command-contract

Step 1: Replace the source-body assertions with a failing CLI fixture

Keep the existing install --upgrade stage and package-hash assertions, but replace the sed/grep inspection of cmd_update and cmd_sync with disposable Git repositories:

  1. create a bare origin.git;
  2. create an upstream clone with a copied bin/panama and a stub executable install;
  3. push the initial branch;
  4. clone it to machine;
  5. append an upstream commit;
  6. run machine/bin/panama update with PANAMA_UPDATE_FIXTURE_LOG consumed by the copied stub installer.

The installer stub must record its argv and optionally fail according to PANAMA_UPDATE_INSTALL_RC.

Add assertions that the real CLI:

  • fast-forwards a clean machine clone to the new upstream commit;
  • invokes the fixture installer with --upgrade;
  • returns the installer's nonzero status;
  • leaves panama sync separate from the installer path;
  • on a dirty-tree stash-pop conflict, leaves no conflict markers and preserves a recoverable stash.

Do not yet assert that installation happens after WIP restoration. Package 3 of the approved design changes that ordering and will extend this same executable fixture with the new failing assertion before changing production code.

Step 2: Repair status propagation in the contract harness

Change run_install so it returns the installer's status rather than cat's status:

local status=0
PATH="$root/shim:$PATH" PANAMA_PATH="$root" PANAMA_RAN="$root/ran" \
  XDG_STATE_HOME="$root/state" bash "$root/install" "$@" \
  >"$root/out" 2>&1 || status=$?
cat "$root/ran"
return "$status"

Replace the indented-assignment parser with a tolerant anchored expression:

match = re.match(r'^\s*STAGES=\((.*)\)\s*$', line)

Fail explicitly when the assignment is not found. Do not run parser code in process substitution whose exit status is ignored.

Step 3: Verify and commit

Run:

tests/setup/update-command-contract
./bin/panama test --safe update-command

Expected: both PASS and the fixture log proves bin/panama update actually ran.

git add tests/setup/update-command-contract
git commit -m "Test: Exercise updates through the real command"

Task 6: Stop contracts from mutating tracked files or reading live preferences

Files:

  • Modify: config/dot/quickshell/scripts/panama-settings-docs
  • Modify: tests/quickshell/settings-docs-contract
  • Modify: tests/quickshell/settings-sync-contract

Step 1: Add a failing output-path contract for generated settings docs

Extend tests/quickshell/settings-docs-contract to copy the committed document to a temporary path, append drift to the copy, and run:

"$generator" --check --output "$scratch/settings.md"

Capture git diff -- docs/settings.md before and after the contract and require byte-for-byte equality. Run the contract now.

Expected: FAIL because the generator does not accept --output and the current test still edits the tracked document.

Step 2: Add a real output seam to the generator

Add:

parser.add_argument("--output", type=pathlib.Path, default=OUTPUT)

Resolve relative explicit paths against the current working directory, use that path for write/check behavior, and keep the existing default unchanged. --stdout must remain mutually exclusive with writing but may coexist with no explicit output.

Update the contract so the stale-copy check never writes docs/settings.md. Its trap should only remove the temporary directory.

Run:

tests/quickshell/settings-docs-contract
git diff --exit-code -- docs/settings.md

Expected: PASS and no diff.

Step 3: Seed settings-sync from a fixture instead of the live settings store

In tests/quickshell/settings-sync-contract, set XDG_CONFIG_HOME="$work/source-config" before the first export and create a representative panama/settings.json there from schema-valid values. Include at least:

  • one boolean;
  • one integer;
  • one numeric enum;
  • one string;
  • one setting omitted from the import bundle to prove merge semantics.

Remove every read of ${XDG_CONFIG_HOME:-$HOME/.config}/panama/settings.json that occurs before the temporary home is established. Keep the allow-list completeness assertion, but compare against the explicit fixture rather than the user's preferences.

Run:

tests/quickshell/settings-sync-contract

Expected: PASS without reading or writing the real settings store.

Step 4: Commit

git add config/dot/quickshell/scripts/panama-settings-docs \
    tests/quickshell/settings-docs-contract tests/quickshell/settings-sync-contract
git commit -m "Test: Isolate generated docs and settings fixtures"

Task 7: Isolate the dock geometry contract

Files:

  • Modify: tests/quickshell/dock-position-contract

Step 1: Write the safety assertions before changing the harness

At contract start, record whether config/dot/quickshell/dock-position-probe.qml exists and its checksum if present. At every exit, assert the source tree matches that initial state. Also fail if the contract reads ${HOME}/.config/panama/settings.json.

Run:

tests/quickshell/dock-position-contract

Expected: FAIL because the contract creates its probe inside the tracked QML tree and reads live settings.

Step 2: Copy the QML tree and seed deterministic settings

After creating work, copy the Quickshell tree to a fixture root:

fixture_shell="$work/quickshell"
cp -a "$shell_dir/." "$fixture_shell/"
probe="$fixture_shell/dock-position-probe.qml"

Write the probe only to $probe. Seed $work/config/panama/settings.json with the schema defaults needed by the dock plus the position under test; do not copy the user's settings. Run each qs -p invocation from $fixture_shell with XDG_CONFIG_HOME="$work/config".

The contract still maps isolated panel surfaces into the current Wayland session. Keep its manifest capability as live-desktop: moving its files and settings into temporary storage removes mutation risk but does not make the visible surfaces hermetic.

Step 3: Verify isolation under an explicit desktop grant

Run:

tests/quickshell/dock-position-contract
tests/setup/contract-manifest-contract
./bin/panama test --allow live-desktop dock-position

Expected: all PASS, the source-tree checksum is unchanged, and the manifest entry remains live-desktop.

Step 4: Commit

git add tests/quickshell/dock-position-contract
git commit -m "Test: Isolate dock geometry fixtures"

Task 8: Update operator documentation and run the Package 1 gate

Files:

  • Modify: README.md
  • Modify: .claude/skills/panama/SKILL.md
  • Modify: skills/panama-desktop/SKILL.md
  • Modify: bin/panama

Step 1: Update the public command documentation

Document:

panama test --safe
panama test --allow live-host updates
panama test --allow live-compositor keybinds
PANAMA_TEST_TIMEOUT_SECONDS=300 panama test --safe

State that:

  • tests/contracts.manifest classifies every contract;
  • --safe means hermetic only;
  • plain full runs prompt in a terminal before any non-hermetic contract;
  • automation must grant each required capability with repeatable --allow;
  • failures print captured stdout/stderr and every contract has a default 180-second outer timeout.

Remove current claims that --safe is defined by tests/desktop-hijacking. Update bin/panama's top comment, usage text, cmd_test comments, and cmd_contracts comments to match behavior. Leave historical design specs unchanged.

Step 2: Run focused verification

bash -n bin/panama \
  tests/setup/contract-manifest-contract \
  tests/setup/test-runner-contract \
  tests/setup/update-command-contract \
  tests/quickshell/agent-usage-contract \
  tests/quickshell/settings-docs-contract \
  tests/quickshell/settings-sync-contract \
  tests/server/compose-secrets-contract
python3 -m py_compile \
  config/dot/quickshell/scripts/panama-settings-docs \
  tests/server/scan-tracked-secrets.py
tests/setup/contract-manifest-contract
tests/setup/test-runner-contract
tests/setup/update-command-contract
tests/quickshell/agent-usage-contract
tests/quickshell/settings-docs-contract
tests/quickshell/settings-sync-contract
tests/server/compose-secrets-contract
tests/setup/readme-contract
git diff --check

Expected: every command exits 0.

Step 3: Run the complete hermetic gate

./bin/panama test --safe

Expected: all selected hermetic contracts pass; the summary reports skipped counts for live-host, live-compositor, live-desktop, and network; no confirmation appears; no production shell or service is restarted.

If a manifest-labeled hermetic contract reaches the network, live compositor, live settings, root prompt, or tracked-file write, stop and reclassify or isolate it before continuing. Do not grant a capability merely to make this gate green.

Step 4: Confirm worktree scope

git status --short
git diff -- config/bash/.bashrc

Expected: the pre-existing .bashrc modification remains unstaged and unchanged from its pre-plan state; only Package 1 files are staged or committed.

Step 5: Commit

git add README.md .claude/skills/panama/SKILL.md skills/panama-desktop/SKILL.md bin/panama
git commit -m "Docs: Explain contract capability gates"

Step 6: Record the package handoff

Capture these facts in the implementation summary before beginning Package 2:

  • final hermetic pass/fail/skip counts;
  • every non-hermetic capability (live-host, live-compositor, live-desktop, network, and privileged) and its contract count;
  • focused verification commands and exit codes;
  • confirmation that config/bash/.bashrc stayed out of all commits;
  • any contract retained as non-hermetic after an attempted isolation, with the exact reason.