| name | orchestrate-v4 |
| description | PR-based pipeline orchestrator with engineering review gates, milestone support, and observability. Refine → Implement (PR) → Review loop → Integration Tests (PR) → Review loop → Merge → Close. Recognizes milestone markers as hard stops. |
| disable-model-invocation | true |
| argument-hint | [supervised|autonomous] [ticket list, e.g. SF-7, SF-8 or #7, #8] |
You are the v4 orchestrator for this session. Your job is to implement GitHub Project tickets sequentially using a PR-based pipeline with engineering review gates. You stay lightweight — you manage the pipeline, board updates, review loops, observability, and sequencing. Subagents do the work.
v4 additions: UI test stage (Playwright — runs in CI via Docker Compose, not post-deploy), infrastructure security auto-detection, conformance auditing, deployment & promotion phases, background CI/CD health watching via ci-fix-v4.
Pipeline Per Ticket
1. REFINE STORY ─────────── refine-story-v4 (updates issue spec)
2. IMPLEMENT ────────────── implement-ticket-v4 (creates PR #1)
3. REVIEW (implementation) ─ engineering-review (standards + build + unit tests)
└─ Loop: reviewer ↔ implementer (max 3 iterations)
└─ On approve → continue to 3.5
3.5. SECURITY REVIEW ──────── security-review (OWASP Top 10 + infrastructure)
└─ Loop: reviewer ↔ implementer (max 2 iterations)
└─ On pass → merge PR #1
4. INTEGRATION TESTS ────── integration-test (branches from updated main, creates PR #2)
5. REVIEW (integration) ─── engineering-review (test quality + tests pass)
└─ Loop: reviewer ↔ test-writer (max 3 iterations)
└─ On approve → merge PR #2
6. UI TESTS ──────── ui-test (branches from updated main, creates PR #3)
7. REVIEW (playwright) ───── engineering-review (test quality + tests pass)
└─ Loop: reviewer ↔ test-writer (max 3 iterations)
└─ On approve → merge PR #3
8. CLOSE ────────────────── close issue, update board
Parse Arguments
Parse $ARGUMENTS as follows:
- Mode: If the first word is
supervised or autonomous, use it as the mode and consume it. Otherwise, default to supervised.
- Ticket list: Everything remaining is the ticket list. Tickets are separated by commas. They may be provided as issue numbers (e.g.,
#7, #8) or Story IDs (e.g., SF-7, SF-8).
If no tickets are provided, ask the user what tickets to implement.
Step 0: Load Context (Once Per Session)
0a. Resolve Project Identity
REPO_NWO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
REPO_OWNER=$(echo "$REPO_NWO" | cut -d/ -f1)
REPO_NAME=$(echo "$REPO_NWO" | cut -d/ -f2)
Store REPO_OWNER and REPO_NAME — you'll use them for all commands.
0b. Sync Standards & Read Config
- Sync the standards repo:
- If
../TI-Engineering-Standards/ exists: cd ../TI-Engineering-Standards && git pull --ff-only && cd -
- If not:
git clone https://github.com/drdatarulz/TI-Engineering-Standards.git ../TI-Engineering-Standards/
- Read
../TI-Engineering-Standards/CLAUDE.md (skim — subagents get the details)
- Read
../TI-Engineering-Standards/standards/story-writing-standards.md — understand milestone marker format
- Read
CLAUDE.md — extract:
- Build command (e.g.,
dotnet build {ProjectName}.sln)
- Test commands (unit + integration)
- Story ID prefix
- Branch naming pattern
- GitHub Project Board URL
- Read
ARCHITECTURE.md
0e. Initialize Session Metrics
session_metrics = {
tickets: [],
total_refine_tokens: 0,
total_impl_tokens: 0,
total_review_tokens: 0,
total_security_tokens: 0,
total_test_tokens: 0,
total_playwright_tokens: 0,
total_duration_ms: 0,
prd_amendments: [],
ci_watches: [], // tracks background CI watcher results
ci_fixes: [] // tracks background CI fix agent results
}
0c. Resolve Project Board IDs
Extract the project number from the board URL in CLAUDE.md, then query:
gh api graphql -f query='
{
user(login: "REPO_OWNER") {
projectV2(number: PROJECT_NUMBER) {
id
field(name: "Status") {
... on ProjectV2SingleSelectField {
id
options { id name }
}
}
}
}
}'
Store the project ID, field ID, and option IDs for: Inbox, Up Next, In Progress, Done, Waiting/Blocked.
0d. Resolve Ticket Issue Numbers
For each ticket in the list, resolve the GitHub issue number. Tickets can be provided as issue numbers (e.g., #7, 7) or as Story IDs (e.g., SF-7). If a Story ID is provided, search for the matching issue:
gh issue list --repo REPO_OWNER/REPO_NAME --search "STORY_ID in:title" --json number,title --jq '.[0].number'
Per-Ticket Pipeline
For EACH ticket, execute these 6 stages:
Stage 1: REFINE STORY
1a. Pre-flight
git checkout main && git pull origin main
- Verify git hooks: If
.githooks/ exists, run git config --local core.hooksPath .githooks
1a.1 Milestone Detection
Check if this ticket is a milestone marker:
gh issue view {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --json labels --jq '.labels[].name' | grep -q '^milestone$'
If milestone label is found: This is a milestone review gate. Do NOT run the pipeline. Instead:
- Run the smoke test checklist from the milestone issue body
- Report milestone results to the user
- STOP regardless of mode (supervised or autonomous). Output:
## Milestone Reached: {MILESTONE_TITLE}
### Smoke Test Results
- [ ] Application starts: {pass/fail}
- [ ] Health endpoint: {pass/fail}
- [ ] {Other checks from issue body}
### Stories Completed in This Milestone
{list of stories completed since last milestone}
Waiting for approval. Review the application and say "proceed" to continue past this milestone.
Wait for user reply. This is a hard gate.
1a.2 Ticket Readiness Check
For non-milestone tickets, verify the ticket is ready:
BODY=$(gh issue view {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --json body --jq .body)
If the body is empty or contains no - [ ] acceptance criteria checkboxes, SKIP this ticket. Add to Skipped table with reason "Ticket not ready — missing acceptance criteria."
1a.3 Rollback Tag
Tag main before any work begins on this ticket:
git tag pre-{STORY_ID}
1b. Spawn refine-story-v4
Read .claude/skills/refine-story-v4/SKILL.md and substitute:
{ISSUE_NUMBER} → the GitHub issue number
{STORY_ID} → the story ID (e.g., AZ-017)
{REPO_OWNER} → resolved repo owner
{REPO_NAME} → resolved repo name
{ORCHESTRATOR_MODE} → true
Pass to Agent tool with subagent_type: "general-purpose".
1c. Process result
- If
STATUS: AlreadyRefined — continue to Stage 1d
- If
STATUS: Refined — continue to Stage 1d
- If
STATUS: Blocked (e.g., missing external API spec) — move issue to Waiting/Blocked, post comment with REASON, skip this ticket
- If
STATUS: NeedsManualReview — move issue to Waiting/Blocked, post comment, skip this ticket
1d. External API Spec Gate (HARD GATE — see standards/api-integration.md)
Before dispatching to implementation, check whether the refined ticket involves external API integration. Read the issue body and check for signs: provider names (e.g., Athena, PropertyLens, E2Value, FEMA), HttpClient references, endpoint URLs, or a ## Spec Reference section.
If the ticket involves an external API:
- Check for the spec on disk:
ls docs/api-specs/{provider}* 2>/dev/null
- If no spec exists: The orchestrator blocks this ticket immediately. Do NOT dispatch to implement-ticket-v4.
- Move issue to Waiting/Blocked
- Post issue comment:
## Blocked: External API Spec Missing
This ticket requires integration with **{provider}** but no API spec was found at `docs/api-specs/`.
**Required action:** Obtain the API spec (OpenAPI JSON, ArcGIS layer definition, or documented response schema) and commit it to `docs/api-specs/{provider}-openapi.json` before implementation can proceed.
**Why this gate exists:** Provider C# models must be built from verified API contracts, not from PRD descriptions or assumptions. See `standards/api-integration.md`.
- Skip this ticket and continue to the next one
- If the spec exists: Continue to Stage 2
If the ticket does NOT involve an external API: Continue to Stage 2.
Stage 2: IMPLEMENT
2a. Pre-flight
git checkout main && git pull origin main
- Create branch:
git checkout -b story/{STORY_ID}-short-name main (use fix/ for bugs, task/ for tasks)
- Move issue to In Progress on the project board
2b. Spawn implement-ticket-v4
Read .claude/skills/implement-ticket-v4/SKILL.md and substitute:
{TICKET_NUMBER} → the story ID (e.g., AZ-017)
{STORY_ID} → the story ID (same value as TICKET_NUMBER)
{TICKET_TITLE} → the ticket title
{ISSUE_NUMBER} → the GitHub issue number
{BRANCH_NAME} → the branch just created
{REPO_OWNER} → resolved repo owner
{REPO_NAME} → resolved repo name
{FIX_MODE} → false
{PR_NUMBER} → (leave as literal — not in fix mode)
{ITERATION} → 0
Pass to Agent tool with subagent_type: "general-purpose".
2c. Process result
- If
STATUS: Complete — extract PR_NUMBER from report, continue to Stage 2d
- If
STATUS: Partial — post issue comment describing what's incomplete, move to Waiting/Blocked, skip this ticket
- If
STATUS: Blocked — post issue comment with blocker, move to Waiting/Blocked, skip this ticket
2d. Scope Completeness Check
After the implementer reports completion, verify the implementation actually covers the full scope of the ticket. Specifically:
-
UI Deferral Detection: If the ticket's acceptance criteria mention any of these: Blazor pages, screens, routes (e.g., /forms, /data-dictionary), UI components, or .razor files — check whether corresponding .razor files were created in the PR. If the criteria require UI but no .razor files were added:
- Check the PR description and implementation notes for deferral language ("deferred", "follow-up", "NOT include UI", "API-only")
- If deferral is detected, check whether a follow-up ticket was created
- If no follow-up ticket exists: Create one automatically. Title:
{STORY_ID}b: {original title} — Blazor UI pages. Label: story. Link as sub-issue of the current milestone. Post an issue comment: "Implementation deferred UI pages. Auto-created follow-up ticket #{NEW_ISSUE_NUMBER}."
- If a follow-up ticket exists: Note it in the issue comment and continue
-
Acceptance Criteria Spot-Check: Compare the ticket's - [ ] acceptance criteria against what was implemented. If more than 30% of criteria appear unaddressed (no corresponding code, endpoints, or tests), treat as STATUS: Partial — post issue comment and move to Waiting/Blocked.
-
Follow-Up Ticket Injection (Non-Negotiable): If a follow-up ticket was created (either by the implementer or auto-created in step 1 above), it must be appended to the current orchestrator run's ticket queue. Follow-up tickets do not wait for a future session — they run in the current batch, after the parent ticket completes.
How to inject:
- Resolve the follow-up issue number
- Verify it is on the project board with all fields set (Status, Type, Priority, Component, Story ID). If not, add it and set the fields.
- Append the issue number to the ticket list so it will be picked up after the current ticket's pipeline (stages 3–8) completes
- Log the injection:
"Follow-up ticket #{FOLLOW_UP_NUMBER} injected into current run after #{CURRENT_TICKET_NUMBER}"
Rationale: A follow-up ticket that isn't in the current run will be forgotten. The orchestrator is the only agent that manages sequencing — if it doesn't pick up the ticket, no one will until a human notices the gap. This is how II-210's deferred UI work (II-226) sat untouched for weeks.
After the completeness check passes, continue to Stage 3.
Stage 3: REVIEW (Implementation)
Run a review loop: reviewer checks → if changes requested → implementer fixes → reviewer re-checks. Max 3 iterations.
3a. Spawn engineering-review
Read .claude/skills/engineering-review-v4/SKILL.md and substitute:
{PR_NUMBER} → the implementation PR number
{ISSUE_NUMBER} → the GitHub issue number
{STORY_ID} → the story ID
{BRANCH_NAME} → the implementation branch
{REPO_OWNER} → resolved repo owner
{REPO_NAME} → resolved repo name
{MODE} → implementation
{ITERATION} → current iteration (starting at 1)
Pass to Agent tool with subagent_type: "general-purpose".
3b. Process review result
Post a dedicated issue comment for every review result — this creates a real-time audit trail on the issue.
If STATUS: Approved:
If STATUS: ChangesRequested and iteration < 3:
If STATUS: ChangesRequested and iteration >= 3:
Stage 3.5: SECURITY REVIEW
Run an OWASP Top 10 security analysis on the approved implementation PR. If the PR contains infrastructure files (.bicep, Dockerfile, .github/workflows/*.yml), the infrastructure security checklist runs automatically. Max 2 iterations (security issues that persist after one fix likely need human judgment).
3.5a. Spawn security-review-v4
Read .claude/skills/security-review-v4/SKILL.md and substitute:
{PR_NUMBER} → the implementation PR number
{ISSUE_NUMBER} → the GitHub issue number
{STORY_ID} → the story ID
{BRANCH_NAME} → the implementation branch
{REPO_OWNER} → resolved repo owner
{REPO_NAME} → resolved repo name
{ITERATION} → current iteration (starting at 1)
Pass to Agent tool with subagent_type: "general-purpose".
3.5b. Process security review result
Post a dedicated issue comment for every security review result — this creates a real-time audit trail on the issue. (The security-review-v4 skill posts its own audit comment; verify it was posted but do not duplicate it.)
If STATUS: Passed:
If STATUS: Blocked and iteration < 2:
- Spawn implement-ticket-v4 in FIX mode:
{FIX_MODE} → true
{PR_NUMBER} → the implementation PR number
{ITERATION} → current iteration number
- All other placeholders same as Stage 2
- After fix completes, loop back to 3.5a with incremented iteration
If STATUS: Blocked and iteration >= 2:
Stage 4: INTEGRATION TESTS
4a. Pre-flight
- Ensure on main with latest:
git checkout main && git pull origin main
- Create integration test branch:
git checkout -b story/{STORY_ID}-integration-tests main
4b. Spawn integration-test
Read .claude/skills/integration-test-v4/SKILL.md and substitute:
{STORY_ID} → the story ID
{TICKET_TITLE} → the ticket title
{ISSUE_NUMBER} → the GitHub issue number
{BRANCH_NAME} → the integration test branch
{REPO_OWNER} → resolved repo owner
{REPO_NAME} → resolved repo name
{IMPLEMENTATION_PR} → the merged implementation PR number
{FIX_MODE} → false
{PR_NUMBER} → (leave as literal — not in fix mode)
{ITERATION} → 0
Pass to Agent tool with subagent_type: "general-purpose".
4c. Process result
- If
STATUS: Complete — extract PR_NUMBER from report, continue to Stage 5
- If
STATUS: Partial or STATUS: Blocked — post issue comment, move to Waiting/Blocked, skip remaining stages
Stage 5: REVIEW (Integration Tests)
Same review loop structure as Stage 3, but in integration-tests mode.
5a. Spawn engineering-review
Read .claude/skills/engineering-review-v4/SKILL.md and substitute:
{PR_NUMBER} → the integration test PR number
{ISSUE_NUMBER} → the GitHub issue number
{STORY_ID} → the story ID
{BRANCH_NAME} → the integration test branch
{REPO_OWNER} → resolved repo owner
{REPO_NAME} → resolved repo name
{MODE} → integration-tests
{ITERATION} → current iteration (starting at 1)
Pass to Agent tool with subagent_type: "general-purpose".
5b. Process review result
Post a dedicated issue comment for every review result — this creates a real-time audit trail on the issue.
If STATUS: Approved:
- Check off ALL acceptance criteria checkboxes in the issue body BEFORE merging (prevents the
Closes #XX auto-close from racing the checkbox update):
BODY=$(gh issue view {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --json body --jq .body)
UPDATED=$(echo "$BODY" | sed 's/- \[ \]/- [x]/g')
gh issue edit {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --body "$UPDATED"
- Verify checkboxes were checked — re-fetch the issue body and confirm no
- [ ] remains:
gh issue view {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --json body --jq '.body' | grep -c '\- \[ \]'
If the count is > 0, retry the edit once. If it still fails, log a warning but continue.
- Post issue comment:
## Integration Test Review — Approved
**PR:** #{PR_NUMBER}
**Iterations:** {N}
**Violations:** 0
**Suggestions:** {count}
Review passed all standards checks. Merging.
- Merge the PR:
gh pr merge {PR_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --merge --delete-branch
- Pull main:
git checkout main && git pull origin main
- Capture the merge SHA:
MERGE_SHA=$(git rev-parse HEAD)
- Delete local branch:
git branch -d {BRANCH_NAME} 2>/dev/null
- Spawn CI watcher (background) — see Background CI/CD Health Watching
- Continue to Stage 6 immediately (do not wait for the watcher)
If STATUS: ChangesRequested and iteration < 3:
If STATUS: ChangesRequested and iteration >= 3:
Stage 6: UI TESTS
6a. Pre-flight
- Ensure on main with latest:
git checkout main && git pull origin main
- Create UI test branch:
git checkout -b story/{STORY_ID}-ui-tests main
6b. Spawn ui-test
Read .claude/skills/ui-test-v4/SKILL.md and substitute:
{STORY_ID} → the story ID
{TICKET_TITLE} → the ticket title
{ISSUE_NUMBER} → the GitHub issue number
{BRANCH_NAME} → the UI test branch
{REPO_OWNER} → resolved repo owner
{REPO_NAME} → resolved repo name
{IMPLEMENTATION_PR} → the merged implementation PR number
{FIX_MODE} → false
{PR_NUMBER} → (leave as literal — not in fix mode)
{ITERATION} → 0
Pass to Agent tool with subagent_type: "general-purpose".
6c. Process result
- If
STATUS: Complete — extract PR_NUMBER from report, continue to Stage 7
- If
STATUS: Partial or STATUS: Blocked — post issue comment, move to Waiting/Blocked, skip remaining stages
Stage 7: REVIEW (Playwright Tests)
Same review loop structure as Stage 5, but reviewing UI test quality.
7a. Spawn engineering-review
Read .claude/skills/engineering-review-v4/SKILL.md and substitute:
{PR_NUMBER} → the UI test PR number
{ISSUE_NUMBER} → the GitHub issue number
{STORY_ID} → the story ID
{BRANCH_NAME} → the UI test branch
{REPO_OWNER} → resolved repo owner
{REPO_NAME} → resolved repo name
{MODE} → ui-tests
{ITERATION} → current iteration (starting at 1)
Pass to Agent tool with subagent_type: "general-purpose".
7b. Process review result
Post a dedicated issue comment for every review result.
If STATUS: Approved:
- Post issue comment:
## UI Test Review — Approved
**PR:** #{PR_NUMBER}
**Iterations:** {N}
**Violations:** 0
**Suggestions:** {count}
Review passed all standards checks. Merging.
- Merge the PR:
gh pr merge {PR_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --merge --delete-branch
- Pull main:
git checkout main && git pull origin main
- Capture the merge SHA:
MERGE_SHA=$(git rev-parse HEAD)
- Delete local branch:
git branch -d {BRANCH_NAME} 2>/dev/null
- Spawn CI watcher (background) — see Background CI/CD Health Watching
- Continue to Stage 8 immediately (do not wait for the watcher)
If STATUS: ChangesRequested and iteration < 3:
If STATUS: ChangesRequested and iteration >= 3:
Stage 8: CLOSE
-
Safety-net checkbox verification — if the issue is still open (not auto-closed by Closes #XX), check off any remaining unchecked acceptance criteria:
REMAINING=$(gh issue view {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --json body --jq '.body' | grep -c '\- \[ \]')
if [ "$REMAINING" -gt 0 ]; then
BODY=$(gh issue view {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --json body --jq .body)
UPDATED=$(echo "$BODY" | sed 's/- \[ \]/- [x]/g')
gh issue edit {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --body "$UPDATED"
fi
-
Post observability metrics as an issue comment before closing:
gh issue comment {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME} --body "$(cat <<'EOF'
## Observability Metrics
**Orchestrator model:** {ORCHESTRATOR_MODEL}
| Phase | Model | Tokens | Duration |
|-------|-------|--------|----------|
| Refine | {REFINE_MODEL} | {REFINE_TOKENS} | {REFINE_DURATION} |
| Implement | {IMPL_MODEL} | {IMPL_TOKENS} | {IMPL_DURATION} |
| Review (Impl) | {REVIEW_MODEL} | {REVIEW_TOKENS} | {REVIEW_DURATION} |
| Security Review | {SECURITY_MODEL} | {SECURITY_TOKENS} | {SECURITY_DURATION} |
| Integration Tests | {TEST_MODEL} | {TEST_TOKENS} | {TEST_DURATION} |
| Review (Tests) | {TEST_REVIEW_MODEL} | {TEST_REVIEW_TOKENS} | {TEST_REVIEW_DURATION} |
| Playwright Tests | {PLAYWRIGHT_MODEL} | {PLAYWRIGHT_TOKENS} | {PLAYWRIGHT_DURATION} |
| Review (Playwright) | {PLAYWRIGHT_REVIEW_MODEL} | {PLAYWRIGHT_REVIEW_TOKENS} | {PLAYWRIGHT_REVIEW_DURATION} |
| **Total** | — | **{TOTAL_TOKENS}** | **{TOTAL_DURATION}** |
Review iterations (impl): {IMPL_REVIEW_ITERS} | Security iterations: {SECURITY_ITERS} | Review iterations (tests): {TEST_REVIEW_ITERS} | Review iterations (playwright): {PLAYWRIGHT_REVIEW_ITERS}
### CI/CD Health
| Merge | PR | Status | Fix PR |
|-------|----|--------|--------|
| {SHA} | #{PR} | {passed/fixed/blocked} | #{FIX_PR or n/a} |
EOF
)"
Omit the CI/CD Health table if all watchers reported Passed (i.e., nothing interesting happened).
Use the per-ticket metrics tracked in session_metrics.tickets[] for this ticket. Tokens should be formatted with comma separators (e.g., 45,230). Duration should be in human-readable format (e.g., 1m 35s). Omit rows for phases that were skipped (e.g., if no integration tests were run, omit that row).
Capturing the model per phase. Every per-stage subagent skill (refine-story-v4, implement-ticket-v4, engineering-review-v4, security-review-v4, integration-test-v4, ui-test-v4) reports its model in the MODEL: line of its STATUS block. Extract that value verbatim and use it in the table above. Use the friendly name (e.g., Opus 4.7, Sonnet 4.6, Haiku 4.5) rather than the model ID. When a phase runs multiple iterations on different models (rare, but possible if you override per iteration), list them comma-separated (e.g., Opus 4.7, Sonnet 4.6).
Capturing the orchestrator's own model. Report the model the orchestrator (this session) is running on — read it from the system prompt's "You are powered by the model named …" line. Use the same friendly-name format.
-
Close the issue (if not already auto-closed):
gh issue close {ISSUE_NUMBER} --repo {REPO_OWNER}/{REPO_NAME}
(Board automation moves it to Done)
Note: Acceptance criteria are primarily checked off in Stage 5b before merging, so this step is a safety net. The individual stage comments (Refinement, Implementation, Review results, Integration Tests) provide the audit trail, and the observability metrics comment provides the cost/performance record.
Supervised Mode Gate
If MODE is supervised, you MUST stop between tickets (not between stages). After completing all 6 stages for a ticket (or after a ticket is skipped/blocked), output your check-in report and end with exactly:
Waiting for approval. Say "proceed" to continue to the next ticket.
The next ticket DOES NOT START until the user replies. This is a hard gate. If you find yourself typing "Now starting the next ticket" in supervised mode, STOP.
In autonomous mode, skip this gate and continue to the next ticket.
Background CI/CD Health Watching
After every PR merge (implementation, integration tests, or UI tests), spawn a ci-fix-v4 agent in WATCH mode as a background agent. This runs in parallel with the next stage — the orchestrator does not block on it.
Spawning the Watcher
Read .claude/skills/ci-fix-v4/SKILL.md and substitute:
{MODE} → WATCH
{MERGE_SHA} → the merge commit SHA (captured after git pull)
{PR_NUMBER} → the PR that was just merged
{STORY_ID} → the current story ID
{REPO_OWNER} / {REPO_NAME} → resolved repo identity
Pass to Agent tool with subagent_type: "general-purpose" and run_in_background: true.
Track each watcher in session_metrics.ci_watches[]:
{ merge_sha, pr_number, story_id, stage, status: "pending" }
Processing Watcher Results
When a background watcher completes, check its status:
If STATUS: Passed:
- Update the watcher entry:
status: "passed"
- No further action — continue current work
If STATUS: Failed:
- Update the watcher entry:
status: "failed"
- Spawn ci-fix-v4 in FIX mode as a background agent:
- Continue current work — do not block
If STATUS: Timeout or STATUS: NoRuns:
- Update the watcher entry with the reported status
- Log a warning but do not halt — these are informational. They may indicate a workflow configuration issue but are not blocking.
Processing Fix Agent Results
When a background fix agent completes, check its status:
If STATUS: Fixed:
- Update the fix entry:
status: "fixed", fix_pr: {FIX_PR_NUMBER}
- No further action — the fix has already been merged
If STATUS: Blocked:
- Update the fix entry:
status: "blocked", reason: {REASON}
- This is a circuit breaker — a CI/CD failure that cannot be auto-fixed means main is broken and deployments are stuck. Halt the orchestrator after the current stage completes.
Drain Before Close (Stage 8)
Before posting the final observability metrics for a ticket, drain all pending CI watchers and fix agents for that ticket. If any are still running, wait for them to complete before closing the ticket. This ensures the ticket's issue comment reflects the full CI/CD outcome.
Circuit Breakers (Orchestrator Halts Entirely)
Even in autonomous mode, STOP the entire loop if:
- 3 consecutive tickets are Blocked or Partial — something systemic is wrong
- A PR merge conflict occurs — needs human judgment
- Build fails on main after a merge — main is corrupted
- 3 review iterations exhausted on a single ticket — already handled per-ticket, but if this happens on 2 consecutive tickets, halt
- A CI/CD fix agent reports Blocked — a pipeline failure that cannot be auto-fixed means main is broken and deployments are stuck
When halted, report the full session summary and explain why you stopped.
Session Summary (Final Report)
After all tickets are processed (or the loop is halted), produce this summary:
## Session Summary
### Completed
| Ticket | Title | Impl PR | Test PR | Playwright PR | Review Iters (Impl) | Security Iters | Review Iters (Test) | Review Iters (Playwright) | Tests Added | Playwright Tests Added |
|--------|-------|---------|---------|---------------|---------------------|----------------|---------------------|---------------------------|-------------|----------------------|
| {PREFIX}-{N} | ... | #N | #N | #N | N | N | N | N | N | N |
### Partial
| Ticket | Title | What Remains |
|--------|-------|-------------|
| {PREFIX}-{N} | ... | [description] |
### Blocked
| Ticket | Title | Blocker |
|--------|-------|---------|
| {PREFIX}-{N} | ... | [what's needed] |
### Skipped
| Ticket | Title | Reason |
|--------|-------|--------|
| {PREFIX}-{N} | ... | [why skipped] |
### Milestones Reached
| Milestone | Smoke Test | Stories Included |
|-----------|-----------|-----------------|
| M1: Auth + Dashboard | Pass/Fail | #1, #2, #3 |
### Observability
**Orchestrator model:** [friendly name, e.g., `Opus 4.7`]
| Ticket | Refine | Impl | Review | Security | Test | Playwright | Total Tokens | Duration |
|--------|--------|------|--------|----------|------|------------|-------------|----------|
| AZ-XXX | Sonnet 4.6 / 12,400 | Opus 4.7 / 45,230 | Sonnet 4.6 / 18,100 | Opus 4.7 / 9,800 | Sonnet 4.6 / 22,400 | Sonnet 4.6 / 18,600 | 126,530 | 115s |
_(Per-stage cells use `{model} / {tokens}` format so cost variance by model is visible at a glance. Models are reported by each subagent in its STATUS block.)_
**Session Totals:**
- Total tokens (all agents): X
- Total duration: Xm Xs
- Tickets completed: X / Y
- Tickets partial: X
- Tickets blocked: X
- Tickets skipped: X
- Milestones reached: X
- Total implementation PRs merged: X
- Total integration test PRs merged: X
- Total UI test PRs merged: X
- Total review iterations (implementation): X
- Total security review iterations: X
- Total security findings (blocking/advisory): X/X
- Total review iterations (integration): X
- Total review iterations (Playwright): X
- Total integration tests added: X
- Total UI tests added: X
- Total files changed: X
- CI/CD watches: X passed, X failed, X fixed, X blocked
### PRD Amendments
| Ticket | Finding | Suggested PRD Update |
|--------|---------|---------------------|
| AZ-XXX | [what was discovered during development] | [what should change in the PRD] |
_(If no PRD amendments, omit this section)_