CLAUDE.md · git:20261103.bce1f3a · 2026-11-03 · sha256 e2807f1e39d8eb6e

CLAUDE.md git:20261103.bce1f3aA

Immutable. This exact content never changes and is served at /api/v1/blob/e2807f1e39d8eb6e.

# CLAUDE.md

## STRICT: Verification commands (memory-safe)

Wide test runs exhaust the developer machine's RAM. These rules are mandatory for the main
agent, every subagent and every CLI lane. Repeat them in any task prompt you hand to a lane.

- Verify with `npm run verify`. It runs `nx affected -t lint test typecheck --base=main`.
  - Only some projects or targets: `npm run verify -- -p A,B` / `npm run verify -- -t test -p A`.
  - Extra Nx or Jest flags go after a second `--`: `npm run verify -- -p A -- --testPathPatterns=foo`.
- `npm run verify` takes a slot of a machine-wide FIFO counting lock first, so at most 3 heavy
  checks run at a time across all sessions, lanes and worktrees. Another check starts only while
  at least 5 GB of memory is free and the newest check has run for 30 s. A check on an empty lock
  always starts. While it waits it prints why (`waiting for a slot` / `waiting for memory`). Do
  not message other sessions about a "slot". `node scripts/verify.mjs --status` shows the slot
  holders, the queue and the free memory. A slot whose process is dead or older than 120 minutes
  is taken over automatically.
  - Tune per shell: `PTAH_VERIFY_SLOTS` (default 3; 1 restores one check at a time),
    `PTAH_VERIFY_MIN_FREE_GB` (default 5), `PTAH_VERIFY_SETTLE_SEC` (default 30).
- The caps are in config: `nx.json` runs one task at a time and `jest.preset.js` gives Jest 2
  workers per check. Do not raise them: Nx tasks, Jest workers and lock slots multiply. Run any
  other heavy command under the same lock:
  `node scripts/verify.mjs --exec --task <name> -- <command> [args...]`.
- Test, lint and typecheck results are cached in one Nx cache that the main checkout and every
  worktree share (`~/.nx/<workspace-id>/`). A check that main already passed is a cache hit.
  Do not set `cacheDirectory` or `NX_CACHE_DIRECTORY`: that turns the sharing off.
- Never run workspace-wide checks, and never `nx run-many` across projects you did not change.
- Never run `build`, `serve`, `dev`, `e2e` or `package` targets unless the user asks for it.
- Prefer one foreground run with a long timeout. Filter its output (`| tail`, `grep`) instead of
  re-running the command to read it.

## Product focus: Electron first

The Electron desktop app (`apps/ptah-electron`) is the priority host. These rules apply to the
main agent, every subagent and every CLI lane. Repeat them in any task prompt you hand to a lane.

- Plan, build and verify features for Electron first.
- Keep the Electron renderer in `apps/ptah-extension-webview`; its name does not make it a VS Code host.
- Run visual reviews and screenshots in Electron only.
- When a change touches a shared lib, run scoped checks for the affected Electron and renderer projects.
- Keep provider CLI lanes and the benchmark's `platform-cli` and `cli-engine` libraries working.

## Git: start every task in its own worktree

- Prefer `ptah_git_worktree_add` when listed; it links the worktree to the chat session. Otherwise use `git worktree add`.
- Before you change any file for a new task, create a worktree on a new branch from `main`:
  `git worktree add -b <type>/<short-name> .claude-worktrees/<short-name> main`.
  `.claude-worktrees/` is git-ignored. Keep `<type>` to the commit type (`fix`, `feat`, ...).
- Make every edit, check and commit of the task inside that worktree. The main checkout stays
  on `main` with no task changes in it. Give the worktree path to each subagent and as the
  `workingDirectory` of each CLI lane for that task.
- Pure questions, read-only investigation and status commands need no worktree.
- Changes that are already in the main checkout move to a worktree before more work starts:
  create the worktree, copy the changed files, confirm they are identical (`cmp`), and only
  then revert them in the main checkout.
