forgedock 1.1.8 → 1.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +10 -33
  2. package/bin/cinema.mjs +23 -5
  3. package/bin/engine-cli.mjs +137 -11
  4. package/bin/env-detect.mjs +249 -0
  5. package/bin/forge-utils.mjs +364 -4
  6. package/bin/forgedock.mjs +1064 -135
  7. package/bin/hooks/session-start.mjs +68 -3
  8. package/bin/init-detect.mjs +101 -12
  9. package/bin/journey.mjs +917 -16
  10. package/bin/recall.mjs +24 -7
  11. package/bin/registry.mjs +91 -3
  12. package/bin/runner.mjs +38 -2
  13. package/bin/tui.mjs +49 -3
  14. package/commands/adopt.md +1 -1
  15. package/commands/analytics.md +8 -8
  16. package/commands/audit.md +1 -1
  17. package/commands/autopilot.md +1 -1
  18. package/commands/ci-audit.md +1 -1
  19. package/commands/cleanup.md +87 -52
  20. package/commands/compat-audit.md +1 -1
  21. package/commands/deploy-info.md +1 -1
  22. package/commands/deploy-pr.md +1 -1
  23. package/commands/diagnose.md +1 -1
  24. package/commands/explain.md +1 -1
  25. package/commands/fix-ci.md +1 -1
  26. package/commands/forgedock-init.md +1 -1
  27. package/commands/incident-response.md +3 -3
  28. package/commands/issue.md +1 -1
  29. package/commands/optimize.md +1 -1
  30. package/commands/orchestrate/config.md +13 -3
  31. package/commands/orchestrate/phase-1-resolve.md +1 -1
  32. package/commands/orchestrate/phase-2-triage.md +1 -1
  33. package/commands/orchestrate/phase-2.5-synthesis.md +1 -1
  34. package/commands/orchestrate/phase-3-dependency.md +128 -20
  35. package/commands/orchestrate/phase-4-execution.md +598 -43
  36. package/commands/orchestrate/phase-5-cleanup.md +1 -1
  37. package/commands/orchestrate/phase-6-report.md +51 -3
  38. package/commands/orchestrate/safety.md +2 -2
  39. package/commands/qa-sweep.md +1 -1
  40. package/commands/quality-gate.md +1 -1
  41. package/commands/recover-orphans.md +5 -5
  42. package/commands/replay.md +1 -1
  43. package/commands/review-pr-agents/api.md +2 -2
  44. package/commands/review-pr-agents/auth.md +2 -2
  45. package/commands/review-pr-agents/billing.md +2 -2
  46. package/commands/review-pr-agents/concurrency.md +2 -2
  47. package/commands/review-pr-agents/database.md +2 -2
  48. package/commands/review-pr-agents/frontend.md +2 -2
  49. package/commands/review-pr-agents/infra.md +2 -2
  50. package/commands/review-pr-agents/protocols.md +1 -1
  51. package/commands/review-pr-agents/scraper.md +2 -2
  52. package/commands/review-pr-agents/security.md +2 -2
  53. package/commands/review-pr-staging.md +41 -3
  54. package/commands/review-pr.md +71 -6
  55. package/commands/rollback.md +1 -1
  56. package/commands/scope.md +1 -1
  57. package/commands/security-audit.md +1 -1
  58. package/commands/test-gate.md +1 -1
  59. package/commands/validate.md +1 -1
  60. package/commands/work-on/build/architect.md +1 -1
  61. package/commands/work-on/build/context.md +9 -6
  62. package/commands/work-on/build/implement.md +1 -1
  63. package/commands/work-on/build/validate.md +1 -1
  64. package/commands/work-on/build.md +31 -6
  65. package/commands/work-on/close.md +3 -2
  66. package/commands/work-on/decompose.md +1 -1
  67. package/commands/work-on/investigate.md +14 -5
  68. package/commands/work-on/remediate.md +331 -0
  69. package/commands/work-on/review.md +1 -1
  70. package/commands/work-on-monolithic.md +1 -1
  71. package/commands/work-on.md +194 -56
  72. package/docs/CI.md +2 -2
  73. package/docs/CODEX.md +1 -1
  74. package/docs/CONFIG.md +186 -0
  75. package/docs/site/command-reference.md +31 -1
  76. package/docs/site/getting-started.md +9 -34
  77. package/docs/site/index.md +1 -1
  78. package/docs/spec/label-state-machine.md +1 -1
  79. package/package.json +2 -1
  80. package/packages/protocol/src/types.js +1 -1
  81. package/scripts/check-command-docs-drift.sh +4 -2
  82. package/scripts/danger-zones.mjs +19 -12
  83. package/scripts/transition-label.sh +101 -13
  84. package/scripts/refresh-bot-token.sh +0 -97
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -139,10 +139,52 @@ done
139
139
  # Results table row (Step 6B).
