# Agent-Queue Run Policy

How the agent-queue daemon and the agents it launches must operate. Written
after a live review found jobs running in `--yolo` (dangerous) mode directly
against **live working trees**, which dirtied repos, produced duplicate/competing
commits, and risked leaking secrets.

## Observed behavior (the problem)

`agent-queue.sh` launches the chosen CLI with `cwd` taken from the job
front-matter (default `$PWD`) and, when `yolo: true` (the default), with
full-autonomy flags:

| Engine | yolo flag |
| --- | --- |
| devin  | `--permission-mode dangerous` |
| claude | `--dangerously-skip-permissions` |
| codex  | `--dangerously-bypass-approvals-and-sandbox` |
| (other) | `--allow-all-tools` |

With `cwd` pointing at a canonical checkout (e.g. `…/learning_ai_fastgap`), a
dangerous-mode agent edits, commits, and pushes in the repo you also work in.

## Policy

1. **Isolation — never run in the canonical checkout.**
   Each job MUST run in a dedicated **git worktree** (or fresh clone) created off
   `origin/main`, not the live working directory. Set the job's `cwd` to that
   worktree. The canonical checkout must be left untouched.

2. **One job = one branch.**
   Create/checkout a dedicated branch (e.g. `aq/<job-id>`) off the latest
   `origin/main`. Agents push that branch and open a PR. **Never push straight to
   the shared `main`** of platform/shared repos.

3. **Least privilege by default.**
   Default `yolo: false`. Reserve the dangerous/`--allow-all-tools` flags for
   **disposable sandboxes only** (throwaway worktree/clone or container). Never
   run dangerous mode against a directory whose changes you care about.

4. **Clean-tree contract.**
   A job starts only from a clean tree and verifies the canonical checkout is
   unchanged when it finishes. If a worktree is dirty at pickup, fail fast.

5. **Test before ship.**
   Run typecheck + lint + the repo's test suite before committing. Commit small,
   conventional messages. Open a PR for review instead of force-merging.

6. **Never track runtime/queue state.**
   The `queue/{.state,inbox,building,testing,review,failed,shipped,logs}` lifecycle
   dirs are runtime state and are git-ignored (see repo `.gitignore`). Jobs must
   not commit them.

7. **One writer per repo.**
   At most one job per target repo at a time (use the existing per-repo lock) so
   two agents never compete on the same working tree.

8. **Secrets stay out of git.**
   Jobs must not write real secrets into tracked files. Use `.env` (gitignored);
   the pre-push secret scan is a backstop, not a license.

## Applying this with the current runner

- Add a **worktree-prep step** before launch: `git -C <repo> worktree add
  <tmp>/<job-id> -b aq/<job-id> origin/main`, then set the job `cwd: <tmp>/<job-id>`.
- Set `yolo: false` in job front-matter unless the `cwd` is a disposable
  sandbox.
- On completion, push `aq/<job-id>` and open a PR; remove the worktree
  (`git worktree remove`) once merged.

## Pre-flight checklist (per job)

- [ ] `cwd` is a dedicated worktree/clone, not a canonical checkout
- [ ] dedicated branch off latest `origin/main`
- [ ] `yolo: false` unless sandboxed/disposable
- [ ] starts from a clean tree
- [ ] tests/lint/typecheck run before commit
- [ ] pushes a branch + PR (no direct shared-`main` pushes)
- [ ] no runtime/queue state or secrets committed
