You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| Review Gate | Quality Enforcement |`review:` field in STAGE.md (auto/ask/external/await/[external,ask]) | orchestrator.ts |
62
+
| Review Gate | Quality Enforcement |`review:` field in STAGE.md — `auto` (harness advances), `ask` (local human approval), `external` (blocks for external review system), `await` (blocks for external event), or compound list like `[external,ask]` (user chooses path) | orchestrator.ts |
| Completion Criteria | Throughout |`quality_gates:` in unit/intent frontmatter, harness-enforced | orchestrator.ts, quality-gate.sh |
@@ -80,7 +80,7 @@ When modifying any component, check if other components need corresponding updat
80
80
| Studio | (no equivalent) | A named lifecycle template (profile implementation) containing stages |
81
81
| Stage | (no equivalent) | A lifecycle phase within a studio, containing hats and review gates |
82
82
| Hat | Role | A behavioral role scoped to a stage, defined in `hats/{hat}.md` files within the stage directory |
83
-
| Review Gate | Quality Gate | A checkpoint between stages (auto, ask, or external)|
83
+
| Review Gate | Quality Gate | A checkpoint between stages controlling advancement. `auto` = harness-only (no human). `ask` = local review UI, human approves/rejects via MCP response. `external` = blocks until external system (GitHub/GitLab) approves; signal detected primarily by branch merge detection, with URL-based CLI probing as fallback. `await` = blocks until an external event occurs (not a review — e.g., customer response, pipeline). Compound: `[external, ask]` = user chooses between external submission or local approval.|
message: `Stage '${currentStage}' is awaiting external review. Provide the review URL via haiku_stage_set or run /haiku:revisit to re-enter the gate.`,
? `Stage '${currentStage}' is awaiting external review at: ${externalUrl}. Neither branch merge detection nor CLI-based check detected approval yet. Run /haiku:pickup after the review is approved.`
1502
+
: `Stage '${currentStage}' is awaiting external review but no review URL was recorded. Run /haiku:pickup after the review is approved.`,
1436
1503
}
1437
1504
}
1438
1505
}
@@ -2655,9 +2722,9 @@ function buildRunInstructions(
2655
2722
sections.push(
2656
2723
`## Awaiting External Review\n\n${
2657
2724
externalUrl
2658
-
? `The stage is awaiting external review at: ${externalUrl}\n\n`
2659
-
: "The stage is awaiting external review but no review URL has been recorded.\n\n"
2660
-
}Ask the user for the status of the external review. If approved, call \`haiku_run_next { intent: "${slug}" }\` — the FSM will detect the approval and advance.\n\n${externalUrl ? "" : `If the user provides a review URL, pass it: \`haiku_run_next { intent: "${slug}", external_review_url: "<url>" }\`\n`}`,
2725
+
? `The stage is awaiting external review at: ${externalUrl}`
2726
+
: "The stage is awaiting external review but no review URL has been recorded."
2727
+
}\n\nThe orchestrator checks for approval automatically (branch merge detection + URL-based CLI probing). Neither detected approval yet.\n\nInform the user that the stage is waiting on external review. After the review is approved, run \`/haiku:pickup\` to continue.`,
For `await` gates, the comms provider can serve as the event signal:
50
+
The comms provider can post gate notifications and receive replies, but the agent cannot use comms MCP tools to self-approve a gate. Gate advancement is controlled by the orchestrator through structural signals (branch merge detection, URL-based CLI probing), not by agent self-confirmation.
51
+
52
+
For `await` gates where a comms signal is the expected resolution (e.g., a customer reply in a Slack thread), the flow is:
51
53
52
54
```
53
55
1. Stage completes → post "Waiting for {event}" to channel
54
56
2. User replies "customer responded" or reacts with ✅
55
-
3. Next session: Claude checks the thread, sees confirmation
56
-
4. Advances the gate
57
+
3. User runs /haiku:pickup after the event occurs
58
+
4. Orchestrator checks gate status and advances
57
59
```
58
60
59
-
This turns the comms channel into a lightweight event bus for human-mediated events.
61
+
For `await` gates where the user wants to approve locally after confirming the event occurred, the stage must have a compound gate `[await, ask]` — the `ask` component allows local approval through the review UI.
62
+
63
+
### Comms as Notification, Not Signal Source
64
+
65
+
Comms MCP tools (Slack, Teams, Discord) are used for:
- Temporary state files — only committed state goes to remote
73
73
- In-progress unit work — only merged results via the intent branch
74
74
75
+
## External Gate Signal Detection
76
+
77
+
For stages with `external` review gates, the orchestrator checks approval using two tiers:
78
+
79
+
### Tier 1: Branch Merge Detection (Primary)
80
+
81
+
The primary signal is whether the stage branch (`haiku/{slug}/{stage}`) was merged back into the intent main branch (`haiku/{slug}/main`). The orchestrator checks this locally using `git merge-base --is-ancestor` and falls back to checking for merged PRs via `gh`/`glab` (which handles squash merges where the branch commit is not a direct ancestor). This is structural verification — the agent cannot fake a branch merge.
82
+
83
+
### Tier 2: URL-Based CLI Probing (Fallback)
84
+
85
+
If a `external_review_url` was recorded in the stage state, the orchestrator also checks PR/MR approval status via CLI tools:
86
+
87
+
-**GitHub** — `gh pr view <url> --json state,reviewDecision` → advances on `MERGED` or `reviewDecision === "APPROVED"`
88
+
-**GitLab** — `glab mr view <url> --output json` → advances on `merged` state or `approved === true`
89
+
90
+
This complements Tier 1 by detecting approval before the branch is actually merged. Runs automatically on every `/haiku:pickup`.
91
+
75
92
## Non-Git Environments
76
93
77
94
When not running in a git repository, the MCP operates in filesystem mode:
78
95
- State is stored as files on disk in `.haiku/`
79
96
- No commits, no pushes, no branches, no worktrees
80
97
- Units work in-place rather than in worktree isolation
81
98
- All lifecycle operations still function — just without version control
99
+
-**External gates fall back to `ask`** — there is no structural signal (branch merge) to enforce external review, so the framework opens the local review UI for human approval instead of blocking indefinitely
0 commit comments