140
140
  ```
141
141
 
142
+ ### Step 6A.7: Determine idle-policy end state <!-- Added: forge#1814 -->
143
+
144
+ **Why**: `phase-4-execution.md` Step 4B item 6.7 can end the live monitoring loop in two visibly
145
+ different ways: a **clean/paused drain** (every original-batch issue reached `DONE`/`FAILED`, or
146
+ is `blocked-on-human-merge` with no cascade activity left to suppress), or an **idle-policy
147
+ pause** (`BATCH_FULLY_GATED` was true at the moment the batch stopped, meaning Step 4C actively
148
+ suppressed one or more newly-spawned review-finding dispatches). Both are legitimate stopping
149
+ points, but rendering an idle-policy pause under the same "Orchestration Complete" header as a
150
+ genuine full drain misrepresents a paused run as finished — the whole point of #1814 is to make
151
+ this pause visible, not silent.
152
+
153
+ ```bash
154
+ # BATCH_FULLY_GATED is the value computed in phase-4-execution.md Step 4B item 6.7 at the point
155
+ # the live loop stopped — threaded into Phase 6 as a plain boolean, not recomputed here (Phase 6
156
+ # runs after the live loop has already ended, so re-running item 6.7's per-issue classification
157
+ # would be redundant; carry the value forward instead).
158
+ ORCHESTRATION_ENDED_IDLE="${BATCH_FULLY_GATED:-false}"
159
+
160
+ # Count of findings deferred this run for the idle-policy reason specifically (distinct from
161
+ # generation>=2 and comment/typo/P3-same-file deferrals, which are unaffected by this policy).
162
+ IDLE_POLICY_DEFERRED_COUNT=0
163
+ for FINDING_NUM in "${DEFERRED_FINDINGS[@]:-}"; do
164
+ [ -z "$FINDING_NUM" ] && continue
165
+ echo "${DEFERRED_REASONS[$FINDING_NUM]:-}" | grep -qi "batch fully human-gated" && \
166
+ IDLE_POLICY_DEFERRED_COUNT=$((IDLE_POLICY_DEFERRED_COUNT + 1))
167
+ done
168
+ ```
169
+
142
170
  ### Step 6B: Present consolidated report
143
171
 
172
+ Always rendered in full, once, regardless of `{NARRATION_MODE}` — `pipeline.narration` (see `config.md`) only gates the per-completion recap in Step 4B item 8. This is the one place full tables are guaranteed to appear.
173
+
144
174
  ```
