# Local Claude/Codex Issue Flows

This workflow set wraps local GitHub and git operations in Anteroom workflows so you can run Claude and Codex against real issues and PRs with deterministic control points.

Use this when your flow is:

- Claude handles planning, implementation, and PR fixes
- Codex handles senior review
- GitHub issue comments and PR discussion are the source of truth
- GitHub, git, checks, and PR bookkeeping still happen through local CLI tools

## Workflow Set

The lifecycle-specific workflows live at:

- `examples/workflows/local_work_item_router.yaml`
- `examples/workflows/local_claude_codex_issue_delivery.yaml`
- `examples/workflows/local_claude_codex_pr_repair.yaml`
- `examples/workflows/local_claude_pr_refresh.yaml`
- `examples/workflows/local_codex_pr_review_only.yaml`

They use the helper script at:

- `scripts/workflows/local_cli_issue_flow.py`

Use each workflow by lifecycle state:

- `local_work_item_router`
  Lifecycle router workflow. Use this as the default entry point when you want
  the workflow stack to inspect live issue/PR state and choose the right
  narrower workflow automatically.
- `local_claude_codex_issue_delivery`
  Use this for a fresh issue with no PR yet. It owns planning, implementation, initial checks, PR creation, and the first PR review/fix loop.
- `local_claude_codex_pr_repair`
  Use this when the PR already exists and the real work is review follow-up or failing-check repair.
- `local_claude_pr_refresh`
  Use this when the PR branch is behind `main`, conflicting, or otherwise needs mergeability repair before review can continue.
- `local_codex_pr_review_only`
  Use this when the branch is already in the right state and you only want senior review.

The helper handles worktree management, GitHub bookkeeping, and all Claude/Codex invocations through local CLI binaries:

- `prepare` -- create or recover the issue worktree
- `plan` -- draft or refresh the implementation plan (Claude)
- `review-plan` -- senior review on the plan (Codex)
- `implement` -- implement the approved issue (Claude)
- `capture-baseline` -- snapshot current-main failures for baseline-aware checks
- `fix-pr` -- address PR review feedback (Claude)
- `fix-checks` -- fix failing checks after lint/test runs (Claude)
- `refresh-pr` -- refresh the PR branch against the base (Claude)
- `review-pr` -- senior review on the PR (Codex)
- `checks` -- run repository checks (shell)
- `autofix` -- run cheap autofixes before retrying checks (shell)
- `sync` -- commit and push branch changes (git)
- `open-pr` -- create or recover the PR (gh)
- `inspect-pr` -- print structured PR lifecycle state as JSON (gh)
- `ready-pr` -- mark the PR ready for review (gh)
- `assert-pr-fresh` -- fail unless the PR does not need refresh (gh)
- `assert-pr-mergeable` -- fail unless the PR is mergeable (gh)
- `assert-pr-approved` -- fail unless the PR is senior-approved (gh)

All Claude and Codex work runs through the helper script via local CLI binaries (`claude`, `codex`), not through Anteroom's internal API-backed agent runners. This keeps local workflows fully independent of the Anteroom AI service layer.

## Prerequisites

The workflow requires these tools:

| Tool | Purpose | Verify |
|------|---------|--------|
| `gh` | GitHub issue/PR management | `gh auth status` |
| `git` | Branch, worktree, and commit operations | `git --version` |
| `claude` | Claude CLI for planning, implementation, and fixes | `claude --version` |
| `codex` | Codex CLI for senior review | `codex --version` |

All Claude and Codex work runs through local CLI binaries invoked by the helper script. No Anteroom AI configuration is needed for these workflows.

Git also needs a configured author identity for automated commits:

```bash
git config user.name
git config user.email
```

## Choose the Entry Point

Start with the router when you are not completely sure which lifecycle state you are in:

```bash
aroom workflow run ./examples/workflows/local_work_item_router.yaml --issue 123
```

The router inspects live PR state through `inspect-pr` and dispatches deterministically:

