forgedock 1.1.1 → 1.1.2

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 (171) hide show
  1. package/README.md +53 -8
  2. package/bin/batch-runner.mjs +339 -0
  3. package/bin/demo.mjs +92 -7
  4. package/bin/engine/phases.mjs +20 -0
  5. package/bin/engine/state.mjs +8 -3
  6. package/bin/engine-cli.mjs +177 -5
  7. package/bin/forgedock.mjs +409 -26
  8. package/bin/hooks/interactive-engine.mjs +509 -0
  9. package/bin/hooks/pre-tool-use.mjs +498 -0
  10. package/bin/hooks/subagent-stop-enforce.mjs +197 -0
  11. package/bin/journey.mjs +72 -14
  12. package/bin/registry.mjs +139 -0
  13. package/bin/report.mjs +447 -0
  14. package/bin/runner.mjs +68 -19
  15. package/bin/settings-hook.mjs +235 -1
  16. package/commands/adopt.md +4 -1
  17. package/commands/analytics.md +4 -1
  18. package/commands/audit-agents.md +110 -27
  19. package/commands/audit.md +20 -1
  20. package/commands/autopilot.md +80 -8
  21. package/commands/changelog.md +2 -1
  22. package/commands/ci-audit.md +2 -1
  23. package/commands/cleanup.md +161 -1
  24. package/commands/compat-audit.md +2 -1
  25. package/commands/deploy-info.md +58 -1
  26. package/commands/design-bench.md +5 -1
  27. package/commands/design-render-critique-loop.md +1 -1
  28. package/commands/diagnose.md +2 -1
  29. package/commands/explain.md +2 -1
  30. package/commands/forge-stats.md +121 -2
  31. package/commands/forgedock-init.md +1 -1
  32. package/commands/geo-audit.md +3 -0
  33. package/commands/incident-response.md +2 -1
  34. package/commands/issue.md +23 -2
  35. package/commands/milestone.md +77 -12
  36. package/commands/optimize.md +2 -1
  37. package/commands/orchestrate/config.md +67 -0
  38. package/commands/orchestrate/phase-1-resolve.md +159 -0
  39. package/commands/orchestrate/phase-2-triage.md +126 -0
  40. package/commands/orchestrate/phase-2.5-synthesis.md +156 -0
  41. package/commands/orchestrate/phase-3-dependency.md +591 -0
  42. package/commands/orchestrate/phase-4-execution.md +962 -0
  43. package/commands/orchestrate/phase-5-cleanup.md +47 -0
  44. package/commands/orchestrate/phase-6-report.md +198 -0
  45. package/commands/orchestrate/safety.md +62 -0
  46. package/commands/orchestrate.md +25 -2045
  47. package/commands/pipeline-health/config.md +34 -0
  48. package/commands/pipeline-health/phase-1-context.md +180 -0
  49. package/commands/pipeline-health/phase-2-metrics.md +1729 -0
  50. package/commands/pipeline-health/phase-3-analyze.md +204 -0
  51. package/commands/pipeline-health/phase-4-proposals.md +117 -0
  52. package/commands/pipeline-health/phase-5-report.md +284 -0
  53. package/commands/pipeline-health/phase-6-summary.md +52 -0
  54. package/commands/pipeline-health.md +25 -2401
  55. package/commands/pipeline-resume.md +24 -1
  56. package/commands/pipeline-status.md +65 -0
  57. package/commands/qa-sweep.md +4 -1
  58. package/commands/quality-gate.md +248 -10
  59. package/commands/replay.md +2 -1
  60. package/commands/review-pr-agents/api.md +135 -0
  61. package/commands/review-pr-agents/auth.md +137 -0
  62. package/commands/review-pr-agents/billing.md +101 -0
  63. package/commands/review-pr-agents/concurrency.md +145 -0
  64. package/commands/review-pr-agents/database.md +103 -0
  65. package/commands/review-pr-agents/frontend.md +89 -0
  66. package/commands/review-pr-agents/infra.md +385 -0
  67. package/commands/review-pr-agents/protocols.md +185 -0
  68. package/commands/review-pr-agents/scraper.md +185 -0
  69. package/commands/review-pr-agents/security.md +406 -0
  70. package/commands/review-pr-agents.md +45 -1722
  71. package/commands/review-pr-staging.md +196 -40
  72. package/commands/review-pr.md +591 -52
  73. package/commands/rollback.md +2 -1
  74. package/commands/scope.md +2 -1
  75. package/commands/security-audit.md +2 -1
  76. package/commands/signal-planner.md +623 -0
  77. package/commands/sync-ecosystem.md +1 -0
  78. package/commands/test-gate.md +17 -1
  79. package/commands/validate.md +2 -1
  80. package/commands/work-on/build/architect.md +28 -0
  81. package/commands/work-on/build/context.md +2 -0
  82. package/commands/work-on/build/implement.md +3 -1
  83. package/commands/work-on/build/validate.md +26 -7
  84. package/commands/work-on/build.md +163 -24
  85. package/commands/work-on/close.md +130 -3
  86. package/commands/work-on/decompose.md +19 -1
  87. package/commands/work-on/investigate.md +117 -2
  88. package/commands/work-on/review.md +24 -4
  89. package/commands/work-on-monolithic.md +7 -2
  90. package/commands/work-on.md +202 -4
  91. package/docs/BRAND.md +14 -7
  92. package/docs/CI.md +2 -2
  93. package/docs/CODEX.md +36 -1
  94. package/docs/CONFIG.md +5 -8
  95. package/docs/FORGE-PROTOCOL.md +15 -1064
  96. package/docs/anthropic-devrel-outreach.md +2 -2
  97. package/docs/articles/command-decomposition-token-savings.md +214 -0
  98. package/docs/articles/model-release-playbook.md +131 -0
  99. package/docs/articles/per-repo-adaptive-scripts-token-savings.md +27 -25
  100. package/docs/claude-breakpoints.json +75 -5
  101. package/docs/design/abc-benchmark.md +1 -1
  102. package/docs/design/design-spec-schema.md +1 -1
  103. package/docs/design/divergent-generation.md +1 -1
  104. package/docs/design/eval-gate-runbook.md +178 -0
  105. package/docs/design/show-hn-draft.md +26 -1
  106. package/docs/design/token-cost-baseline-1298.md +59 -0
  107. package/docs/eval/README.md +117 -0
  108. package/docs/eval/corpus/seed-v1.json +6 -0
  109. package/docs/eval/published/claude-sonnet-4-6-2026-07-04.json +33 -0
  110. package/docs/site/annotations-explained.md +24 -0
  111. package/docs/site/command-learning-path.md +51 -14
  112. package/docs/site/command-reference.md +339 -113
  113. package/docs/site/for-companies.md +95 -0
  114. package/docs/site/forge-annotation-protocol.md +12 -256
  115. package/docs/site/getting-started.md +43 -4
  116. package/docs/site/github-is-the-memory.md +113 -0
  117. package/docs/site/how-it-works.md +3 -13
  118. package/docs/site/index.md +9 -1
  119. package/docs/spec/eval-run-result.md +147 -0
  120. package/docs/spec/forge-protocol-v1.md +441 -18
  121. package/docs/spec/label-state-machine.md +55 -0
  122. package/docs/spec/review-protocol.md +158 -0
  123. package/docs/spec-graph-schema.md +28 -0
  124. package/docs/superpowers/specs/2026-07-04-economic-self-governance-design.md +181 -0
  125. package/docs/superpowers/specs/2026-07-04-provenance-trail-design.md +189 -0
  126. package/examples/forgedock-demo/README.md +41 -22
  127. package/examples/forgedock-demo/issues/06-bug-tags-type-validation.md +43 -0
  128. package/examples/forgedock-demo/issues/07-bug-negative-offset-pagination.md +42 -0
  129. package/examples/forgedock-demo/issues/08-bug-patch-mass-assignment.md +49 -0
  130. package/examples/forgedock-demo/issues/09-bug-count-injection.md +47 -0
  131. package/examples/forgedock-demo/issues/10-feature-sort-param.md +39 -0
  132. package/examples/forgedock-demo/issues/11-feature-patch-tags.md +37 -0
  133. package/examples/forgedock-demo/issues/12-feature-bulk-create.md +42 -0
  134. package/examples/forgedock-demo/issues/13-feature-archive-notes.md +46 -0
  135. package/examples/forgedock-demo/issues/14-refactor-extract-title-validation.md +41 -0
  136. package/examples/forgedock-demo/issues/15-refactor-protected-route-flag.md +43 -0
  137. package/examples/forgedock-demo/issues/16-refactor-extract-store.md +45 -0
  138. package/examples/forgedock-demo/issues/17-perf-tags-dedup-set.md +35 -0
  139. package/examples/forgedock-demo/issues/18-perf-remove-redundant-sort.md +37 -0
  140. package/examples/forgedock-demo/issues/19-docs-api-reference-full.md +53 -0
  141. package/examples/forgedock-demo/issues/20-docs-intentional-flaw-convention.md +46 -0
  142. package/examples/forgedock-demo/scripts/smoke.js +18 -1
  143. package/examples/forgedock-demo/src/db.js +36 -11
  144. package/examples/forgedock-demo/src/routes/notes.js +106 -9
  145. package/examples/forgedock-demo/src/server.js +4 -1
  146. package/package.json +3 -1
  147. package/packages/protocol/LICENSE +21 -0
  148. package/packages/protocol/src/cli.js +135 -0
  149. package/packages/protocol/src/emit.js +146 -0
  150. package/packages/protocol/src/index.js +43 -0
  151. package/packages/protocol/src/parse.js +229 -0
  152. package/packages/protocol/src/types.js +171 -0
  153. package/packages/protocol/src/validate.js +122 -0
  154. package/scripts/bench-topology-cost.mjs +372 -0
  155. package/scripts/check-command-docs-drift.sh +198 -0
  156. package/scripts/check-protocol-restatements.sh +176 -0
  157. package/scripts/check-registry/README.md +72 -0
  158. package/scripts/check-registry/manifest.json +6 -0
  159. package/scripts/code-index.sh +454 -0
  160. package/scripts/conformance-check.mjs +168 -0
  161. package/scripts/doctor-pipeline-state.sh +484 -0
  162. package/scripts/eval-gate-baseline.json +17 -0
  163. package/scripts/eval-gate-scorecard.mjs +242 -0
  164. package/scripts/eval-scorecard-aggregator.mjs +252 -0
  165. package/scripts/flaky-quarantine.sh +241 -0
  166. package/scripts/forge-annotation.sh +567 -0
  167. package/scripts/issue-dedup.sh +236 -0
  168. package/scripts/validate-annotation-node.mjs +233 -0
  169. package/scripts/worktree-lifecycle.sh +3 -3
  170. package/templates/devdocs/agent/using-forgedock.md +14 -0
  171. package/docs/site/.vitepress/config.mjs +0 -85
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Autonomous platform improvement cycle — recon, triage, fix, report. Runs recon+triage by default; pass --fix to also pick up and fix top issues. Human gates all deploys.
3
- argument-hint: [--fix | --recon-only | --fix --limit 5 | --dry-run]
3
+ argument-hint: [--fix | --recon-only | --fix --limit 5 | --dry-run | --fix --yes]
4
+ install: extras
4
5
  ---