175
+ {IF ORCHESTRATION_ENDED_IDLE == "true":}
176
+ ## Orchestration Paused — Idle (waiting on {#MERGE_READY_PRS[@]:-0} + {#BLOCKED_ON_MERGE[@]:-0} merge(s))
177
+
178
+ This run stopped because the remaining batch is fully human-gated — every original issue is
179
+ merged/invalid, or blocked on a human decision/merge. {IDLE_POLICY_DEFERRED_COUNT} newly-spawned
180
+ review-finding issue(s) were deferred (not dispatched) rather than added to the open-issue count.
181
+ See "Merge-Ready" and "Blocked-on-Merge" below for the exact action needed to resume. Re-run
182
+ `/orchestrate` (or let a still-running session's live wake pick it up) once you've merged the
183
+ PR(s) listed there — deferred findings are re-evaluated automatically by the next Completion
184
+ Sweep (Step 4F.2.5) once the batch is no longer fully gated.
185
+ {ELSE:}
145
186
  ## Orchestration Complete
187
+ {END IF}
146
188
 
147
189
  **Scope**: {milestone / issue list}
148
190
  **Duration**: {approximate time}
@@ -245,7 +287,7 @@ current session's live wake pick them up automatically if it is still running).
245
287
 
246
288
  ### Summary
247
289
  - **Investigations**: {N} completed, spawned {M} new issues
248
- - **Review findings**: {N} spawned, {M} resolved in-batch, {K} swept, {J} deferred (cosmetic), {L} deferred (gen2)
290
+ - **Review findings**: {N} spawned, {M} resolved in-batch, {K} swept, {J} deferred (cosmetic), {L} deferred (gen2), {IDLE_POLICY_DEFERRED_COUNT} deferred (idle policy, forge#1814)
249
291
  - **Succeeded**: {N} issues resolved (implementation + sweep)
250
292
  - **Failed**: {N} issues need attention
251
293
  - **Merge-ready**: {#MERGE_READY_PRS[@]:-0} PRs awaiting only a human merge (see "Merge-Ready" section above)
@@ -279,11 +321,14 @@ current session's live wake pick them up automatically if it is still running).
279
321
  | Contract→code divergences | {N} (agents that updated contract mid-build) |
280
322
  | Review findings created | {N_total} |
281
323
  | Findings queued after cascade control | {N_queued}/{N_total} ({N_deferred} deferred — see Step 4C) |
324
+ | Findings deferred — idle policy (forge#1814) | {IDLE_POLICY_DEFERRED_COUNT} (batch fully human-gated at defer time — see Step 4B item 6.7) |
325
+ | P3 findings clubbed (surface-area batching, forge#1818) | {SURFACE_BATCH_COUNT:-0} batch(es) covering {#SURFACE_BATCHED_FINDINGS[@]:-0} finding(s) — see Step 4C |
326
+ | Findings deferred — token budget (forge#1858) | {#TOKEN_DEFERRED[@]:-0} (batch spend {BATCH_TOKEN_SPEND:-0}/{TOKEN_BUDGET:-uncapped} tokens — see Step 4C) |
282
327
  | Competing recommendations reconciled (Phase 2.5) | {RECONCILED_COUNT} (investigation plans arbitrated in place + serialized) |
283
328
  | Findings validated | {N} |
284
329
  | False positives | {N} ({%}) |
285
330
  | Anomalies flagged | {N} |
286
- | Budget limit | ${BUDGET_LIMIT:-uncapped} |
331
+ | Budget limit ($) | ${BUDGET_LIMIT:-uncapped} |
287
332
  | Projected spend (dispatched issues) | ${PROJECTED_SPEND:-—} |
288
333
  | Actual spend (best-effort telemetry) | ${ACTUAL_SPEND:-—} |
289
334
  | Issues deferred (budget ceiling) | {#DEFERRED_BUDGET_ISSUES[@]:-0} |
@@ -292,6 +337,8 @@ current session's live wake pick them up automatically if it is still running).
292
337
 
293
338
  `value-weighted throughput` = Σ(priority_weight × danger_zone_weight) for **merged** issues ÷ actual spend (USD). A higher value means more high-priority issues were resolved per dollar. Trend this across runs via `/pipeline-health` to measure the economic scheduling ROI. <!-- Added: forge#1743 -->
294
339
 
340
+ `P3 findings clubbed` and `Findings deferred — token budget` are a DIFFERENT mechanism from the `$`-denominated `Budget limit`/`Projected spend`/`Actual spend`/`Issues deferred (budget ceiling)` rows above (forge#1743, opt-in `--budget N` flag, gates the *original* issue dispatch order). The token-budget row reads the always-on, token-denominated ceiling that scopes ONLY to Step 4C's review-finding cascade dispatch (forge#1858); `SURFACE_BATCH_COUNT` and `SURFACE_BATCHED_FINDINGS` are populated by the same Step 4C surface-area-batching block (forge#1818) that clubs P3 findings sharing a file/leaf-directory into one dispatched pipeline. Both degrade gracefully to `0`/`uncapped` when the batch had no review findings or ran with defaults. <!-- Added: forge#1858 -->
341
+
295
342
  **Compute value-weighted throughput** (populate before rendering the table):
296
343
 
297
344
  ```bash
@@ -328,6 +375,7 @@ fi
328
375
  - **Value-weighted throughput trending down** → high-value issues deferred or blocked; check Step 3E.5 score distribution
329
376
 
330
377
  ### Next Steps
378
+ {If ORCHESTRATION_ENDED_IDLE == "true": "This run paused on the human-gated idle policy (forge#1814) — merge the PR(s) listed in the Merge-Ready section above, then re-run `/orchestrate` (or let a still-running session's live wake pick it up automatically) to resume dispatch of blocked-on-merge dependents and re-evaluate the {IDLE_POLICY_DEFERRED_COUNT} deferred finding(s)."}
331
379
  {If milestone and all issues done: "Milestone ready to ship. Run `/milestone ship {slug}` when ready. The ship command includes a pre-merge hunk-loss audit (Step 2.5) that detects staging-only hunks in milestone-modified files and rebases the milestone branch to absorb them before creating the PR — protecting against squash-merge regressions."}
332
380
  {If some failed: "Issues #{X}, #{Y} need manual attention. Re-run with `/work-on #{X}` after resolving blockers."}
333
381
  {If fast-lane: "All fixes merged to staging. Merge staging → main via GitHub web UI when ready to deploy."}
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -10,7 +10,7 @@ install: internal
10
10
 
11
11
  1. **Every agent MUST invoke `/work-on` via the Skill tool.** No custom prompts. No manual implementation. Copy the Phase 4A template, fill in variables, done. (See HARD RULES at top of file.)
12
12
  2. **NEVER merge anything to `main`** — agents merge to `staging` or `milestone/{slug}` only
13
- 3. **No artificial concurrency limit by default** — spawn as many agents as there are independent issues. Only file overlap and dependencies require sequencing. Set `forge.yaml → orchestration.max_concurrent` to cap in-flight workers and prevent rate-limit storms on large batches (see Engine mode § Concurrency model).
13
+ 3. **Concurrency is capped by default (12 in-flight agents)** <!-- Updated: forge#1912 --> — file overlap and dependencies still determine which issues are *eligible* to run in parallel, but Phase 4 never dispatches more than `MAX_CONCURRENT` at once (default 12); the rest queue and dispatch as running agents complete. Set `forge.yaml → orchestration.max_concurrent` to raise or lower the cap (see Engine mode § Concurrency model, and `phase-4-execution.md` Step 4A-pre.0.2).
14
14
  4. **Always confirm with user before launching** — Step 3E is the mandatory checkpoint
15
15
  5. **No retries** — if an agent fails, report it and move on
16
16
  6. **Respect existing work** — skip issues already being worked on (`workflow:building`, `workflow:in-review`)
@@ -12,7 +12,7 @@ install: extras
12
12
 
13
13
  You are the QA orchestrator. Auto-discover every page across the platform (dashboard, marketing, blog, auth, docs, pricing), then systematically test every UI element, interaction, workflow, and state transition using browser automation. Create GitHub issues for every finding.
14
14
 
15
- **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
15
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
16
16
  **NEVER use plan mode (EnterPlanMode).**
17
17
 
18
18
  <!-- FORGE:SPEC_LOADED — qa-sweep.md loaded and active. Agent is bound by this spec. -->
@@ -13,7 +13,7 @@ You are a quality gate that runs AFTER implementation but BEFORE commit. Your jo
13
13
 
14
14
  You do NOT post to GitHub. You do NOT create issues. You return findings directly to the builder agent that spawned you.
15
15
 
16
- **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
16
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
17
17
  **NEVER use plan mode (EnterPlanMode).**
18
18
 
19
19
  <!-- FORGE:SPEC_LOADED — quality-gate.md loaded and active. Agent is bound by this spec. -->
@@ -11,7 +11,7 @@ argument-hint: [--dry-run | --since <hours> | --issue <number>]
11
11
 
12
12
  Scan ALL open issues with intermediate workflow labels for orphaned state — issues where the agent died mid-pipeline (context expired, rate-limited, crashed) and no active agent is continuing. Diagnose each orphan's actual GitHub state and apply the appropriate recovery action.
13
13
 
14
- **Agent model policy**: `model: "sonnet"`. Fallback: `model: "opus"` if rate-limited.
14
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet". Fallback: `model: "opus"` if rate-limited.
15
15
  **NEVER use plan mode (EnterPlanMode).**
16
16
  **NEVER use the Agent tool** — recover-orphans re-enters the pipeline via `Skill(skill="work-on", ...)` and `Skill(skill="review-pr", ...)` only.
17
17
 
@@ -336,7 +336,7 @@ for NUM in $ORPHAN_LIST; do
336
336
  else
337
337
  gh issue edit "$NUM" ${GH_FLAG} \
338
338
  --add-label "workflow:merged" \
339
- --remove-label "workflow:investigating,workflow:ready-to-build,workflow:building,workflow:in-review,workflow:invalid,workflow:decomposed" \
339
+ --remove-label "workflow:investigating,workflow:ready-to-build,workflow:building,workflow:in-review,workflow:awaiting-merge,workflow:invalid,workflow:decomposed" \
340
340
  2>/dev/null || true
341
341
  gh issue close "$NUM" ${GH_FLAG} \
342
342
  --comment "Closed by /recover-orphans: PR #${PR_NUM} was already merged. Labels corrected." \
@@ -362,7 +362,7 @@ for NUM in $ORPHAN_LIST; do
362
362
  2>/dev/null || true
363
363
  gh issue edit "$NUM" ${GH_FLAG} \
364
364
  --add-label "workflow:merged" \
365
- --remove-label "workflow:investigating,workflow:ready-to-build,workflow:building,workflow:in-review,workflow:invalid,workflow:decomposed" \
365
+ --remove-label "workflow:investigating,workflow:ready-to-build,workflow:building,workflow:in-review,workflow:awaiting-merge,workflow:invalid,workflow:decomposed" \
366
366
  2>/dev/null || true
367
367
  fi
368
368
  fi
@@ -378,7 +378,7 @@ for NUM in $ORPHAN_LIST; do
378
378
  Skill(skill="review-pr", args="${PR_NUM} --auto-merge --issue ${NUM} --gh-flag ${GH_FLAG}")
379
379
  # After review: update label
380
380
  gh issue edit "$NUM" ${GH_FLAG} --add-label "workflow:in-review" \
381
- --remove-label "workflow:building" 2>/dev/null || true
381
+ --remove-label "workflow:building,workflow:awaiting-merge" 2>/dev/null || true
382
382
  fi
383
383
  RECOVERY_RESULTS="${RECOVERY_RESULTS}| #${NUM} | review-pr | PR #${PR_NUM} submitted for review |\n"
384
384
  ;;
@@ -401,7 +401,7 @@ for NUM in $ORPHAN_LIST; do
401
401
  echo " [DRY-RUN] Would: remove workflow:investigating, workflow:ready-to-build, workflow:building, workflow:in-review"
402
402
  else
403
403
  gh issue edit "$NUM" ${GH_FLAG} \
404
- --remove-label "workflow:investigating,workflow:ready-to-build,workflow:building,workflow:in-review" \
404
+ --remove-label "workflow:investigating,workflow:ready-to-build,workflow:building,workflow:in-review,workflow:awaiting-merge" \
405
405
  2>/dev/null || true
406
406
  gh issue comment "$NUM" ${GH_FLAG} \
407
407
  --body "<!-- FORGE:ORPHAN_RECOVERED -->
@@ -10,7 +10,7 @@ install: extras
10
10
 
11
11
  Replay a completed pipeline run. Fetches all FORGE annotations posted during the pipeline and displays them chronologically — phase headings, timestamps, and key structured fields. Read-only: nothing is written, no labels changed.
12
12
 
13
- **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
13
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
14
14
 
15
15
  ---
16
16
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -11,7 +11,7 @@ install: internal
11
11
 
12
12
 
13
13
  **Trigger**: New or modified routers/routes, OR SDK/OpenAPI files changed (`sdk/`, `openapi*.json`, `openapi-versions/`)
14
- **Type**: `general-purpose` | **Model**: `sonnet`
14
+ **Type**: `general-purpose` | **Model**: `{SUBAGENT_MODEL}`
15
15
 
16
16
  **Prompt template:**
17
17
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -11,7 +11,7 @@ install: internal
11
11
 
12
12
 
13
13
  **Trigger**: AUTH domain detected
14
- **Type**: `security-exploit-auditor` | **Model**: `sonnet`
14
+ **Type**: `security-exploit-auditor` | **Model**: `{SUBAGENT_MODEL}`
15
15
 
16
16
  **Prompt template:**
17
17
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -11,7 +11,7 @@ install: internal
11
11
 
12
12
 
13
13
  **Trigger**: BILLING domain detected
14
- **Type**: `codebase-explorer` | **Model**: `sonnet`
14
+ **Type**: `codebase-explorer` | **Model**: `{SUBAGENT_MODEL}`
15
15
 
16
16
  **Prompt template:**
17
17
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -11,7 +11,7 @@ install: internal
11
11
 
12
12
 
13
13
  **Trigger**: CONCURRENCY domain detected OR BILLING domain detected
14
- **Type**: `general-purpose` | **Model**: `sonnet`
14
+ **Type**: `general-purpose` | **Model**: `{SUBAGENT_MODEL}`
15
15
 
16
16
  **Prompt template:**
17
17
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -11,7 +11,7 @@ install: internal
11
11
 
12
12
 
13
13
  **Trigger**: DATABASE domain detected
14
- **Type**: `general-purpose` | **Model**: `sonnet`
14
+ **Type**: `general-purpose` | **Model**: `{SUBAGENT_MODEL}`
15
15
 
16
16
  **Prompt template:**
17
17
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -11,7 +11,7 @@ install: internal
11
11
 
12
12
 
13
13
  **Trigger**: WEB service touched
14
- **Type**: `codebase-explorer` | **Model**: `sonnet`
14
+ **Type**: `codebase-explorer` | **Model**: `{SUBAGENT_MODEL}`
15
15
 
16
16
  **Prompt template:**
17
17
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -11,7 +11,7 @@ install: internal
11
11
 
12
12
 
13
13
  **Trigger**: INFRA service touched
14
- **Type**: `general-purpose` | **Model**: `sonnet`
14
+ **Type**: `general-purpose` | **Model**: `{SUBAGENT_MODEL}`
15
15
 
16
16
  **Prompt template:**
17
17
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -11,7 +11,7 @@ install: internal
11
11
  **Note**: This agent is for projects with a web-scraping or browser-automation domain. It only spawns when `review.domains.scraping` is set in `forge.yaml`. Projects using Playwright solely for E2E testing do not spawn this agent.
12
12
 
13
13
  **Trigger**: SCRAPING domain detected AND `review.domains.scraping` is configured in forge.yaml
14
- **Type**: `codebase-explorer` | **Model**: `sonnet`
14
+ **Type**: `codebase-explorer` | **Model**: `{SUBAGENT_MODEL}`
15
15
 
16
16
  **Prompt template:**
17
17
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- install: internal
2
+ install: core
3
3
  ---
4
4
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
5
5
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -10,7 +10,7 @@ install: internal
10
10
 
11
11
 
12
12
 
13
- **Type**: `security-exploit-auditor` | **Model**: `sonnet`
13
+ **Type**: `security-exploit-auditor` | **Model**: `{SUBAGENT_MODEL}`
14
14
 
15
15
  **Prompt template:**
16
16
  ```
@@ -13,7 +13,7 @@ install: extras
13
13
 
14
14
  Performs comprehensive review of `staging` before merging to `main`. Handles large diffs (1,000-10,000+ lines), diverse changes, deep analysis, and business impact assessment.
15
15
 
16
- **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
16
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
17
17
  **NEVER use plan mode (EnterPlanMode).**
18
18
  **NEVER use the Agent tool** — this spec uses `Task` for domain agent dispatch. The Agent tool bypasses the allowed-tools constraint declared in this spec's frontmatter and produces opaque output that cannot be structured into the review verdict.
19
19
 
@@ -370,7 +370,7 @@ For fixable failures: checkout staging, apply fix, verify locally, commit as `fi
370
370
 
371
371
  ## Phase 2: Material Change Analysis
372
372
 
373
- Launch agent (model: sonnet) to analyze all commits since last deploy. Categorize as: NEW FEATURE, ENHANCEMENT, BUG FIX, REFACTOR, SECURITY, PERFORMANCE, INFRASTRUCTURE, DEPENDENCY. Separate user-facing vs internal. Document breaking changes and required pre-deploy actions.
373
+ Launch agent (model: {SUBAGENT_MODEL}) to analyze all commits since last deploy. Categorize as: NEW FEATURE, ENHANCEMENT, BUG FIX, REFACTOR, SECURITY, PERFORMANCE, INFRASTRUCTURE, DEPENDENCY. Separate user-facing vs internal. Document breaking changes and required pre-deploy actions.
374
374
 
375
375
  **MANDATORY — post findings as PR comment**: After completing analysis, the agent MUST post its full report directly to the PR:
376
376
  ```bash
@@ -435,7 +435,45 @@ gh pr comment ${PR_NUMBER} -R ${GH_REPO} --body "<!-- FORGE:REVIEW-AGENT:code-qu
435
435
 
436
436
  ## Phase 5: Security & Billing Deep Dive
437
437
 
438
- Read agent catalog from `.claude/commands/review-pr-agents.md`. Launch domain-specific agents based on which domains have changes. Substitute PR diff commands with staging diff commands. Agents: General Security (always), Auth, Billing, Concurrency, Scraper, API Design, Database, Infrastructure.
438
+ **MANDATORY TEMPLATE-RESOLUTION GUARD — run BEFORE reading the agent catalog:**
439
+
440
+ Missing persona templates are a fatal setup error, not permission to skip multi-agent review. Resolve the template source through this ordered chain (identical to the one used by `/review-pr` Phase 3C — do not diverge) and STOP if none resolve — never fall through to reviewing inline in the main context:
441
+
442
+ ```bash
443
+ TEMPLATE_BASE=""
444
+ if [[ -f "$FORGE_HOME/commands/review-pr-agents/protocols.md" ]]; then
445
+ TEMPLATE_BASE="$FORGE_HOME/commands/review-pr-agents"
446
+ TEMPLATE_SOURCE="forge_home"
447
+ else
448
+ FORGE_YAML="${FORGE_CONFIG:-$(git rev-parse --show-toplevel 2>/dev/null)/forge.yaml}"
449
+ REPO_PATH=$(yq '.paths.root' "$FORGE_YAML" 2>/dev/null || git rev-parse --show-toplevel 2>/dev/null || pwd)
450
+ if [[ -f "$REPO_PATH/commands/review-pr-agents/protocols.md" ]]; then
451
+ TEMPLATE_BASE="$REPO_PATH/commands/review-pr-agents"
452
+ TEMPLATE_SOURCE="repo_path"
453
+ elif [[ -f "$REPO_PATH/commands/review-pr-agents.md" ]] && grep -q "^### Agent:" "$REPO_PATH/commands/review-pr-agents.md" 2>/dev/null; then
454
+ # Content check (not just existence) required: a post-split repo still ships a small
455
+ # router stub at this same path that only points back to the (missing) persona
456
+ # directory — reading it would provide no actual protocol/persona content.
457
+ MONOLITHIC_CATALOG="$REPO_PATH/commands/review-pr-agents.md"
458
+ TEMPLATE_SOURCE="monolithic_catalog"
459
+ else
460
+ TEMPLATE_SOURCE="none"
461
+ fi
462
+ fi
463
+
464
+ if [[ "$TEMPLATE_SOURCE" == "none" ]]; then
465
+ echo "FATAL: no review-pr-agents template source resolved (checked \$FORGE_HOME, repo-path fallback, monolithic catalog)."
466
+ # HARD STOP — post error, add needs-human, do NOT review
467
+ fi
468
+ ```
469
+
470
+ **If `TEMPLATE_SOURCE` is `none`**: HARD STOP. Post a PR comment explaining the setup is broken, instructing the user to run `npx forgedock update` to repair the install, add `needs-human`, and exit without posting any findings or a verdict. **NEVER perform the review inline in the main agent context as a substitute.**
471
+
472
+ **If `TEMPLATE_SOURCE` is `forge_home` or `repo_path`** (normal cases — behavior unchanged): `Read: $TEMPLATE_BASE/protocols.md` and `Read: $TEMPLATE_BASE/<persona>.md` per selected agent.
473
+
474
+ **If `TEMPLATE_SOURCE` is `monolithic_catalog`** (last resort): `Read: $MONOLITHIC_CATALOG` and extract the shared protocols section plus each selected persona's section from within that single file.
475
+
476
+ Launch domain-specific agents based on which domains have changes. Substitute PR diff commands with staging diff commands. Agents: General Security (always), Auth, Billing, Concurrency, Scraper, API Design, Database, Infrastructure.
439
477
 
440
478
  **MANDATORY — each domain agent MUST post its findings directly to the PR immediately upon completion** (not batched by the orchestrator):
441
479
  ```bash
@@ -13,7 +13,7 @@ allowed-tools: Task, Bash, Read, Grep, Glob, WebFetch, Skill
13
13
  **NEVER use plan mode (EnterPlanMode)** during review — it breaks execution context.
14
14
  **NEVER use the Agent tool** — review-pr dispatches domain agents via `Task` tool only. `Agent` spawns opaque subprocesses that bypass the allowed-tools constraint and cannot post structured findings to the PR. Always use `Task(...)` for review agent launch (Phase 3C).
15
15
 
16
- **Agent model policy**: `model: "sonnet"` (standard tier); the General Security & Quality reviewer spawned as always-runs Task uses `effort: xhigh` (deep tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Pass model and effort explicitly in every `Task` tool call. Feature gate: pass `effort` only on Claude Code >= 2.1.154.
16
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier); the General Security & Quality reviewer spawned as always-runs Task uses `effort: xhigh` (deep tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Pass model and effort explicitly in every `Task` tool call. Feature gate: pass `effort` only on Claude Code >= 2.1.154. **The domain-review Task agents this file dispatches** (per `commands/review-pr-agents/*.md`) resolve via `model: "{SUBAGENT_MODEL}"` — forge.yaml `agents.subagent_model`, else `agents.default_model`, else `"sonnet"` — not `{DEFAULT_MODEL}` directly.
17
17
 
18
18
  <!-- FORGE:SPEC_LOADED — review-pr.md loaded and active. Agent is bound by this spec. -->
19
19
 
@@ -1257,12 +1257,60 @@ DOMAIN_FILES_API=$(echo "$FILES" | grep -iE "router|route|endpoint|openapi|sdk|a
1257
1257
 
1258
1258
  ### 3C: Load Agent Templates & Launch
1259
1259
 
1260
- **>>> INVOCATION: Read shared protocols + selected persona files:**
1260
+ **>>> MANDATORY TEMPLATE-RESOLUTION GUARD — run BEFORE any Read of persona templates:**
1261
+
1262
+ Missing persona templates are a fatal setup error, not permission to skip multi-agent review. Resolve the template source through this ordered chain and STOP if none resolve — never fall through to reviewing inline in the main context:
1263
+
1264
+ ```bash
1265
+ # Tier 1: $FORGE_HOME (the installed location — the common case)
1266
+ TEMPLATE_BASE=""
1267
+ if [[ -f "$FORGE_HOME/commands/review-pr-agents/protocols.md" ]]; then
1268
+ TEMPLATE_BASE="$FORGE_HOME/commands/review-pr-agents"
1269
+ TEMPLATE_SOURCE="forge_home"
1270
+ else
1271
+ # Tier 2: repo-path fallback — same resolution already used for the code index below.
1272
+ # FORGE_YAML is resolved independently here (not yet loaded — that happens further
1273
+ # down in this phase) so the guard does not depend on later-phase ordering.
1274
+ FORGE_YAML="${FORGE_CONFIG:-$(git rev-parse --show-toplevel 2>/dev/null)/forge.yaml}"
1275
+ REPO_PATH=$(yq '.paths.root' "$FORGE_YAML" 2>/dev/null || git rev-parse --show-toplevel 2>/dev/null || pwd)
1276
+ if [[ -f "$REPO_PATH/commands/review-pr-agents/protocols.md" ]]; then
1277
+ TEMPLATE_BASE="$REPO_PATH/commands/review-pr-agents"
1278
+ TEMPLATE_SOURCE="repo_path"
1279
+ elif [[ -f "$REPO_PATH/commands/review-pr-agents.md" ]] && grep -q "^### Agent:" "$REPO_PATH/commands/review-pr-agents.md" 2>/dev/null; then
1280
+ # Tier 3: monolithic catalog — last resort, contains all personas + protocols in one file.
1281
+ # The content check (`### Agent:` headers) is required, not just file existence: a
1282
+ # post-split repo still ships a small router stub at this same path that only points
1283
+ # BACK to the (missing) commands/review-pr-agents/ directory — reading it would not
1284
+ # provide any actual protocol/persona content, silently reproducing the original bug
1285
+ # one tier deeper. <!-- Added: forge#1849 -->
1286
+ TEMPLATE_BASE=""
1287
+ MONOLITHIC_CATALOG="$REPO_PATH/commands/review-pr-agents.md"
1288
+ TEMPLATE_SOURCE="monolithic_catalog"
1289
+ else
1290
+ TEMPLATE_SOURCE="none"
1291
+ fi
1292
+ fi
1293
+
1294
+ if [[ "$TEMPLATE_SOURCE" == "none" ]]; then
1295
+ echo "FATAL: no review-pr-agents template source resolved (checked \$FORGE_HOME, repo-path fallback, monolithic catalog)."
1296
+ # HARD STOP — post error, add needs-human, do NOT review
1297
+ fi
1261
1298
  ```
1262
- Read: $FORGE_HOME/commands/review-pr-agents/protocols.md
1263
- Read: $FORGE_HOME/commands/review-pr-agents/<persona>.md (one per selected agent from Phase 3B)
1299
+
1300
+ **If `TEMPLATE_SOURCE` is `none`**: HARD STOP. Post a PR comment explaining the setup is broken (`gh pr comment $ARGUMENTS --body "..."`) instructing the user to run `npx forgedock update` to repair the install, add `needs-human`, and exit Phase 3 without posting any findings or a `FORGE:REVIEW` verdict. **NEVER perform the review inline in the main agent context as a substitute.** A degraded solo review that presents itself as complete is worse than no review — missing templates must fail loudly, not silently.
1301
+
1302
+ **If `TEMPLATE_SOURCE` is `forge_home` or `repo_path`** (the normal cases — behavior unchanged from before this guard existed):
1303
+ ```
1304
+ Read: $TEMPLATE_BASE/protocols.md
1305
+ Read: $TEMPLATE_BASE/<persona>.md (one per selected agent from Phase 3B)
1264
1306
  ```
1265
1307
 
1308
+ **If `TEMPLATE_SOURCE` is `monolithic_catalog`** (last-resort fallback):
1309
+ ```
1310
+ Read: $MONOLITHIC_CATALOG
1311
+ ```
1312
+ Then extract the shared protocols section and each selected persona's section from within that single file — same content, different packaging.
1313
+
1266
1314
  Persona file names: `security.md` (always), `auth.md`, `billing.md`, `concurrency.md`, `scraper.md`, `frontend.md`, `api.md`, `database.md`, `infra.md`.
1267
1315
  See `review-pr-agents.md` for the full routing table mapping domains → persona files.
1268
1316
 
@@ -1437,7 +1485,7 @@ The `protocols.md` file contains the Evidence-Based Review Protocol, Structured
1437
1485
  6. Substitute code index slice: `[INDEX_SLICE]` → the matching `$INDEX_SLICE_{DOMAIN}` variable for this agent (e.g., `$INDEX_SLICE_AUTH` for the auth agent). Agents MUST query index data first; fall back to grep only when index slice is empty or unavailable.
1438
1486
  7. Substitute per-agent diff slice: `[DOMAIN_DIFF_SLICE]` → the matching `$DIFF_SLICE_*` variable (e.g., `$DIFF_SLICE_AUTH` for the auth agent, `$DIFF_SLICE_SECURITY` for the security agent). This replaces any `gh pr diff [PR_NUMBER]` call inside the agent template — the agent works from the pre-computed slice, not the full changeset.
1439
1487
  8. If Phase 2.5 found broken assumptions, append them to the agent's prompt as "Pre-found integration issues to verify"
1440
- 9. Launch via `Task` tool with the resolved model (default `"sonnet"`, fallback `"opus"` if rate-limited)
1488
+ 9. Launch via `Task` tool with `model: "{SUBAGENT_MODEL}"` (forge.yaml `agents.subagent_model`, else `agents.default_model`, else `"sonnet"`; fallback `"opus"` if rate-limited)
1441
1489
 
1442
1490
  **CRITICAL**: Launch ALL selected agents in a SINGLE message using multiple Task tool calls. Each agent posts findings directly to the PR via `gh pr comment`.
1443
1491
 
@@ -1487,7 +1535,7 @@ AGENT_COUNT=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" --jq '[.[] | s
1487
1535
  FINDING_COUNT=$(echo "$ALL_FINDINGS" | grep -c '.' || echo 0)
1488
1536
  ```
1489
1537
 
1490
- If synthesis needed, launch a `general-purpose` Task (model: resolved per policy — default sonnet, fallback opus):
1538
+ If synthesis needed, launch a `general-purpose` Task (model: `"{SUBAGENT_MODEL}"`, fallback `"opus"` if rate-limited):
1491
1539
  - Deduplicate findings by file + line range ±5 (keep higher confidence)
1492
1540
  - Resolve contradictions by reading disputed code
1493
1541
  - Dismiss false positives with evidence
@@ -2117,6 +2165,23 @@ REVIEW_IS_STALE="false"
2117
2165
  if [ "$CURRENT_SHA" != "$REVIEW_SHA" ]; then REVIEW_IS_STALE="true"; fi
2118
2166
  ```
2119
2167
 
2168
+ **Verifiable agent count (MANDATORY — do not report a self-asserted `Agents: [N]` figure)** <!-- Added: forge#1849 -->
2169
+
2170
+ A degraded run that skipped Task-based agent dispatch must be visible from this summary alone, without interrogating the agent afterward. Compute the actual launched-agent count from the `<!-- FORGE:REVIEW-AGENT:{domain} -->` comments each agent is required to post (Phase 3C), rather than trusting a free-text tally:
2171
+
2172
+ ```bash
2173
+ ACTUAL_AGENT_DOMAINS=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" \
2174
+ --jq '[.[].body | scan("<!-- FORGE:REVIEW-AGENT:([a-z-]+) -->") | .[0]] | unique | join(", ")' 2>/dev/null || echo "")
2175
+ # NOTE: no `|| echo 0` fallback here — grep -c always prints a count (including 0 on
2176
+ # no match) even though it exits 1 in that case. Appending `|| echo 0` after a `grep -c`
2177
+ # pipeline double-counts: the pipeline already printed "0", then the fallback prints a
2178
+ # second "0" line, corrupting the value to "0\n0" in exactly the zero-agent case this
2179
+ # check exists to detect. <!-- Added: forge#1849 -->
2180
+ ACTUAL_AGENT_COUNT=$(echo "$ACTUAL_AGENT_DOMAINS" | tr ',' '\n' | grep -c '.' 2>/dev/null)
2181
+ ```
2182
+
2183
+ Substitute `ACTUAL_AGENT_COUNT`/`ACTUAL_AGENT_DOMAINS` into the summary's `**Agents**: [N] ([names])` field below — do NOT substitute a manually-counted or remembered figure. If the agent's own recollection of what it launched disagrees with `ACTUAL_AGENT_COUNT` (e.g. it believes it ran agents but zero `FORGE:REVIEW-AGENT` comments exist), that mismatch itself is the signal this check exists to surface: report `ACTUAL_AGENT_COUNT` as-is (it is the ground truth) and add a note in the Recommendation section flagging the discrepancy — never suppress it to make the summary look complete. If `ACTUAL_AGENT_COUNT` is `0`, the review degraded to solo/inline mode (the exact failure mode this guard exists to catch) and the verdict MUST reflect that (`NEEDS RE-REVIEW`), regardless of what analysis was performed inline.
2184
+
2120
2185
  ```bash
2121
2186
  gh pr comment $ARGUMENTS --body "$(cat <<'EOF'
2122
2187
  # PR Review Summary: #[NUMBER] - [TITLE]
@@ -16,7 +16,7 @@ install: extras
16
16
 
17
17
  You are the pipeline's emergency rollback system. When a shipped feature or fix causes production issues, this command creates a revert PR and fast-tracks it through the pipeline.
18
18
 
19
- **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
19
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
20
20
 
21
21
  **NEVER use plan mode (EnterPlanMode)** — it breaks execution context.
22
22
 
package/commands/scope.md CHANGED
@@ -12,7 +12,7 @@ You are a read-only pre-flight analyst. Given a GitHub issue number, you estimat
12
12
 
13
13
  **This command is strictly READ-ONLY.** No labels are written, no comments are posted, no worktrees are created.
14
14
 
15
- **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
15
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
16
16
  **NEVER use plan mode (EnterPlanMode).**
17
17
 
18
18
  ---
@@ -19,7 +19,7 @@ This command is designed to be run:
19
19
 
20
20
  This is NOT a PR review — it does not approve or block. It creates issues for each gap found.
21
21
 
22
- **Agent model policy**: `model: "sonnet"`, `effort: xhigh` (deep tier — comprehensive security analysis). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` only on Claude Code >= 2.1.154.
22
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet", `effort: xhigh` (deep tier — comprehensive security analysis). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` only on Claude Code >= 2.1.154.
23
23
  **NEVER use plan mode (EnterPlanMode).**
24
24
 
25
25
  ---
@@ -13,7 +13,7 @@ install: extras
13
13
 
14
14
  Verifies a staging→main bundle's acceptance criteria against running code before deploy. Called by `/review-pr-staging` (Phase 6.5) with the bundle PRs, or run standalone when `--prs` is absent (computes the bundle itself). Returns a machine-readable BLOCK / PASS / SKIP verdict for the caller to consume.
15
15
 
16
- **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
16
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
17
17
  **NEVER use plan mode (EnterPlanMode).**
18
18
  **NEVER use the Agent tool** — test-gate dispatches test clusters via `Task` only. The Agent tool bypasses the allowed-tools constraint and produces output that cannot be structured into the machine-readable BLOCK / PASS / SKIP verdict.
19
19
 
@@ -12,7 +12,7 @@ install: extras
12
12
 
13
13
  Verify whether a reported issue is real before anyone writes code. This command exists for reports that come from outside the pipeline — user complaints, DevOps alerts, monitoring triggers, gut feelings. It is the checkpoint before creating a GitHub issue.
14
14
 
15
- **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
15
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
16
16
 
17
17
  **Output**: A verdict (CONFIRMED / NOT A PROBLEM / NEEDS MORE DATA) with evidence.
18
18
 
@@ -11,7 +11,7 @@ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--files AFFE
11
11
  **Time budget**: Max 3 minutes. Skip any file read that times out.
12
12
  **Output**: Post `<!-- FORGE:ARCHITECT -->` comment on the issue, then return structured plan to caller.
13
13
 
14
- **Agent model policy**: `model: "sonnet"`, `effort: xhigh` (deep tier — full code-path tracing, multi-file architecture planning). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` only on Claude Code >= 2.1.154.
14
+ **Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet", `effort: xhigh` (deep tier — full code-path tracing, multi-file architecture planning). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` only on Claude Code >= 2.1.154.
15
15
  **NEVER use plan mode (EnterPlanMode).**
16
16
 
17
17
  <!-- FORGE:SPEC_LOADED — work-on/build/architect.md loaded and active. Agent is bound by this spec. -->