- `no_pr` -> `local_claude_codex_issue_delivery`
- `review_repair` -> `local_claude_codex_pr_repair`
- `refresh_needed` -> `local_claude_pr_refresh`
- `review_only` -> `local_codex_pr_review_only`

Use a narrower workflow directly when you already know the lifecycle state or you want to bypass routing while debugging.

## Direct Workflow Commands

Use the fresh-issue workflow directly:

```bash
aroom workflow run ./examples/workflows/local_claude_codex_issue_delivery.yaml --issue 123
```

Use PR repair directly:

```bash
aroom workflow run ./examples/workflows/local_claude_codex_pr_repair.yaml --issue 123
```

Use PR refresh directly:

```bash
aroom workflow run ./examples/workflows/local_claude_pr_refresh.yaml --issue 123
```

Use review-only directly:

```bash
aroom workflow run ./examples/workflows/local_codex_pr_review_only.yaml --issue 123
```

Inspect the resolved steps first:

```bash
aroom workflow run ./examples/workflows/local_claude_codex_issue_delivery.yaml --issue 123 --dry-run
```

If a review loop stops before approval, inspect the run and resume it after adjustments:

```bash
aroom workflow status <run_id>
aroom workflow history <run_id>
aroom workflow resume <run_id> --definition ./examples/workflows/local_claude_codex_issue_delivery.yaml
```

## Operational Guidance

Use the router by default.

Use a direct workflow when:

- you already know the branch has no PR and you want the full issue-delivery path
- you already know the PR just needs repair
- you already know the PR needs refresh against `main`
- you only want a senior-review pass

Avoid rerunning full issue delivery on an existing PR by default. `issue_delivery` is intentionally the only workflow that re-enters issue planning. Existing PR repair, refresh, and review-only runs should use the narrower workflows instead of reopening the full issue path.

## Checks

By default the helper uses:

```bash
ruff check src/ tests/ && python -m pytest tests/unit/ -x -q --tb=short
```

You can change that by editing the `ANTEROOM_LOCAL_CHECKS` environment values in the workflow YAML.

For fresh issue delivery, the workflow can now capture a current-`main` baseline before the initial checks loop and let `checks --allow-baseline` succeed when the branch introduces no new failures beyond that baseline. This mode is strict by default:

- baseline capture runs in an isolated temporary worktree
- baseline-aware execution removes pytest fail-fast masking so hidden later failures still surface
- stale or incompatible baseline metadata invalidates the comparison and fails closed

If the prepared issue branch already contains committed implementation work, issue delivery now takes a smaller existing-work fast path:

- `assess-existing-work` detects when the issue branch is already ahead of `origin/main` with committed file changes
- the workflow writes a compact branch-state plan instead of reopening a full from-scratch plan draft
- Codex reviews the current branch state and remaining validation path, not speculative fresh implementation steps
- if approved, the workflow skips `implement_issue` and continues directly into baseline capture and checks

## Notes

- The helper stores per-issue workflow state under the repository's shared git-common-dir (`git rev-parse --git-common-dir`) in an `anteroom-workflows/` directory. This ensures all linked worktrees share the same workflow state, so router-launched child workflows can find state created by the parent checkout.
- `prepare` also records the issue worktree's `.venv` interpreter metadata when present so router-launched child workflows can run `python_script` checks with the prepared worktree Python environment instead of the parent mission checkout.
- The issue body gets an `Implementation Plan` section managed between `<!-- anteroom:plan:start -->` and `<!-- anteroom:plan:end -->`.
- Plan and PR gating both use the `senior-approved` label.
- The fresh-issue `plan_loop` is intentionally capped at 3 rounds. If plan review
  is still churning after that, stop rerunning the full issue-delivery flow and
  either approve the plan manually or switch to a narrower/direct repair path.
- `issue_delivery` is intentionally the only workflow that re-enters issue
  planning. Existing PR repair, refresh, and review-only runs should use the
  narrower workflows instead of rerunning the full issue path.
