| name | orchestrate-v3 |
| 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. AZ-017, AZ-018] |
You are the v3 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.
v3 additions: Milestone marker support (hard stop on milestone-labeled issues), per-ticket observability (token/duration tracking), PRD amendment capture, rollback tagging.
Pipeline Per Ticket
1. REFINE STORY ─────────── refine-story-v3 (updates issue spec)
2. IMPLEMENT ────────────── implement-ticket-v3 (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 analysis)
└─ 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. 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 in any format (e.g.,
AZ-017, AZ-018 #45, AZ-019).
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_duration_ms: 0,
prd_amendments: []
}
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, if the GitHub issue number isn't provided, search for it:
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-v3
Read .claude/skills/refine-story-v3/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 2
- If
STATUS: Refined — continue to Stage 2
- If
STATUS: NeedsManualReview — move issue to Waiting/Blocked, post comment, skip this ticket
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-v3
Read .claude/skills/implement-ticket-v3/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.
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-v3/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. Max 2 iterations (security issues that persist after one fix likely need human judgment).
3.5a. Spawn security-review-v3
Read .claude/skills/security-review-v3/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-v3 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-v3 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-v3/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-v3/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
- Delete local branch:
git branch -d {BRANCH_NAME} 2>/dev/null
- Continue to Stage 6
If STATUS: ChangesRequested and iteration < 3:
If STATUS: ChangesRequested and iteration >= 3:
Stage 6: 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
| Phase | Tokens | Duration |
|-------|--------|----------|
| Refine | {REFINE_TOKENS} | {REFINE_DURATION} |
| Implement | {IMPL_TOKENS} | {IMPL_DURATION} |
| Review (Impl) | {REVIEW_TOKENS} | {REVIEW_DURATION} |
| Security Review | {SECURITY_TOKENS} | {SECURITY_DURATION} |
| Integration Tests | {TEST_TOKENS} | {TEST_DURATION} |
| Review (Tests) | {TEST_REVIEW_TOKENS} | {TEST_REVIEW_DURATION} |
| **Total** | **{TOTAL_TOKENS}** | **{TOTAL_DURATION}** |
Review iterations (impl): {IMPL_REVIEW_ITERS} | Security iterations: {SECURITY_ITERS} | Review iterations (tests): {TEST_REVIEW_ITERS}
EOF
)"
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).
-
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.
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
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 | Review Iters (Impl) | Security Iters | Review Iters (Test) | Tests Added |
|--------|-------|---------|---------|---------------------|----------------|---------------------|-------------|
| AZ-XXX | ... | #N | #N | N | N | N | N |
### Partial
| Ticket | Title | What Remains |
|--------|-------|-------------|
| AZ-YYY | ... | [description] |
### Blocked
| Ticket | Title | Blocker |
|--------|-------|---------|
| AZ-ZZZ | ... | [what's needed] |
### Skipped
| Ticket | Title | Reason |
|--------|-------|--------|
| AZ-AAA | ... | [why skipped] |
### Milestones Reached
| Milestone | Smoke Test | Stories Included |
|-----------|-----------|-----------------|
| M1: Auth + Dashboard | Pass/Fail | AZ-001, AZ-002, AZ-003 |
### Observability
| Ticket | Refine Tokens | Impl Tokens | Review Tokens | Security Tokens | Test Tokens | Total Tokens | Duration |
|--------|--------------|-------------|---------------|-----------------|-------------|-------------|----------|
| AZ-XXX | 12,400 | 45,230 | 18,100 | 9,800 | 22,400 | 107,930 | 95s |
**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 review iterations (implementation): X
- Total security review iterations: X
- Total security findings (blocking/advisory): X/X
- Total review iterations (integration): X
- Total tests added: X
- Total files changed: X
### 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)_