5
6
 
6
7
  # /autopilot — Recursive Platform Improvement Cycle
@@ -19,13 +20,18 @@ Resolve `{BILLING_ENABLED}` from `forge.yaml` before executing any phase:
19
20
  BILLING_ENABLED=$(yq '.billing.enabled // false' "$(git rev-parse --show-toplevel)/forge.yaml" 2>/dev/null || echo 'false')
20
21
  ```
21
22
 
23
+ **NEVER use plan mode (EnterPlanMode).**
24
+ **NEVER use the Agent tool** — autopilot dispatches work via `Skill(skill="work-on", ...)` only. The Agent tool bypasses the Skill pipeline's label state machine, investigation comments, and structured review — leaving no audit trail.
25
+
26
+ <!-- FORGE:SPEC_LOADED — autopilot.md loaded and active. Agent is bound by this spec. -->
27
+
22
28
  You are an autonomous improvement engine for this project. Your job is to **find what's wrong, create trackable issues, and optionally fix the highest-impact ones** — all in a single cycle. Every cycle leaves the platform measurably better than before.
23
29
 
24
30
  **This is designed to run repeatedly.** Each cycle builds on the last — issues created in cycle N get fixed in cycle N+1. The platform compounds improvements over time.
25
31
 
26
32
  **NEVER use plan mode (EnterPlanMode)** — it breaks execution context.
27
33
 
28
- **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`. User can override with `--model <name>`. Pass the resolved model in every `Agent`/`Task` tool call. Each agent prompt is scoped to a specific data source or issue — the model executes the explicit steps without needing broad inference.
34
+ **Agent model policy**: `model: "sonnet"` (standard tier). Fallback: `model: "opus"` if rate-limited. User can override with `--model <name>`. Pass model explicitly in every `Agent`/`Task` tool call. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154.
29
35
 