- `local_work_item_router` is the preferred general entry point for common
  local Claude/Codex delivery runs. It does deterministic state-driven routing
  and then hands off to the narrower workflow that owns that lifecycle state.
- Codex senior-review attempts default to a 300-second timeout. Override with
  `ANTEROOM_LOCAL_PLAN_REVIEW_TIMEOUT_SECONDS` (integer, seconds). If a review
  times out, exits nonzero, or returns unusable JSON, the helper marks the
  attempt as `review_failed`, keeps `needs-senior-review`, removes
  `senior-approved`, and returns a bounded step failure for diagnosis.
- The workflow step timeout for `review-plan` is set above the helper default so
  the helper can enforce its own timeout and report structured review failures
  instead of being cut off early by the workflow engine.
- If the same GitHub user both authors the PR and runs the review, GitHub may
  not count that as an independent approval. The workflow still uses the label
  gate consistently.

## PR State Helper Contract

The helper exposes workflow-facing PR lifecycle commands:

- `inspect-pr --issue <N>` prints JSON with:
  - `issue_number`, `pr_number`, `exists`, `url`, `state`, `is_draft`, `review_decision`, `labels`
  - `mergeable` normalized to `mergeable`, `conflicting`, or `unknown`
  - `check_summary` with `overall`, per-bucket `counts`, `has_required_pending`, and `has_required_failures`
  - `branch_status` with `head_ref`, `base_ref`, `base_sha`, `head_sha`, `behind_base`, `ahead_of_base`, `diverged`, and `needs_refresh`
  - `lifecycle` as one of `no_pr`, `refresh_needed`, `review_repair`, or `review_only`
  - `ready_for_senior_review` when the PR is non-draft, fresh, mergeable, and not waiting on or failing checks
- `assert-pr-fresh --issue <N>` fails unless the PR exists and `branch_status.needs_refresh` is false
- `assert-pr-mergeable --issue <N>` fails unless the PR exists and helper-normalized mergeability is acceptable
- `assert-pr-approved --issue <N>` still uses the final `senior-approved` label gate, but now includes mergeability and check context in failure diagnostics

Draft PR behavior is explicit:

- `open-pr` creates or discovers the PR only
- `open-pr` does not auto-convert an existing draft PR to ready
- `ready-pr` is the only helper command that transitions a draft PR to ready for review
- existing draft PRs classify as `review_repair`, not a separate lifecycle bucket

## Workflow Selection Guide

### Decision table

| You have... | Use this workflow | Why |
|---|---|---|
| A GitHub issue, no branch or PR | `local_claude_codex_issue_delivery` | Full lifecycle: plan, implement, create PR, review loop |
| A PR with review comments or failing checks | `local_claude_codex_pr_repair` | Targeted fix cycle without re-planning |
| A PR that is behind `main` or has conflicts | `local_claude_pr_refresh` | Rebase/merge to restore mergeability before review |
| A clean PR that just needs senior sign-off | `local_codex_pr_review_only` | Minimal: review pass only |
| Not sure / want automatic routing | `local_work_item_router` | Inspects PR state and dispatches to the correct workflow |

When in doubt, use the router. It adds one `inspect-pr` call and routes deterministically.

### Anti-patterns

- **Full issue delivery on an existing PR.** Issue delivery re-enters planning from scratch. If the PR already exists, use PR repair or the router. Rerunning issue delivery risks overwriting existing implementation work.
- **PR repair on a stale branch.** Repair assumes the branch is mergeable. If the branch is behind `main`, run PR refresh first — otherwise repair may introduce merge conflicts that block review.
- **Skipping the router to save one step.** The cost of picking the wrong lifecycle workflow (wasted cycles, overwritten work, confusing review state) is much higher than one extra `inspect-pr` call.
- **Rerunning issue delivery after plan review churns.** The plan loop is capped at 3 rounds. If the plan is still not approved after 3 rounds, approve manually or switch to a narrower workflow. Do not restart the full issue delivery path.
- **Using review-only when checks are failing.** Review-only assumes the branch is in reviewable state. If checks are red, use PR repair to fix them first.