- The worktree and its branch stay until the user says to remove them. After the PR merges
  and the user authorizes cleanup, use `git worktree remove .claude-worktrees/<short-name>`.

## Git: complete the task through PR checks and review

- The default task workflow is worktree → implement → verify → review → commit → push →
  open a pull request → watch CI jobs and code reviews → address actionable findings.
  Do not finish a completed task with uncommitted changes or an unpublished branch.
- This is standing authorization to commit verified task changes, push the task branch,
  and open or update its pull request without a separate request for each step. It replaces
  older project preferences that require explicit follow-up approval for commits, pushes,
  or pull requests. Apply this authorization when a skill says the user handles Git or
  requires a separate commit/push request. Keep worker-lane ownership restrictions intact.
  A current user instruction to stop, keep work local, or defer delivery takes precedence.
  If a tool denies an action, stop that action and report the blocker.
- Only the coordinating agent commits, pushes, and manages the pull request. Delegate these
  actions explicitly if needed. Implementation lanes report their changes to that agent
  and must not push or open competing pull requests on their own.
- Inspect the worktree status and the complete task diff before each commit. Stage only
  task files by explicit path. Preserve unrelated changes. Follow `.commitlintrc.json` and
  the repository commit conventions. Do not bypass hooks or signing.
- Complete scoped verification and an independent review before the initial push. If a
  check cannot run or a failure blocks delivery, report the exact blocker. Do not claim
  success, suppress failures, or publish unfinished work as ready for review.
- Open the pull request against `main`. Inspect every task commit, not only the latest.
  Keep the title under 70 characters. Include `## Summary` and `## Test plan`, with actual
  verification results and any checks that did not run. Reuse an existing task PR.
- After each push, watch the PR's CI jobs and code reviews with `gh`. Use a background
  watcher for long waits. Inspect failed job logs, review comments, and unresolved threads.
  Address confirmed task-related defects, verify the fixes, create new commits, and push
  again. Explain why any disputed finding needs no change. Repeat for the new PR head.
- Do not treat a successful push as task completion. Report the PR URL, current head,
  CI results, and review state. If CI or reviews remain pending, explicitly report that
  state and keep the watch active while the session permits. Report failed, cancelled,
  timed-out, or unavailable checks and any blocker that needs the user's decision.
- This authorization does not permit merges, force pushes, history rewrites, branch
  deletion, or worktree removal. Keep the branch and worktree until the user authorizes
  cleanup. Never bypass a permission denial through another tool or agent.

## Git: commit in the foreground, push in the background

- Run `git commit` in the foreground. Never run it in the background: lint-staged hides
  unstaged changes during the hook and restores them afterwards, so a file edited while the
  hook runs can be committed or lost (see the TASK_2026_224 comment in `.husky/pre-commit`).
  The pre-commit hook is lint-staged only, so it is fast.
- Run `git push` (chained with `gh pr create` when a PR is due) as one background command
  (the Bash tool's `run_in_background`) and continue with other work; act on the result when
  it completes. The pre-push hook runs di-lint and the Electron `validate-deps` build gate on
  every push. A failed gate needs a fix commit on top, then push again. The hook takes the
  same verify lock as `npm run verify`, so a push can wait in the queue behind another check.

## Repo-local fleet rules

- The commitlint scope enum and other enforced commit rules live in `.commitlintrc.json`.
  Read that config before committing. Keep the subject at most 72 characters and every body
  line at most 100 characters; wrap body text at 72. `security` and `git` are not scopes.
- A multi-scope subject with commas is allowed, e.g. `fix(agent-sdk,chat): ...`.
- To test only the changed projects, run `npm run verify -- -t test -p A,B` and confirm that
  the output header says "Running target test for N projects" with N equal to the number
  requested. Never use positional `nx test A B` because those names become Jest path filters.