30
36
  ---
31
37
 
@@ -38,6 +44,7 @@ You are an autonomous improvement engine for this project. Your job is to **find
38
44
  | `--fix --limit N` | Fix at most N issues (default: 3) |
39
45
  | `--recon-only` | Phase 1 only (data collection, no issue creation) |
40
46
  | `--dry-run` | Run everything but don't create issues or PRs — just report what would happen |
47
+ | `--fix --yes` | Auto-approve low-risk fixes (P3, single-file, non-sensitive domain); P0/P1, multi-file, and sensitive-domain fixes still require confirmation |
41
48
 
42
49
  Parse `$ARGUMENTS` and set these variables:
43
50
  ```
@@ -45,6 +52,7 @@ MODE = "full" | "recon-only" | "fix" # derived from flags
45
52
  DO_FIX = true if --fix present
46
53
  FIX_LIMIT = N from --limit N, default 3
47
54
  DRY_RUN = true if --dry-run present
55
+ AUTO_YES = true if --yes present
48
56
  ```
49
57
 
50
58
  ---
@@ -356,22 +364,47 @@ gh issue list --state open --label "bug" --limit 50 --json number,title,labels,c
356
364
 
357
365
  **MANDATORY CHECKPOINT — do NOT proceed without user confirmation.**
358
366
 
367
+ **Exception**: when `AUTO_YES = true`, classify each fix target by risk tier before prompting. Low-risk fixes are auto-approved; high-risk fixes still require confirmation.
368
+
369
+ **Risk classification** (evaluate per-issue at this step):
370
+
371
+ ```
372
+ LOW_RISK = all of the following are true:
373
+ - Priority is P2 or P3 (not P0 or P1)
374
+ - Affects only a single file (from issue body or recon finding)
375
+ - No sensitive-domain labels: auth, billing, database, security, payments, gdpr
376
+
377
+ HIGH_RISK = any of the following:
378
+ - Priority P0 or P1
379
+ - Multi-file change (2+ files)
380
+ - Has a sensitive-domain label (auth, billing, database, security, payments, gdpr)
381
+ - Issue has `needs-human` label
382
+ ```
383
+
384
+ When `AUTO_YES = true`:
385
+ - **LOW_RISK issues**: auto-approve, log `[AUTO-APPROVED: low-risk]`, proceed to 4B.5/4C without waiting.
386
+ - **HIGH_RISK issues**: present the checkpoint below and wait for user response. If user skips, remove from fix targets and continue with remaining low-risk issues.
387
+
388
+ When `AUTO_YES = false` (default): present the full checkpoint for ALL fix targets and wait.
389
+
359
390
  ```markdown
360
391
  ## Autopilot Fix Plan
361
392
 
362
393
  I'll run `/work-on` for these {N} issues:
363
394
 
364
- | # | Title | Priority | Estimated Scope |
365
- |---|-------|----------|-----------------|
366
- | {number} | {title} | {priority} | {small/medium/large} |
395
+ | # | Title | Priority | Estimated Scope | Risk Tier |
396
+ |---|-------|----------|-----------------|-----------|
397
+ | {number} | {title} | {priority} | {small/medium/large} | LOW / HIGH |
367
398
 
368
399
  Each issue goes through: investigate → validate → build → review → merge to staging.
369
400
  Nothing merges to `main` — you deploy when ready.
370
401
 
402
+ {If AUTO_YES and any HIGH_RISK: "Note: {N_low} low-risk issues were auto-approved. The {N_high} high-risk issue(s) above require your confirmation."}
403
+
371
404
  **Proceed?** (yes / adjust / skip)
372
405
  ```
