Implement features based on a design document using CAFleet-native orchestration with TDD cycle. Use when the user asks to implement or execute a design document. Takes document path as argument. Do NOT implement a design document by reading it and coding manually — always invoke this skill instead.
Implement features based on a design document using up to four roles orchestrated via the CAFleet message broker: Director (orchestrator), Programmer (implements), Tester (writes tests), and Verifier (E2E/integration testing). Every inter-agent message is persisted in SQLite and visible in the admin WebUI timeline. The Director judges which members to spawn based on the nature of the implementation tasks. For each step, the Tester writes unit tests first, the Director reviews and approves them, then the Programmer implements code to pass the tests. The Director also reviews the Programmer's implementation for code quality and design doc compliance before committing. After all TDD steps, the Verifier performs E2E/integration verification (Phase D) if spawned. After user approval, the Director runs the full publication flow: Step 6 pushes the feature branch and opens a PR with @copilot requested, Step 7 runs a cron-driven Copilot review loop that routes inline comments to the still-live Programmer / Tester and exits when Copilot approves or has been quiescent for 5 ticks, and Step 8 finalizes, commits the completion marker, pushes it (when the branch is tracked on origin), and tears the team down.
| Role | Identity |
|---|
| Does |
|---|
| Does NOT |
|---|
| Role definition |
|---|
| Director | Main Claude | Register with CAFleet, spawn members via cafleet member create, validate doc, assign steps, review tests against design doc, review implementation code for quality and compliance, commit after each phase, escalation arbitration, orchestrate TDD cycle | Write code, write tests | roles/director.md |
| Programmer | Member agent | Implement code to pass tests, run tests, report results via cafleet send, escalate test defects to Director, update design doc checkboxes and Progress counter | Write or modify tests, commit code, communicate with user directly | roles/programmer.md |
| Tester | Member agent | Read design doc, write unit tests per step, fix tests based on Director feedback, report to Director via cafleet send | Write implementation code, commit code, communicate with user directly | roles/tester.md |
| Verifier | Member agent (optional) | E2E/integration testing, tool discovery, evidence collection (screenshots, logs, output), failure reporting with suggested fixes | Write code, write tests, commit, communicate with user directly | roles/verifier.md |
The Director registers with a CAFleet session and spawns each needed member via cafleet member create. All coordination goes through the persistent message queue — every message is auditable via the admin WebUI.
User
+-- Director (main Claude -- cafleet register, cafleet member create, orchestrates TDD cycle)
+-- Programmer (member agent -- implements code to pass tests)
+-- Tester (member agent -- writes unit tests per step)
+-- Verifier (member agent, optional -- E2E/integration testing)
cafleet send (step assignments, test results, code review feedback, escalation)cafleet send (step assignments, test review feedback, test defect reports)cafleet send (verification assignments, results, failure routing)cafleet --session-id <session-id> poll --agent-id <recipient-agent-id> into the member's pane via tmux send-keys. The literal <session-id> and <recipient-agent-id> UUIDs are the session and target member UUIDs the broker has in scope, baked into the injected command string. --session-id is a global flag (placed before the subcommand); --agent-id is a per-subcommand option (placed after the subcommand name).cafleet member create). If TMUX is not set, abort with an explanatory message to the user before spawning anyone.gh must be authenticated for Steps 6 + 7. Lack of auth is NOT fatal — the Director checks gh auth status at Step 6a and falls back to Step 8 local-finalize, skipping the PR and Copilot review loop entirely. All other prerequisites (tmux, approved design doc, feature branch) remain unchanged.| Agent Teams primitive | CAFleet equivalent |
|---|---|
TeamCreate(name="execute-{slug}") | CAFleet session created via cafleet session create — it bootstraps the session + root Director + placement + Administrator in one transaction (no separate cafleet register call needed for the Director) |
Agent(team_name=..., subagent_type=...) | cafleet --session-id <session-id> member create --agent-id <director-agent-id> --name "..." --description "..." -- "<prompt>" |
SendMessage(to="Programmer") | cafleet --session-id <session-id> send --agent-id <director-agent-id> --to <programmer-agent-id> --text "..." |
SendMessage(to="Director") (from member) | cafleet --session-id <session-id> send --agent-id <my-agent-id> --to <director-agent-id> --text "..." |
agent-team-supervision /loop | Skill(cafleet-monitoring) /loop |
TeamDelete | cafleet --session-id <session-id> member delete --agent-id <director-agent-id> --member-id <member-agent-id> for each member, then cafleet session delete <session-id> (soft-deletes the session and sweeps the root Director + Administrator + any surviving members in one transaction). The root Director cannot be deregistered via cafleet deregister — session delete is the only supported teardown. |
| Auto message delivery | Push notification injects cafleet --session-id <session-id> poll --agent-id <recipient-agent-id> into member's tmux pane |
Before validation, resolve $ARGUMENTS into a concrete design-doc.md path.
Load Skill(base-dir) and follow its procedure with $ARGUMENTS as the argument.
${RESOLVED_ARGS} = $ARGUMENTS.${RESOLVED_ARGS} = ${BASE}/design-docs/$ARGUMENTS. Resolve to absolute path.Using ${RESOLVED_ARGS}, apply a three-tier detection strategy, evaluated in order:
| Tier | Condition | Action |
|---|---|---|
| 1 — Direct file path | ${RESOLVED_ARGS} ends with design-doc.md | Use as-is |
| 2 — Slug directory | ${RESOLVED_ARGS} is a directory that contains design-doc.md directly | Append /design-doc.md |
| 3 — Base directory | ${RESOLVED_ARGS} is a directory containing **/design-doc.md (one level deep) | Enter discovery flow |
Tier evaluation is sequential and short-circuits.
When the base directory tier matches:
**/design-doc.md files under the base directory, then filter results to keep only those exactly one level deep (i.e., <base>/<slug>/design-doc.md). Discard any deeper matches.**Status**: field from the document header.Status: Approved. Documents with any other status (Draft, In Progress, Complete) are excluded.| Count | Behavior |
|---|---|
| 0 | Error and abort (see Error: Zero Approved below) |
| 1 | Auto-select: proceed with this document directly |
| 2–4 | Present options via AskUserQuestion (see Selection UI below) |
| 5+ | Present options via paginated AskUserQuestion (see Pagination below) |
Use AskUserQuestion with one question. Each option label is the slug name (directory name) of the design doc. The built-in "Other" option is always available for the user to type a direct path or cancel.
Example with 3 approved docs:
Question: "Which design document would you like to implement?"
Options:
1: "feature-auth"
2: "refactor-db-layer"
3: "add-cli-export"
(Other is added automatically)
When there are more than 4 approved docs, AskUserQuestion's option limit (max 4) is exceeded. Use pagination with all options sorted alphabetically by slug:
"More..."."More..." needed). This avoids a last page with only 1 option, which would violate AskUserQuestion's minimum of 2 options per question.Example with 7 approved docs: page 1 shows 3 + "More..." (4 remain), page 2 shows all 4. Example with 5: page 1 shows 3 + "More..." (2 remain), page 2 shows both 2.
When design docs exist but none have Status: Approved, display a message listing all found docs with their current statuses so the user understands why none qualified. Format:
No approved design documents found in <base-directory>.
Found documents:
- <slug-1>/design-doc.md — Status: Draft
- <slug-2>/design-doc.md — Status: In Progress
- <slug-3>/design-doc.md — Status: Complete
Only documents with Status: Approved can be executed. Update the status or specify a direct path.
Then abort (do not proceed to team creation or execution).
When ${RESOLVED_ARGS} does not match any of the three tiers (not a file path ending in design-doc.md, not a directory containing design-doc.md, and no **/design-doc.md found underneath), display:
Invalid argument: `${RESOLVED_ARGS}`
Expected one of:
- Path to a design-doc.md file (e.g., my-feature/design-doc.md)
- Slug directory containing design-doc.md (e.g., my-feature/)
- No argument (discovers all design docs in ${BASE}/design-docs/)
Then abort.
After resolution, the resolved path is used as the design document path for all subsequent steps.
Before registering with CAFleet:
COMMENT( markers using Grep. If found, resolve them directly: apply the requested changes and remove the markers. Verify with Grep that no COMMENT( markers remain before proceeding.FIXME(claude) markers in the codebase using Grep. If found, note them for the Programmer to resolve first.gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' and the current branch with git branch --show-current. If they match, use AskUserQuestion to propose the branch name feat/<design-doc-slug> and ask the user to approve before creating it. The user will create the branch themselves or approve the proposed name. If already on a non-default branch, skip this step.Load Skill(cafleet) and Skill(cafleet-monitoring).
agent_idcafleet session create (which must be run inside a tmux session) atomically creates the session and registers a root Director bound to the current tmux pane — there is no separate cafleet register step for the Director. Use --json so both IDs are machine-parseable:
cafleet session create --label "design-doc-execute-{slug}" --json
# → {
# "session_id": "550e8400-e29b-41d4-a716-446655440000",
# "label": "design-doc-execute-{slug}",
# "created_at": "…",
# "administrator_agent_id": "…",
# "director": {
# "agent_id": "7ba91234-…",
# "name": "director",
# "description": "Root Director for this session",
# "registered_at": "…",
# "placement": { "director_agent_id": null, "tmux_session": "…", "tmux_window_id": "…", "tmux_pane_id": "…", "coding_agent": "unknown", "created_at": "…" }
# }
# }
Capture session_id and director.agent_id from the JSON response. Substitute them for <session-id> and <director-agent-id> in every subsequent command. Do not store them in shell variables — permissions.allow matches command strings literally, so every command must carry the literal UUIDs. Remember: --session-id is a global flag that goes before the subcommand; --agent-id is a per-subcommand option that goes after the subcommand name.
If you already have a running session (e.g. an outer orchestration), reuse its session_id and its root Director's agent_id instead of creating a new session. Do not attempt to register a second Director with cafleet register --name Director — the root Director from session create is the team lead; a second registration would just create an unrelated agent with no placement row.
/loopBEFORE spawning any member, follow Skill(cafleet-monitoring)'s Monitoring Mandate and start a /loop monitor at the 1-minute interval using the literal <session-id> and <director-agent-id> UUIDs. This is the team-health loop — it stays active through Steps 3–5 and, when Step 6 runs, is swapped (create-before-delete order in Step 7a) for the augmented team-health + PR-review loop. Whichever loop is active gets CronDeleted in Step 8's cleanup.
Based on the design document steps (see roles/director.md for the full decision matrix):
| Task nature | Team composition |
|---|---|
| Code implementation | Programmer + Tester |
| Config/documentation only | Programmer only |
| E2E verification needed (user-visible changes, CLI/UI/API) | + Verifier |
Read the role files that will be embedded verbatim in spawn prompts:
.claude/skills/cafleet-design-doc-execute/roles/programmer.md.claude/skills/cafleet-design-doc-execute/roles/tester.md (if Tester needed).claude/skills/cafleet-design-doc-execute/roles/verifier.md (if Verifier needed)cafleet member createProgrammer spawn prompt:
You are the Programmer in a design document execution team (CAFleet-native).
<ROLE DEFINITION>
[Content of roles/programmer.md injected here verbatim]
</ROLE DEFINITION>
Load these skills at startup:
- Skill(cafleet) — for communication with the Director
- Skill(cafleet-design-doc) — for template and guidelines
SESSION ID: <session-id>
DIRECTOR AGENT ID: <director-agent-id>
YOUR AGENT ID: <my-agent-id> (will be filled in literally by member create)
DESIGN DOCUMENT: [INSERT DESIGN DOC PATH]
COMMUNICATION PROTOCOL:
- Report to Director: cafleet --session-id <session-id> send --agent-id <my-agent-id> --to <director-agent-id> --text "your report"
- When you see cafleet poll output with a message from the Director, act on those instructions.
IMPORTANT: Do NOT commit code yourself. The Director handles all git operations.
IMPORTANT: If blocked, send a message to the Director immediately instead of assuming.
IMPORTANT: Read and follow rules/bash-command.md for all Bash commands.
Start by reading the design document. Then wait for the Director to assign your first step.
Spawn with:
cafleet --session-id <session-id> --json member create --agent-id <director-agent-id> \
--name "Programmer" \
--description "Implements code to pass tests per step" \
-- "<Programmer spawn prompt (embedded role content)>"
Parse agent_id from the JSON response and substitute it for <programmer-agent-id> in every subsequent command.
Tester spawn prompt (if needed):
You are the Tester in a design document execution team (CAFleet-native).
<ROLE DEFINITION>
[Content of roles/tester.md injected here verbatim]
</ROLE DEFINITION>
Load these skills at startup:
- Skill(cafleet) — for communication with the Director
- Skill(cafleet-design-doc) — for template and guidelines
SESSION ID: <session-id>
DIRECTOR AGENT ID: <director-agent-id>
YOUR AGENT ID: <my-agent-id> (will be filled in literally by member create)
DESIGN DOCUMENT: [INSERT DESIGN DOC PATH]
COMMUNICATION PROTOCOL:
- Report to Director: cafleet --session-id <session-id> send --agent-id <my-agent-id> --to <director-agent-id> --text "your report"
- When you see cafleet poll output with a message from the Director, act on those instructions.
IMPORTANT: Do NOT commit code yourself. The Director handles all git operations.
IMPORTANT: Do NOT write implementation code — only test code.
IMPORTANT: If blocked, send a message to the Director immediately instead of assuming.
IMPORTANT: Read and follow rules/bash-command.md for all Bash commands.
Start by reading the design document. Then wait for the Director to assign your first step.
Spawn with:
cafleet --session-id <session-id> --json member create --agent-id <director-agent-id> \
--name "Tester" \
--description "Writes unit tests per step" \
-- "<Tester spawn prompt (embedded role content)>"
Parse agent_id from the JSON response and substitute it for <tester-agent-id> in every subsequent command.
Verifier spawn prompt (if needed):
You are the Verifier in a design document execution team (CAFleet-native).
<ROLE DEFINITION>
[Content of roles/verifier.md injected here verbatim]
</ROLE DEFINITION>
Load these skills at startup:
- Skill(cafleet) — for communication with the Director
- Skill(cafleet-design-doc) — for template and guidelines
SESSION ID: <session-id>
DIRECTOR AGENT ID: <director-agent-id>
YOUR AGENT ID: <my-agent-id> (will be filled in literally by member create)
DESIGN DOCUMENT: [INSERT DESIGN DOC PATH]
COMMUNICATION PROTOCOL:
- Report to Director: cafleet --session-id <session-id> send --agent-id <my-agent-id> --to <director-agent-id> --text "your report"
- When you see cafleet poll output with a message from the Director, act on those instructions.
IMPORTANT: Do NOT commit code or modify implementation/test files.
IMPORTANT: If blocked, send a message to the Director immediately instead of assuming.
IMPORTANT: Read and follow rules/bash-command.md for all Bash commands.
Start by reading the design document and discovering available tools.
Then wait for the Director to assign your first verification task.
Spawn with:
cafleet --session-id <session-id> --json member create --agent-id <director-agent-id> \
--name "Verifier" \
--description "E2E/integration testing and evidence collection" \
-- "<Verifier spawn prompt (embedded role content)>"
Parse agent_id from the JSON response and substitute it for <verifier-agent-id> in every subsequent command.
cafleet --session-id <session-id> member list --agent-id <director-agent-id>
All spawned members must show status: active with a non-null pane_id. If any is missing or pending, retry the spawn before proceeding.
See roles/director.md for commit message conventions.
For each step in the design document:
Skip this phase entirely when the Tester was not spawned (Programmer-only team composition for config/documentation-only steps). Proceed directly to Phase B and assign the step to the Programmer without a separate test-writing commit.
cafleet --session-id <session-id> send --agent-id <director-agent-id> \
--to <tester-agent-id> --text "Step N: <description>. Spec: <…>. Write unit tests and report file paths when done."
cafleet --session-id <session-id> poll --agent-id <director-agent-id>. If the test framework is ambiguous, ask the user via AskUserQuestion and relay the answer via cafleet send.cafleet send if issues found. Repeat until satisfied.&&):
git add <test-files>git commit -m "test: add tests for [feature description]"cafleet --session-id <session-id> send --agent-id <director-agent-id> \
--to <programmer-agent-id> --text "Step N: <description>. Tests at: <paths>. Implement to pass all tests, update design doc checkboxes and Progress counter, then report."
cafleet --session-id <session-id> poll --agent-id <director-agent-id>. On suspected test defect, see roles/director.md for the escalation protocol.cafleet send if issues found. Programmer fixes, re-runs tests, re-reports via cafleet send. Repeat until satisfied.&&):
git add <files> <design-doc>git commit -m "feat: [description of what was implemented]"Repeat from Phase A for the next step. Always include the design document in the implementation commit.
Escalation Protocol (Test Defect): If the Programmer reports a suspected test defect (implementation matches design doc but tests expect something different), the Director reads the design doc and test, then directs either the Tester to fix the test or the Programmer to adjust the implementation via cafleet send. 3-round limit before escalating to the user.
On-Demand Verification: Any member can request verification mid-task via cafleet send to the Director. The Director decides whether to route immediately or defer:
| Route immediately | Defer to Phase D |
|---|---|
| User-visible behavior change (UI, CLI output, API response) | Internal refactoring or data model change |
| Integration with external system | Adequately covered by unit tests |
| Behavior difficult to catch with unit tests alone | Verification requires setup from a later step |
Skip this phase entirely if the Verifier was not spawned. Proceed directly to Step 5 (User Approval).
If the Verifier was spawned, assign verification:
cafleet --session-id <session-id> send --agent-id <director-agent-id> --to <verifier-agent-id> --text "...".cafleet send.cafleet send, test gaps → Tester via cafleet send, spec issues → user.After all TDD steps complete but before finalization, present the implementation to the user for approval.
Before presenting to the user, verify the design document's Success Criteria section:
## Success Criteria section from the design document.- [ ] → - [x]).cafleet send.This step is mandatory and must not be skipped.
git diff main...HEAD).Use AskUserQuestion:
| Option | Label | Description | Behavior |
|---|---|---|---|
| 1 | Approve | Proceed with push, PR creation, Copilot review loop, then finalize | Steps 6 → 7 → 8 |
| 2 | Scan for COMMENT markers | Add COMMENT(name): feedback markers to the changed source files, then select this option to process them | Scan and process markers (see Revision Loop below) |
| 3 | (Other — built-in) | (Free text input, e.g. "approve but skip PR") | Interpret user intent (see Revision Loop below). Intent judgment recognises an approve-local variant that skips Steps 6 + 7 and jumps straight to Step 8 (local finalize only, no push/PR). Abort intent triggers the Abort Flow. |
See roles/director.md for user interaction rules (COMMENT handling, classification, intent judgment, abort detection).
When the user selects "Scan for COMMENT markers": scan changed files for COMMENT( markers. Classify by file location (see roles/director.md) and route via cafleet send:
cafleet --session-id <session-id> send --agent-id <director-agent-id> --to <programmer-agent-id> --text "...".cafleet --session-id <session-id> send --agent-id <director-agent-id> --to <tester-agent-id> --text "...".After all COMMENTs are resolved and verified, re-present to user.
When the user selects "Other": interpret intent per roles/director.md rules.
No round limit — the loop continues until the user approves or aborts.
git add <design-doc> then git commit -m "docs: mark design doc as aborted"/loop is active — team-health if Step 6 was skipped, augmented if Step 7 started — then delete members and run cafleet session delete <session-id> to tear down the session and sweep the root Director + Administrator).After Step 5 Approve, the Director pushes the feature branch, opens a PR, and requests a Copilot review BEFORE marking the design doc complete. Every command is run as a separate Bash call — do NOT chain with &&.
| Check | Command | Failure action |
|---|---|---|
gh authenticated | gh auth status | Report gh not authenticated; skipping PR creation → Step 8 local-finalize |
| Not on default branch | git branch --show-current vs gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' | Report on default branch; cannot open PR → Step 8 local-finalize |
| Branch has commits beyond base | git log <base>..HEAD --oneline | Report no commits to push → Step 8 local-finalize |
gh repo view --json nameWithOwner --jq '.nameWithOwner'. Capture the literal <owner>/<repo> string (e.g. himkt/cafleet) and substitute it into every gh api repos/<owner>/<repo>/... call below. Like the PR number, this is a literal string — NO shell variables.git push -u origin <branch-name>. If this fails (non-fast-forward, branch protection, etc.), report the exact stderr to the user and proceed to Step 8 local-finalize. NEVER force-push.gh pr list --head <branch-name> --json number --jq '.[0].number // empty'. If the result is non-empty, reuse that PR number. Otherwise, run gh pr create --fill and parse the printed URL's trailing number.42) and substitute it into <pr-number> in every subsequent command. DO NOT use a shell variable — permissions.allow matches literal command strings.gh pr edit <pr-number> --add-reviewer @copilot.gh api repos/<owner>/<repo>/pulls/<pr-number>/requested_reviewers should list Copilot. If Copilot is absent from the response AND no Copilot review already exists (gh pr view <pr-number> --json reviews), report Copilot reviewer unavailable for this PR and proceed to Step 8 local-finalize.last_push_ts: record the ISO 8601 timestamp of the push completion (the Director's wall-clock time captured immediately after step 2 returned, or date -u +%Y-%m-%dT%H:%M:%SZ). This initialises the in-context loop state described in the "PR Review Loop State" subsection below.Once the PR exists and Copilot has been invited, the Director runs a cron-driven review loop. The cafleet-monitoring team-health /loop is replaced by an augmented loop that keeps the team-health checks AND adds PR review polling.
The Director holds three in-context variables across loop firings. They are NOT persisted to disk — the Director carries them in its own working memory.
| Variable | Meaning | Update rule |
|---|---|---|
last_push_ts | ISO 8601 timestamp of the most recent push to the PR branch | Reset on every git push from 6b-step 2 or 7d-step 3 |
ticks_since_last_new_review | Number of consecutive loop ticks with 0 new Copilot items | Increment each tick; reset to 0 when new Copilot items arrive |
round | Fix-round counter (push → Copilot review → fix cycle) | Increment after every push from 7d; reset only via 7e "Continue" |
/loop (create-before-delete)On entry to Step 7:
/loop first with the template in "Augmented Loop Prompt" below. Record the new cron ID.CronDelete the existing team-health loop (cron ID recorded in Step 3c).Order matters: create-before-delete eliminates any window where no monitor is running. A one-tick overlap (both loops firing for one minute) is harmless — the Director receives two nudge prompts and reconciles them trivially.
On exit from Step 7 (any exit condition), keep the augmented loop running — Step 8's shutdown is responsible for the final CronDelete.
On each 1-minute wake-up, the Director runs — in order:
cafleet-monitoring): member list → poll → member capture fallback → nudge stalled members.gh pr view <pr-number> --json reviews (GraphQL-shaped; fields are author.login, state, submittedAt, body) AND gh api repos/<owner>/<repo>/pulls/<pr-number>/comments (REST-shaped; fields are user.login, body, path, line, created_at).author.login for gh pr view reviews, user.login for gh api inline comments) matches the regex ^copilot (case-insensitive). Copilot reviews currently post under a login that begins with copilot — the exact slug varies by account plan, so a prefix match is the safe filter.submittedAt for reviews, created_at for inline comments) is strictly later than last_push_ts.| Result | Action |
|---|---|
The most recent Copilot-authored entry in reviews has state == "APPROVED" | Exit loop (success) → Step 8 |
0 new Copilot items AND ticks_since_last_new_review >= 5 | Exit loop (quiescent) → Step 8 |
0 new Copilot items AND ticks_since_last_new_review < 5 | Increment ticks_since_last_new_review, continue |
| ≥ 1 new Copilot items | Go to 7c |
Why 5 ticks (not 3): Copilot's first review after a push can take 3–5 minutes. 3 ticks risks declaring quiescence while Copilot is still composing its response. 5 ticks (~5 minutes) gives the model comfortable headroom without dragging the session out indefinitely.
Why not reviewDecision: the PR-level reviewDecision only reflects required reviewers (typically CODEOWNERS). Copilot is usually not a CODEOWNER, so an approve from Copilot alone leaves reviewDecision null/REVIEW_REQUIRED. Reading the Copilot-specific entry in the reviews array is the reliable signal.
For each new inline comment, pick the owner by file-path pattern:
| Path pattern | Owner | Route |
|---|---|---|
Design doc (design-docs/**/design-doc.md) | Director | Director applies directly — no cafleet send route |
Test file (e.g. **/test_*.py, **/*_test.py, **/tests/**) | Tester | cafleet --session-id <session-id> send --agent-id <director-agent-id> --to <tester-agent-id> --text "Copilot review: <file>:<line> — <comment body>. Please address." |
| Any other source file | Programmer | cafleet --session-id <session-id> send --agent-id <director-agent-id> --to <programmer-agent-id> --text "Copilot review: <file>:<line> — <comment body>. Please address." |
For review-level comments (body text not attached to a specific line), route by Director judgment: spec-level → Director resolves directly; implementation-level → Programmer; test-level → Tester.
cafleet poll. Members do NOT commit — the Director commits after each report.git add / git commit is its own Bash call, no &&):
git commit -m "fix: address Copilot review - <short summary>"git commit -m "fix: address Copilot test review - <short summary>"git commit -m "docs: address Copilot review - <short summary>"git push (no flags — the branch already tracks origin from Step 6).last_push_ts to the post-push wall-clock timestamp, reset ticks_since_last_new_review = 0, and increment round.gh pr edit <pr-number> --add-reviewer @copilot. Re-adding the same reviewer triggers a fresh Copilot pass.When round >= 5, break the auto-loop and escalate to the user via AskUserQuestion:
| Option | Behavior |
|---|---|
| 1. Continue | Reset round = 0, resume Step 7 |
| 2. Finalize now | Exit loop → Step 8 (accept remaining Copilot comments as-is) |
| 3. (Other) | Intent judgment; abort-intent → Abort Flow |
Use this as the /loop prompt for Step 7. Substitute the literal UUIDs and the literal PR number before passing the prompt to /loop — no shell variables.
Monitor team health AND PR review state (interval: 1 minute).
TEAM HEALTH:
1. Run `cafleet --session-id <session-id> --json member list --agent-id <director-agent-id>`.
2. Run `cafleet --session-id <session-id> --json poll --agent-id <director-agent-id> --since "<ISO 8601 timestamp of last check>"`. ACK progress reports.
3. For each member that has not sent a message since last check, run `cafleet --session-id <session-id> member capture --agent-id <director-agent-id> --member-id <member-agent-id> --lines 200`.
4. Nudge stalled members via `cafleet --session-id <session-id> send --agent-id <director-agent-id> --to <member-agent-id> --text "Report your progress now. If blocked, state what is blocking you."`.
PR REVIEW:
5. Run `gh pr view <pr-number> --json reviews` (GraphQL shape: `author.login`, `state`, `submittedAt`, `body`).
6. Run `gh api repos/<owner>/<repo>/pulls/<pr-number>/comments` (REST shape: `user.login`, `body`, `path`, `line`, `created_at`).
7. Filter to entries where the appropriate login field (`author.login` for GraphQL reviews, `user.login` for REST inline comments) starts with `copilot` (case-insensitive) and the appropriate timestamp (`submittedAt` / `created_at`) > `<last-push-timestamp>`.
8. If the most recent Copilot-authored entry in `reviews` has `state == "APPROVED"`: signal Step 7 exit (success).
9. If filter returned 0 entries for 5 consecutive ticks: signal Step 7 exit (quiescent).
10. If filter returned ≥ 1 entries: classify by file path and dispatch via `cafleet --session-id <session-id> send --agent-id <director-agent-id> --to <member-agent-id> --text "Copilot review: <file>:<line> — <body>. Please address."`.
ESCALATION:
11. If any member has been nudged 2 times with no progress, escalate to the user.
12. If `round >= 5`, escalate to the user with the Continue / Finalize-now / Other prompt.
| Case | Detection | Behavior |
|---|---|---|
gh auth status fails | Step 6a precondition check | Skip Steps 6 + 7, go directly to Step 8 local-finalize |
| On default branch | Step 6a precondition check | Skip Steps 6 + 7, go directly to Step 8 local-finalize |
| No commits beyond base | Step 6a precondition check | Skip Steps 6 + 7, go directly to Step 8 local-finalize |
git push rejected | stderr of git push | Report exact stderr to user, skip Step 7, go to Step 8 local-finalize. NEVER force-push. |
gh pr create fails | stderr of gh pr create | Report, skip Step 7, go to Step 8 local-finalize |
@copilot reviewer unavailable | gh api .../requested_reviewers shows no Copilot AND no prior Copilot review | Report Copilot reviewer unavailable for this PR; skip Step 7; go to Step 8 |
Fix-push fails mid-loop (round > 0) | stderr of git push | Escalate to user (AskUserQuestion: retry / finalize now / abort) |
Round limit reached (round >= 5) | Counter check in loop | AskUserQuestion — see 7e above |
| User selects "Other" in Step 5 with abort-intent text | Existing LLM intent judgment | Abort Flow (unchanged — no push) |
| User selects "Other" in Step 5 with approve-local intent | Existing LLM intent judgment, extended | Skip Steps 6 + 7; go to Step 8 local-finalize |
/loop firings keep arriving while the user is speaking to the Director. The Director obeys the project's "Stop means stop" rule (.claude/rules/skill-discovery.md): when the user signals halt (explicit "stop", "wait", profanity / frustration, repeated rejection of tool calls), the Director:
cafleet send / git commit / git push / gh actions immediately./loop firings as notification-only — runs the PR review poll for situational awareness but does NOT route comments, commit, or push until the user re-engages with a specific instruction.If the user explicitly aborts, follow the Abort Flow (update doc Status → "Aborted", commit, run Shutdown Protocol). Step 7's cleanup is identical to Step 8's cleanup — CronDelete the augmented loop, delete members, run cafleet session delete.
Runs after Step 7 exits, or directly after Step 5 when Step 6 was skipped (gh not authenticated / default branch / no commits / approve-local intent).
git add <design-doc> (separate Bash call).git commit -m "docs: mark design doc as complete" (separate Bash call).git rev-parse --abbrev-ref <branch-name>@{upstream}.
git push. This covers both the "Step 6 fully succeeded" path and the "Step 6 partial-fail (push OK, PR create failed)" path, so the final docs commit is never orphaned locally when the branch is already on origin.git push -u): skip the push. The docs commit stays local.CronDelete the currently active /loop monitor — whichever cron ID is recorded: team-health (from Step 3c) if Step 6 was skipped, augmented (from Step 7) otherwise.cafleet --session-id <session-id> member delete --agent-id <director-agent-id> --member-id <programmer-agent-id>
cafleet --session-id <session-id> member delete --agent-id <director-agent-id> --member-id <tester-agent-id> # if spawned
cafleet --session-id <session-id> member delete --agent-id <director-agent-id> --member-id <verifier-agent-id> # if spawned
cafleet deregister --agent-id <director-agent-id> is rejected with Error: cannot deregister the root Director; use 'cafleet session delete' instead.):
cafleet session delete <session-id>
# → Deleted session <session-id>. Deregistered N agents.
session delete soft-deletes the sessions row and physically deletes every associated agent_placements row while preserving all tasks rows for audit — the message history remains inspectable in the admin WebUI (subject to the WebUI's soft-delete filtering behavior).