373
406
 
374
- Wait for user response. If they adjust, re-select. If they skip, end the cycle.
407
+ Wait for user response on high-risk issues. If they adjust, re-select. If they skip all, end the cycle.
375
408
 
376
409
  ### 4B.5: Spec-Edit Impact Analysis (MANDATORY before any spec-touching fix) <!-- Added: forge#870 -->
377
410
 
@@ -484,6 +517,44 @@ FIX_RESULTS.push({
484
517
  When ready to deploy, merge `staging` → `main` via GitHub.
485
518
  ```
486
519
 
520
+ ### 4E: Deploy Train Check <!-- Added: forge#1332 -->
521
+
522
+ After fixes are merged to staging, check the deploy train state. The deploy train is the single rolling staging→main PR — one per deploy cycle. Do NOT open a new staging→main PR if one is already open.
523
+
524
+ ```bash
525
+ # Check for an open staging→main deploy PR (the current train)
526
+ TRAIN_PR=$(gh pr list {GH_FLAG} \
527
+ --head "{STAGING_BRANCH}" \
528
+ --base "{DEFAULT_BRANCH}" \
529
+ --state open \
530
+ --json number,url \
531
+ --jq '.[0] // empty' 2>/dev/null)
532
+
533
+ TRAIN_PR_NUMBER=$(echo "$TRAIN_PR" | jq -r '.number // empty')
534
+
535
+ if [ -n "$TRAIN_PR_NUMBER" ]; then
536
+ # Train exists — check if it is held by open findings
537
+ HELD_BY_COUNT=$(gh issue list {GH_FLAG} \
538
+ --label "review-finding" \
539
+ --state open \
540
+ --search "PR #${TRAIN_PR_NUMBER}" \
541
+ --json number --jq '. | length' 2>/dev/null || echo 0)
542
+
543
+ if [ "$HELD_BY_COUNT" -gt 0 ]; then
544
+ echo "Deploy train PR #${TRAIN_PR_NUMBER} is HELD by ${HELD_BY_COUNT} open finding(s)."
545
+ echo "The fixes merged in this autopilot cycle may resolve some of them."
546
+ echo "Re-run /review-pr-staging ${TRAIN_PR_NUMBER} to re-evaluate the train gate."
547
+ else
548
+ echo "Deploy train PR #${TRAIN_PR_NUMBER} is CLEAR — no open findings. Ready to merge when you authorize."
549
+ fi
550
+ else
551
+ echo "No open staging→main PR found. The merged fixes are queued in staging."
552
+ echo "Run /review-pr-staging to open a new train PR when ready."
553
+ fi
554
+ ```
555
+
556
+ **Deploy policy**: Autopilot NEVER merges staging→main. It merges issue fixes TO staging only. The train PR is a human-gated merge — the user decides when to ship.
557
+
487
558
  ---
488
559
 
489
560
  ## Safety Rules
@@ -497,7 +568,7 @@ When ready to deploy, merge `staging` → `main` via GitHub.
497
568
  7. **If a fix fails, move on** — don't retry. Log it and let the next cycle or human handle it.
498
569
  8. **DRY_RUN means NO side effects** — no issues created, no PRs, no label changes. Report only.
499
570
  9. **P0 overrides everything** — if P0 exists, skip normal recon and fix P0 immediately.
500
- 10. **Always gate fixes on user approval** — Phase 4B checkpoint is non-negotiable.
571
+ 10. **Always gate high-risk fixes on user approval** — Phase 4B checkpoint is non-negotiable for P0/P1, multi-file, or sensitive-domain changes. `--yes` only auto-approves LOW_RISK tier (P2/P3, single-file, non-sensitive).
501
572
 
502
573
  ---
503
574
 
@@ -525,4 +596,5 @@ The platform gets better every cycle. Issues that aren't picked up age and rise
525
596
  - **Runtime**: Recon-only ~3-5 min. Full cycle with fixes ~15-45 min depending on issue count.
526
597
  - **Token budget**: Recon is cheap (mostly MCP + API calls). Fixes are expensive (full /work-on per issue).
527
598
  - **Idempotent**: Safe to run multiple times — dedup prevents duplicate issues, /work-on resumes from checkpoints.
528
- - **Pairs with /loop**: Run `/loop 4h /autopilot` for continuous improvement, or `/loop 4h /autopilot --fix --limit 2` for autonomous fixing with a human checkpoint every cycle.
599
+ - **Pairs with /loop**: Run `/loop 4h /autopilot` for continuous improvement, `/loop 4h /autopilot --fix --limit 2` for autonomous fixing with a human checkpoint every cycle, or `/loop 4h /autopilot --fix --yes` for fully unattended low-risk fixes (high-risk issues still surface for approval).
600
+ - **Event-driven complement**: `/autopilot` is a periodic cycle. When a specific production signal fires (metric regression, incident, GEO gap), use `/signal-planner` instead — it converts the signal into a dependency-ordered issue DAG, executes via `/orchestrate`, and verifies the originating signal is resolved after the work merges. Use `/autopilot` for scheduled health sweeps; use `/signal-planner` for targeted signal-driven response.
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Auto-generate release notes from merged PRs and FORGE:TRAJECTORY annotations — grouped by conventional commit type
3
3
  argument-hint: [v1.0.0..v1.1.0 | since:YYYY-MM-DD | last-N]
4
+ install: extras
4
5
  ---
5
6
 
6
7
  # /changelog — Release Notes Generator
@@ -9,7 +10,7 @@ argument-hint: [v1.0.0..v1.1.0 | since:YYYY-MM-DD | last-N]
9
10
 
10
11
  Generate a structured markdown changelog from merged PRs and their FORGE:TRAJECTORY annotations. Groups entries by conventional commit type (feat, fix, refactor, docs, chore) and enriches each entry with task type and investigation verdict from the pipeline's annotation layer.
11
12
 
12
- **Agent model policy**: Default `model: "sonnet"`. Fallback: `model: "opus"` if Sonnet is rate-limited.
13
+ **Agent model policy**: `model: "haiku"`, `effort: low` (mechanical tier — annotation reading, changelog generation). Fallback: `model: "sonnet"` if rate-limited. Feature gate: pass `effort` only on Claude Code >= 2.1.154.
13
14
 
14
15
  **NEVER use plan mode (EnterPlanMode)** — it breaks execution context.
15
16
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Stack-aware CI gap detection — audits a project's GitHub Actions workflows against its declared tech stack and files issues for missing config validation checks
3
3
  argument-hint: [--repo <prefix>] [--dry-run]
4
+ install: extras
4
5
  ---
5
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
7
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -29,7 +30,7 @@ This command is designed to be run:
29
30
 
30
31
  This is NOT a PR review — it does not approve or block. It creates issues for each CI gap found.
31
32
 
32
- **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`.
33
+ **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.
33
34
  **NEVER use plan mode (EnterPlanMode).**
34
35
 
35
36
  ---
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Sweep closed issues for stale labels, missing workflow state, and Project board gaps — plus prune worktrees, branches, and milestones
3
3
  argument-hint: [labels | branches | milestones | board | orphans | all]
4
+ install: extras
4
5
  ---
5
6
  <!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
6
7
  <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
@@ -44,11 +45,12 @@ All `{GH_REPO}`, `{GH_FLAG}`, `{REPO_PATH}`, `{STAGING_BRANCH}`, `{PROJECT_BOARD
44
45
 
45
46
  | Input | Action |
46
47
  |-------|--------|
47
- | `labels` or empty | Fix stale/missing workflow labels on closed issues |
48
+ | `labels` or empty | Fix stale/missing workflow labels on closed issues; detect OPEN issues stuck in intermediate states (Phase 1D) |
48
49
  | `orphans` | Close open issues whose PRs are already merged |
49
50
  | `branches` | Prune worktrees and remote branches for merged PRs |
50
51
  | `milestones` | Report milestones with 0 open issues (advisory — never closes) |
51
52
  | `board` | Sync closed issues to Project board with correct terminal state |
53
+ | `batch-p3` | Sweep: fold stale unbatched P3 review findings into domain-grouped batch issues |
52
54
  | `all` | All of the above, in order |
53
55
 
54
56
  ---
@@ -105,6 +107,46 @@ gh issue list {GH_FLAG} --state closed --limit 200 --json number,title,labels \
105
107
 
106
108
  These were closed outside the pipeline. Report count but don't fix (not necessarily wrong).
107
109
 
110
+ ### 1D: Detect stale OPEN issues in intermediate workflow states
111
+
112
+ Open issues stuck in `workflow:building`, `workflow:in-review`, or `workflow:investigating` beyond a configurable threshold indicate a stalled agent. These are invisible to Phase 1A–1C (which only query closed issues).
113
+
114
+ ```bash
115
+ # Configurable threshold — override by setting STALE_THRESHOLD_HOURS before invoking /cleanup
116
+ STALE_THRESHOLD_HOURS=${STALE_THRESHOLD_HOURS:-48}
117
+
118
+ # Compute cutoff datetime — GNU date (Linux) with BSD date (macOS) fallback
119
+ CUTOFF=$(date -d "${STALE_THRESHOLD_HOURS} hours ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null \
120
+ || date -v-${STALE_THRESHOLD_HOURS}H +%Y-%m-%dT%H:%M:%SZ 2>/dev/null \
121
+ || echo "")
122
+
123
+ echo "=== Stale-Open Intermediate Issues (threshold: ${STALE_THRESHOLD_HOURS}h) ==="
124
+
125
+ STALE_OPEN_COUNT=0
126
+
127
+ for LABEL in "workflow:building" "workflow:in-review" "workflow:investigating"; do
128
+ ISSUES=$(gh issue list {GH_FLAG} \
129
+ --state open \
130
+ --label "$LABEL" \
131
+ --limit 100 \
132
+ --json number,title,updatedAt,labels \
133
+ --jq --arg threshold "$CUTOFF" --arg label "$LABEL" \
134
+ '[.[] | select($threshold == "" or .updatedAt < $threshold)] |
135
+ .[] | "#\(.number) — \(.title[:60]) [label: \($label)] [last update: \(.updatedAt[:10])] → resume: /work-on \(.number)"' \
136
+ 2>/dev/null || echo "")
137
+
138
+ if [ -n "$ISSUES" ]; then
139
+ echo "$ISSUES"
140
+ COUNT=$(echo "$ISSUES" | grep -c '^#' 2>/dev/null || echo 0)
141
+ STALE_OPEN_COUNT=$((STALE_OPEN_COUNT + COUNT))
142
+ fi
143
+ done
144
+
145
+ echo "Total stale-open intermediate issues: $STALE_OPEN_COUNT"
146
+ ```
147
+
148
+ These are **report-only** — no automatic action is taken. Use `/work-on <n>` (idempotent) to resume a stalled issue. Priority issues (P1/P2) should be actioned first.
149
+
108
150
  ---
109
151
 
110
152
  ## Phase 2: Orphaned Issues (open issues with merged PRs)
@@ -278,6 +320,111 @@ Do NOT call `gh api ... -X PATCH -f state=closed` on any milestone. This phase i
278
320
 
279
321
  ---
280
322
 
323
+ ## Phase 4B: P3 Batch Sweep (if `batch-p3` or `all`)
324
+
325
+ <!-- Added: forge#1333 -->
326
+
327
+ **Purpose**: Fold stale unbatched P3 review findings into domain-grouped batch issues. Reduces pipeline overhead from individual per-finding full-pipeline runs.
328
+
329
+ **Skip if**: Input is not `batch-p3` and not `all`.
330
+
331
+ ### Step 4B.1: Fetch open batchable P3 findings
332
+
333
+ ```bash
334
+ # Find all open P3 review findings that carry the FORGE:BATCHABLE annotation
335
+ # and are not already members of a batch (no "batch" label)
336
+ UNBATCHED_P3=$(gh issue list {GH_FLAG} \
337
+ --state open \
338
+ --label "review-finding,priority:P3" \
339
+ --limit 500 \
340
+ --json number,title,body,labels,createdAt \
341
+ --jq '.[] | select(.body | test("<!-- FORGE:BATCHABLE -->"))
342
+ | select(([.labels[].name] | any(. == "batch")) | not)
343
+ | select(([.labels[].name] | any(. == "security" or . == "billing")) | not)
344
+ | select((.title | test("security|billing|payment|stripe"; "i")) | not)')
345
+
346
+ echo "Unbatched batchable P3 findings: $(echo "$UNBATCHED_P3" | jq -s 'length')"
347
+ ```
348
+
349
+ ### Step 4B.2: Group by domain
350
+
351
+ For each finding, extract the domain from the first affected file path under `## Affected Files`:
352
+
353
+ ```bash
354
+ # Domain = top-level directory of the first affected file
355
+ # e.g., "services/api/auth/login.py" → "services/api/auth"
356
+ # "commands/review-pr.md" → "commands"
357
+ # Exclude findings where the domain contains "billing" or "security"
358
+
359
+ # Group findings by domain, track oldest creation timestamp per group
360
+ declare -A DOMAIN_ISSUES
361
+ declare -A DOMAIN_OLDEST
362
+
363
+ echo "$UNBATCHED_P3" | jq -c '.[]' | while read -r issue; do
364
+ NUM=$(echo "$issue" | jq -r '.number')
365
+ CREATED=$(echo "$issue" | jq -r '.createdAt')
366
+ BODY=$(echo "$issue" | jq -r '.body')
367
+
368
+ # Extract first affected file path from body
369
+ FIRST_FILE=$(echo "$BODY" | sed -n '/^## Affected Files/,/^## /p' | grep -oP '`[^`]+`' | head -1 | tr -d '`')
370
+ if [ -z "$FIRST_FILE" ]; then
371
+ FIRST_FILE=$(echo "$BODY" | grep -oP '(?<=\`)[^`]+\.(?:py|ts|tsx|js|go|rs|java|sh|md)(?=\`)' | head -1 || echo "unknown")
372
+ fi
373
+ DOMAIN=$(echo "$FIRST_FILE" | cut -d/ -f1,2,3 | sed 's|/[^/]*$||')
374
+ [ -z "$DOMAIN" ] && DOMAIN="general"
375
+
376
+ echo "${NUM}:${DOMAIN}:${CREATED}"
377
+ done
378
+ ```
379
+
380
+ ### Step 4B.3: Apply batching threshold
381
+
382
+ For each domain group:
383
+ - **Trigger**: 5+ unbatched batchable P3 findings in the domain, **OR** the oldest finding in the domain is > 72 hours old
384
+ - **No trigger**: fewer than 5 findings AND none older than 72 hours → skip (no batch created)
385
+
386
+ ```bash
387
+ NOW_EPOCH=$(date +%s)
388
+ HOURS_72=$((72 * 3600))
389
+
390
+ # For each domain group that meets the threshold, create a batch issue
391
+ # (max 10 members per batch — if more, create multiple batches of ≤ 10 each)
392
+
393
+ # Exclude domains with "security" or "billing" in the domain path
394
+ echo "$DOMAIN_ISSUES" | while IFS=: read -r domain issue_list; do
395
+ echo "$domain" | grep -qiE 'security|billing' && continue
396
+
397
+ COUNT=$(echo "$issue_list" | tr ',' '\n' | wc -l)
398
+ OLDEST_EPOCH=$(echo "$DOMAIN_OLDEST[$domain]" | date -d "$..." +%s 2>/dev/null || echo "$NOW_EPOCH")
399
+ AGE_SECS=$((NOW_EPOCH - OLDEST_EPOCH))
400
+
401
+ if [ "$COUNT" -ge 5 ] || [ "$AGE_SECS" -ge "$HOURS_72" ]; then
402
+ echo "Batching $COUNT P3 findings in domain: ${domain}"
403
+ # Create batch issues (in chunks of ≤ 10)
404
+ # See orchestrate.md Phase 1 for the batch creation template
405
+ fi
406
+ done
407
+ ```
408
+
409
+ **Batch creation** uses the same template as `orchestrate.md Phase 1 → P3 Review-Finding Batching`. After creating the batch issue, add the `batch` label to each member issue to prevent re-batching on the next sweep.
410
+
411
+ ### Step 4B.4: Report
412
+
413
+ ```
414
+ ## P3 Batch Sweep
415
+
416
+ | Domain | Unbatched P3s | Threshold Met | Action |
417
+ |--------|--------------|---------------|--------|
418
+ | {domain} | {N} | ≥5 issues | Created batch #{NUM} ({M} members) |
419
+ | {domain} | {N} | Oldest > 72h | Created batch #{NUM} ({M} members) |
420
+ | {domain} | {N} | Below threshold | No action |
421
+
422
+ Total batch issues created: {N}
423
+ Total P3 findings batched: {N}
424
+ ```
425
+
426
+ ---
427
+
281
428
  ## Phase 5: Sync Project Board (if `board` or `all`)
282
429
 
283
430
  **Skip if `project_board` is not configured** — check resolved vars before proceeding:
@@ -320,6 +467,13 @@ fi
320
467
  | workflow:investigating → cleaned | {N} |
321
468
  | needs-validation removed | {N} |
322
469
 
470
+ ### Stale-Open Intermediate Issues (Phase 1D)
471
+ | Issue | Label | Last Update | Action |
472
+ |-------|-------|-------------|--------|
473
+ | #{N} | workflow:X | YYYY-MM-DD | `/work-on {N}` to resume |
474
+
475
+ *Total stale-open: {N} (threshold: {STALE_THRESHOLD_HOURS}h)*
476
+
323
477
  ### Orphaned Issues Closed
324
478
  | Issue | Merged PR | Action |
325
479
  |-------|-----------|--------|
@@ -345,4 +499,10 @@ fi
345
499
 
346
500
  ### Still Missing Workflow Label
347
501
  {N} closed issues have no workflow label (closed outside pipeline — no action needed)
502
+
503
+ ### P3 Batch Sweep Results
504
+ | Domain | Unbatched P3s | Action |
505
+ |--------|--------------|--------|
506
+ | {domain} | {N} | Created batch #{NUM} with {M} members |
507
+ | {domain} | {N} | Below threshold — no action (< 5 findings, none > 72h) |
348
508
  ```
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: On-demand Claude Code compatibility and feature parity report — compares installed version against the breakpoints registry and lists affected ForgeDock features
3
3
  argument-hint: [--refresh]
4
+ install: extras
4
5
  ---
5
6
 
6
7
  # /compat-audit — Claude Code Compatibility Report
@@ -9,7 +10,7 @@ argument-hint: [--refresh]
9
10
 
10
11
  You are the ForgeDock compatibility auditor. Produce a point-in-time advisory report that shows whether the user's installed Claude Code version is current and which ForgeDock features may behave differently on their runtime. This command is **non-blocking** — it never aborts the session. All output is advisory.
11
12
 
12
- **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`.
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
14
  **NEVER use plan mode (EnterPlanMode).**
14
15
 
15
16
  ---
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Show what will deploy next — diff staging vs main with issue/PR summary, risk assessment, and deploy checklist
3
3
  argument-hint: [staging | milestone/{slug} | compare {branch}]
4
+ install: extras
4
5
  ---
5
6
 
6
7
  # /deploy-info — Pre-Deploy Summary
@@ -15,10 +16,12 @@ argument-hint: [staging | milestone/{slug} | compare {branch}]
15
16
 
16
17
  You are the pipeline's deploy awareness layer. Before the user merges staging → main (triggering CI/CD deployment), this command shows exactly what's going out: which PRs, which issues, what changed, and what risks exist.
17
18
 
18
- **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`. User can override with `--model <name>`.
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
20
 
20
21
  **NEVER use plan mode (EnterPlanMode)** — it breaks execution context.
21
22
 
23
+ <!-- FORGE:SPEC_LOADED — deploy-info.md loaded and active. Agent is bound by this spec. -->
24
+
22
25
  ---
23
26
 
24
27
  ## Phase 0: Review-Finding Readiness Check
@@ -278,6 +281,52 @@ gh workflow run {deploy.workflow} --ref main -f {deploy.workflow_inputs.services
278
281
 
279
282
  ---
280
283
 
284
+ ## Phase 4B: Deploy Train State <!-- Added: forge#1332 -->
285
+
286
+ **Purpose**: Report the current state of the rolling staging→main deploy candidate (the "merge train"). One deploy PR should stay open per deploy cycle — this phase shows whether a candidate exists, what is holding it, and what is queued behind it.
287
+
288
+ ```bash
289
+ git fetch origin {STAGING_BRANCH} {DEFAULT_BRANCH} 2>/dev/null
290
+
291
+ # Step 1: Find the current open staging→main deploy PR (the "train")
292
+ TRAIN_PR=$(gh pr list {GH_FLAG} \
293
+ --head "{STAGING_BRANCH}" \
294
+ --base "{DEFAULT_BRANCH}" \
295
+ --state open \
296
+ --json number,title,headRefOid,createdAt,reviewRequests \
297
+ --jq '.[0] // empty' 2>/dev/null)
298
+
299
+ TRAIN_PR_NUMBER=$(echo "$TRAIN_PR" | jq -r '.number // empty')
300
+ TRAIN_PR_SHA=$(echo "$TRAIN_PR" | jq -r '.headRefOid // empty' | cut -c1-7)
301
+ TRAIN_PR_CREATED=$(echo "$TRAIN_PR" | jq -r '.createdAt // empty')
302
+
303
+ if [ -z "$TRAIN_PR_NUMBER" ]; then
304
+ TRAIN_STATUS="NO_TRAIN — no open staging→main PR. Run /review-pr-staging to open one."
305
+ else
306
+ # Step 2: Check whether the train is held (has blocking findings)
307
+ HELD_BY=$(gh issue list {GH_FLAG} \
308
+ --label "review-finding" \
309
+ --state open \
310
+ --search "PR #${TRAIN_PR_NUMBER}" \
311
+ --limit 20 \
312
+ --json number,title \
313
+ --jq '[.[] | "#\(.number): \(.title)"] | join("\n")' 2>/dev/null || true)
314
+
315
+ if [ -n "$HELD_BY" ]; then
316
+ TRAIN_STATUS="HELD"
317
+ else
318
+ TRAIN_STATUS="CLEAR — ready to merge"
319
+ fi
320
+
321
+ # Step 3: Count commits queued (commits in staging not yet in main)
322
+ QUEUED_COMMITS=$(git rev-list --count origin/{DEFAULT_BRANCH}..origin/{STAGING_BRANCH} 2>/dev/null || echo "?")
323
+ fi
324
+ ```
325
+
326
+ Train state is included in the Phase 5 output summary.
327
+
328
+ ---
329
+
281
330
  ## Phase 5: Output Summary
282
331
 
283
332
  ```
@@ -285,6 +334,14 @@ gh workflow run {deploy.workflow} --ref main -f {deploy.workflow_inputs.services
285
334
 
286
335
  **Commits**: {N} | **PRs**: {N} | **Issues closed**: {N} | **Files changed**: {N}
287
336
 
337
+ ### Deploy Train State
338
+ **Train PR**: #{TRAIN_PR_NUMBER} (SHA: {TRAIN_PR_SHA}, opened: {TRAIN_PR_CREATED})
339
+ **Status**: {TRAIN_STATUS}
340
+ {If HELD: "**Held by**: {count} open finding(s) — fix and push to unblock:\n{HELD_BY}"}
341
+ {If CLEAR: "**Ready to merge**: no open findings on the train PR"}
342
+ {If NO_TRAIN: "No open staging→main PR — run /review-pr-staging to open one"}
343
+ **Queued commits**: {QUEUED_COMMITS} (commits in staging not yet in main)
344
+
288
345
  ### Services Affected
289
346
  | Service | Files Changed | Rebuild Required |
290
347
  |---------|---------------|-----------------|
@@ -22,6 +22,10 @@ live there — this command is the executable workflow over that methodology.
22
22
  **No application runtime.** ForgeDock is a set of command specs. This command is a step-by-step procedure an
23
23
  agent executes; the only executable helper is the deterministic aggregator `scripts/bench-scorecard.mjs`.
24
24
 
25
+ **NEVER use plan mode (EnterPlanMode).**
26
+
27
+ <!-- FORGE:SPEC_LOADED — design-bench.md loaded and active. Agent is bound by this spec. -->
28
+
25
29
  ---
26
30
 
27
31
  ## The three arms (one variable)
@@ -128,7 +132,7 @@ The aggregator (see `scripts/bench-scorecard.mjs`):
128
132
  generated arm is a judge defect, not a harness win — treat those runs as suspect.
129
133
 
130
134
  Post the result as a `FORGE:BENCH_SCORECARD` annotation (registered in
131
- [`docs/FORGE-PROTOCOL.md`](../docs/FORGE-PROTOCOL.md)) on the tracking issue:
135
+ [`docs/spec/forge-protocol-v1.md`](../docs/spec/forge-protocol-v1.md)) on the tracking issue:
132
136
 
133
137
  ```bash
134
138
  gh issue comment <ISSUE> --body "<!-- FORGE:BENCH_SCORECARD -->
@@ -82,7 +82,7 @@ real reference*. They must never be the same judge. This is also distinct from t
82
82
 
83
83
  ## `FORGE:CRITIQUE` annotation
84
84
 
85
- Registered in [FORGE-PROTOCOL](../docs/FORGE-PROTOCOL.md). One per iteration, so the improvement trajectory is an
85
+ Registered in [FORGE Annotation Protocol](../docs/spec/forge-protocol-v1.md). One per iteration, so the improvement trajectory is an
86
86
  auditable artifact:
87
87
 
88
88
  ```markdown
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Trace a failed or stalled pipeline run — identify which FORGE annotation is missing or malformed, diagnose the failure point, and suggest specific remediation steps
3
3
  argument-hint: [issue number] [--repo prefix]
4
+ install: extras
4
5
  ---
5
6
 
6
7
  # /diagnose — Pipeline Failure Tracer
@@ -9,7 +10,7 @@ argument-hint: [issue number] [--repo prefix]
9
10
 
10
11
  **NEVER use plan mode (EnterPlanMode)** — it breaks execution context.
11
12
 
12
- **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`.
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
14
 
14
15
  You are the pipeline's diagnostic layer. Given a single GitHub issue number, you reconstruct the full FORGE annotation chain for that pipeline run, identify the exact failure point, and suggest specific remediation steps. This command is **read-only** — it never mutates GitHub state.
15
16
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Plain-English breakdown of what happened on a GitHub issue — translates FORGE pipeline annotations into a human-readable narrative for teammates and PMs
3
3
  argument-hint: <issue number or PR#N> [--repo prefix]
4
+ install: extras
4
5
  ---
5
6
 
6
7
  # /explain — FORGE Annotation Translator
@@ -9,7 +10,7 @@ argument-hint: <issue number or PR#N> [--repo prefix]
9
10
 
10
11
  You translate the FORGE pipeline's machine-readable annotations on a GitHub issue or PR into a clear, plain-English narrative that anyone can understand — no pipeline knowledge required. This is a read-only command: it never writes to GitHub, never changes labels, and never modifies any state.
11
12
 
12
- **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`.
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
14
  **NEVER use plan mode (EnterPlanMode).**
14
15
 
15
16
  ---