forgedock 1.0.16 → 1.0.17

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 (71) hide show
  1. package/README.md +21 -3
  2. package/bin/forgedock.mjs +1992 -540
  3. package/bin/github-app-manifest.json.license +2 -0
  4. package/bin/hooks/session-start.mjs +4 -5
  5. package/bin/registry.mjs +20 -0
  6. package/bin/tui.mjs +172 -96
  7. package/commands/adopt.md +433 -0
  8. package/commands/analytics.md +2 -0
  9. package/commands/audit-agents.md +2 -0
  10. package/commands/audit.md +2 -0
  11. package/commands/changelog.md +354 -0
  12. package/commands/cleanup.md +2 -0
  13. package/commands/compat-audit.md +330 -0
  14. package/commands/deploy-info.md +6 -5
  15. package/commands/diagnose.md +483 -0
  16. package/commands/explain.md +349 -0
  17. package/commands/forge-stats.md +2 -0
  18. package/commands/forgedock-init.md +2 -0
  19. package/commands/geo-audit.md +2 -0
  20. package/commands/incident-response.md +2 -0
  21. package/commands/issue.md +2 -0
  22. package/commands/milestone.md +2 -0
  23. package/commands/optimize.md +411 -0
  24. package/commands/orchestrate.md +118 -0
  25. package/commands/pipeline-health.md +60 -1
  26. package/commands/qa-sweep.md +2 -0
  27. package/commands/quality-gate.md +37 -0
  28. package/commands/replay.md +263 -0
  29. package/commands/resume.md +264 -0
  30. package/commands/review-pr-agents.md +5 -1
  31. package/commands/review-pr-staging.md +2 -0
  32. package/commands/review-pr.md +85 -3
  33. package/commands/rollback.md +2 -0
  34. package/commands/scope.md +280 -0
  35. package/commands/security-audit.md +2 -0
  36. package/commands/status.md +262 -0
  37. package/commands/sync-ecosystem.md +2 -0
  38. package/commands/validate.md +2 -0
  39. package/commands/work-on/build/architect.md +128 -18
  40. package/commands/work-on/build/context.md +130 -17
  41. package/commands/work-on/build/implement.md +2 -0
  42. package/commands/work-on/build/validate.md +2 -0
  43. package/commands/work-on/build.md +32 -7
  44. package/commands/work-on/close.md +85 -0
  45. package/commands/work-on/decompose.md +2 -0
  46. package/commands/work-on/investigate.md +30 -3
  47. package/commands/work-on/review.md +13 -1
  48. package/commands/work-on-monolithic.md +2 -0
  49. package/commands/work-on.md +624 -36
  50. package/docs/BRAND.md +51 -0
  51. package/docs/CONFIG.md +94 -0
  52. package/docs/articles/per-repo-adaptive-scripts-token-savings.md +174 -0
  53. package/docs/claude-breakpoints.json +47 -0
  54. package/docs/site/getting-started.md +21 -0
  55. package/package.json +3 -3
  56. package/scripts/classify-lane.sh +145 -0
  57. package/scripts/transition-label.sh +161 -0
  58. package/scripts/validate-pr-target.sh +30 -0
  59. package/templates/devdocs/README.md +72 -0
  60. package/templates/devdocs/agent/using-forgedock.md +3 -0
  61. package/templates/devdocs/agent/using-github.md +3 -0
  62. package/templates/devdocs/index.yaml +162 -0
  63. package/templates/devdocs/project/architecture.md +3 -0
  64. package/templates/devdocs/project/conventions.md +3 -0
  65. package/templates/devdocs/project/custom-instructions.md +3 -0
  66. package/templates/devdocs/project/glossary.md +3 -0
  67. package/templates/devdocs/project/stack.md +3 -0
  68. package/templates/devdocs/templates/commit-convention.md +3 -0
  69. package/templates/devdocs/templates/issue.md +3 -0
  70. package/templates/devdocs/templates/pull-request.md +3 -0
  71. package/templates/devdocs/templates/review-finding.md +3 -0
@@ -36,12 +36,13 @@ TARGET=${TARGET_BRANCH:-main}
36
36
 
37
37
  # Step 1: Find all PR numbers in the bundle (same logic as review-pr-staging Phase 0A)
38
38
  BUNDLE_PRS=$(git log origin/$TARGET..origin/$SOURCE --oneline \
39
- | grep -oP '#\d+' \
39
+ | grep -oE '#[0-9]+' \
40
40
  | sort -u \
41
41
  | tr -d '#')
42
42
 
43
43
  MERGE_PRS=$(git log origin/$TARGET..origin/$SOURCE --merges --oneline \
44
- | grep -oP '(?<=pull request #)\d+' \
44
+ | grep -oE 'pull request #[0-9]+' \
45
+ | grep -oE '[0-9]+' \
45
46
  | sort -u)
46
47
 
47
48
  ALL_PR_NUMBERS=$(echo "$BUNDLE_PRS $MERGE_PRS" | tr ' ' '\n' | sort -u | grep -E '^[0-9]+$')
@@ -127,7 +128,7 @@ git log --oneline origin/$TARGET..origin/$SOURCE --format="%h %s" | head -50
127
128
 
128
129
  ```bash
129
130
  # Extract PR numbers from merge commits
130
- PR_NUMBERS=$(git log origin/$TARGET..origin/$SOURCE --merges --format="%s" | grep -oP '#\d+' | sort -u)
131
+ PR_NUMBERS=$(git log origin/$TARGET..origin/$SOURCE --merges --format="%s" | grep -oE '#[0-9]+' | sort -u)
131
132
 
132
133
  # Get PR details
133
134
  for PR in $PR_NUMBERS; do
@@ -142,7 +143,7 @@ done
142
143
  # Extract issue references from PR bodies
143
144
  for PR in $PR_NUMBERS; do
144
145
  NUM=${PR#\#}
145
- CLOSES=$(gh pr view $NUM --json body --jq '.body' 2>/dev/null | grep -oP 'Closes #\K\d+')
146
+ CLOSES=$(gh pr view $NUM --json body --jq '.body' 2>/dev/null | grep -oE 'Closes #[0-9]+' | grep -oE '[0-9]+')
146
147
  for ISSUE in $CLOSES; do
147
148
  gh issue view $ISSUE --json number,title,labels --jq '"\(.number) | \(.title) | \([.labels[].name] | join(","))"' 2>/dev/null
148
149
  done
@@ -225,7 +226,7 @@ if [ -n "$NEW_ENV" ]; then
225
226
  # Cross-check with SOPS chain (only when deploy.secrets_backend == "sops")
226
227
  # If your project uses a different backend, skip this block and verify manually.
227
228
  if [ "{DEPLOY_SECRETS_BACKEND}" = "sops" ]; then
228
- for var in $(echo "$NEW_ENV" | grep -oP '^\+\K[A-Z_]+'); do
229
+ for var in $(echo "$NEW_ENV" | grep -oE '^\+[A-Z_]+' | sed 's/^\+//'); do
229
230
  if ! grep -q "$var" scripts/decrypt-secrets.sh 2>/dev/null; then
230
231
  echo " ❌ $var NOT in decrypt-secrets.sh ENV_MAPPING"
231
232
  fi
@@ -0,0 +1,483 @@
1
+ ---
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
+ argument-hint: [issue number] [--repo prefix]
4
+ ---
5
+
6
+ # /diagnose — Pipeline Failure Tracer
7
+
8
+ **Input**: $ARGUMENTS
9
+
10
+ **NEVER use plan mode (EnterPlanMode)** — it breaks execution context.
11
+
12
+ **Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`.
13
+
14
+ 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
+ ---
17
+
18
+ ## Config Resolution
19
+
20
+ Before executing any phase, read `forge.yaml` to resolve project references:
21
+
22
+ ```bash
23
+ CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"
24
+ if [ -f "$CONFIG_FILE" ]; then
25
+ GH_OWNER=$(yq '.project.owner' "$CONFIG_FILE")
26
+ GH_REPO_NAME=$(yq '.project.repo' "$CONFIG_FILE")
27
+ GH_REPO="${GH_OWNER}/${GH_REPO_NAME}"
28
+ GH_FLAG="-R $GH_REPO"
29
+ REPO_PATH=$(yq '.paths.root' "$CONFIG_FILE")
30
+ # FORGE_REPO: the self-pipeline repo (may differ from GH_REPO for multi-repo setups)
31
+ FORGE_REPO=$(yq '.project.forge_repo // ""' "$CONFIG_FILE")
32
+ [ -z "$FORGE_REPO" ] && FORGE_REPO="$GH_REPO"
33
+ else
34
+ echo "ERROR: forge.yaml not found. Run: npx forgedock init"
35
+ exit 1
36
+ fi
37
+ ```
38
+
39
+ ## Input Parsing
40
+
41
+ Parse `$ARGUMENTS` for:
42
+ - **`{NUMBER}`** — issue number (required). Exit with usage message if absent.
43
+ - **`--repo prefix`** — satellite repo prefix (optional). Look up in `forge.yaml → repos.satellites[]`.
44
+
45
+ ```bash
46
+ NUMBER=$(echo "$ARGUMENTS" | grep -oE '^[0-9]+' | head -1)
47
+ if [ -z "$NUMBER" ]; then
48
+ echo "Usage: /diagnose {issue-number} [--repo prefix]"
49
+ echo "Example: /diagnose 611"
50
+ exit 1
51
+ fi
52
+
53
+ # Optional satellite repo routing
54
+ REPO_PREFIX=$(echo "$ARGUMENTS" | grep -oE -- '--repo [^ ]+' | sed 's/--repo //' | head -1)
55
+ if [ -n "$REPO_PREFIX" ]; then
56
+ SATELLITE_REPO=$(yq ".repos.satellites[] | select(.prefix == \"$REPO_PREFIX\") | .repo" "$CONFIG_FILE" 2>/dev/null)
57
+ if [ -n "$SATELLITE_REPO" ] && [ "$SATELLITE_REPO" != "null" ]; then
58
+ GH_REPO="$SATELLITE_REPO"
59
+ GH_FLAG="-R $GH_REPO"
60
+ echo "Satellite repo: $GH_REPO"
61
+ else
62
+ echo "WARNING: --repo prefix '$REPO_PREFIX' not found in forge.yaml — using default repo"
63
+ fi
64
+ fi
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Phase 1: Load Issue Context
70
+
71
+ ### 1A: Fetch issue
72
+
73
+ ```bash
74
+ ISSUE=$(gh issue view "$NUMBER" $GH_FLAG \
75
+ --json number,title,body,labels,state,comments,milestone,createdAt,closedAt)
76
+
77
+ echo "Issue #$NUMBER: $(echo "$ISSUE" | jq -r '.title')"
78
+ echo "State: $(echo "$ISSUE" | jq -r '.state')"
79
+ echo "Labels: $(echo "$ISSUE" | jq -r '[.labels[].name] | join(", ")')"
80
+ echo "Created: $(echo "$ISSUE" | jq -r '.createdAt')"
81
+ [ "$(echo "$ISSUE" | jq -r '.closedAt')" != "null" ] && \
82
+ echo "Closed: $(echo "$ISSUE" | jq -r '.closedAt')"
83
+ ```
84
+
85
+ ### 1B: Fetch all comments
86
+
87
+ ```bash
88
+ COMMENTS=$(gh api "repos/${GH_REPO}/issues/${NUMBER}/comments" \
89
+ --jq '[.[] | {id: .id, author: .user.login, body: .body, created_at: .created_at}]')
90
+
91
+ COMMENT_COUNT=$(echo "$COMMENTS" | jq 'length')
92
+ echo "Comments found: $COMMENT_COUNT"
93
+ ```
94
+
95
+ ### 1C: Extract workflow labels
96
+
97
+ ```bash
98
+ WORKFLOW_LABELS=$(echo "$ISSUE" | jq -r '[.labels[].name | select(startswith("workflow:"))] | join(", ")')
99
+ echo "Workflow labels: ${WORKFLOW_LABELS:-none}"
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Phase 2: Classify Annotation Chain
105
+
106
+ Walk the comments in creation order and classify each by FORGE marker.
107
+
108
+ **Canonical annotation sequence** (from work-on.md — update this list when work-on.md adds new markers):
109
+
110
+ | Order | Marker | Completion Marker | Phase |
111
+ |-------|--------|-------------------|-------|
112
+ | 1 | `<!-- FORGE:INVESTIGATOR -->` | `<!-- INVESTIGATION:COMPLETE -->` | Phase 1: Investigation |
113
+ | 2 | `<!-- FORGE:CONTRACT -->` | (none — standalone) | Phase 3C: Builder Contract |
114
+ | 3 | `<!-- FORGE:CONTEXT -->` | `<!-- FORGE:CONTEXT:COMPLETE -->` | Phase 3C.5: Context |
115
+ | 4 | `<!-- FORGE:ARCHITECT -->` | `<!-- FORGE:ARCHITECT:COMPLETE -->` | Phase 3C.6: Architecture |
116
+ | 5 | `<!-- FORGE:BUILDER -->` | `<!-- FORGE:BUILDER:COMPLETE -->` | Phase 3M: Implementation |
117
+ | 6 | `<!-- FORGE:REVIEW_STARTED -->` | (none — standalone) | Phase 5B: Review initiated |
118
+ | 7 | `<!-- FORGE:TRAJECTORY -->` | (none — terminal) | Phase 7B: Trajectory log |
119
+
120
+ **Alternative path markers** (indicate non-standard outcomes):
121
+
122
+ | Marker | Meaning |
123
+ |--------|---------|
124
+ | `<!-- FORGE:DECOMPOSED -->` | Issue was decomposed into sub-issues |
125
+ | `<!-- FORGE:DECOMPOSED:COMPLETE -->` | Decomposition completed cleanly |
126
+ | `<!-- FORGE:GATE_FAILED -->` | Quality gate blocked the build |
127
+ | `<!-- FORGE:PUSH_BLOCKED -->` | Branch push was blocked |
128
+ | `<!-- FORGE:ANCESTRY_FAILED -->` | Post-commit ancestry audit failed |
129
+
130
+ **Classify each comment**:
131
+
132
+ ```bash
133
+ # For each comment body, check for FORGE markers and completion markers
134
+ # Build an ordered map: marker → {present: bool, complete: bool, partial: bool, comment_id}
135
+
136
+ FOUND_INVESTIGATOR=false; INVESTIGATOR_COMPLETE=false
137
+ FOUND_CONTRACT=false
138
+ FOUND_CONTEXT=false; CONTEXT_COMPLETE=false; CONTEXT_PARTIAL=false
139
+ FOUND_ARCHITECT=false; ARCHITECT_COMPLETE=false; ARCHITECT_PARTIAL=false
140
+ FOUND_BUILDER=false; BUILDER_COMPLETE=false
141
+ FOUND_REVIEW_STARTED=false
142
+ FOUND_TRAJECTORY=false
143
+ FOUND_DECOMPOSED=false; DECOMPOSED_COMPLETE=false
144
+ FOUND_GATE_FAILED=false
145
+ FOUND_PUSH_BLOCKED=false
146
+ FOUND_ANCESTRY_FAILED=false
147
+
148
+ # Walk comments in order
149
+ echo "$COMMENTS" | jq -c '.[]' | while IFS= read -r comment; do
150
+ BODY=$(echo "$comment" | jq -r '.body')
151
+ COMMENT_ID=$(echo "$comment" | jq -r '.id')
152
+
153
+ echo "$BODY" | grep -q "FORGE:INVESTIGATOR" && FOUND_INVESTIGATOR=true && \
154
+ echo "$BODY" | grep -q "INVESTIGATION:COMPLETE" && INVESTIGATOR_COMPLETE=true
155
+
156
+ echo "$BODY" | grep -q "FORGE:CONTRACT" && FOUND_CONTRACT=true
157
+
158
+ echo "$BODY" | grep -q "FORGE:CONTEXT" && FOUND_CONTEXT=true && \
159
+ echo "$BODY" | grep -q "FORGE:CONTEXT:COMPLETE" && CONTEXT_COMPLETE=true && \
160
+ echo "$BODY" | grep -q "FORGE:CONTEXT:PARTIAL" && CONTEXT_PARTIAL=true
161
+
162
+ echo "$BODY" | grep -q "FORGE:ARCHITECT" && FOUND_ARCHITECT=true && \
163
+ echo "$BODY" | grep -q "FORGE:ARCHITECT:COMPLETE" && ARCHITECT_COMPLETE=true && \
164
+ echo "$BODY" | grep -q "FORGE:ARCHITECT:PARTIAL" && ARCHITECT_PARTIAL=true
165
+
166
+ echo "$BODY" | grep -q "FORGE:BUILDER" && FOUND_BUILDER=true && \
167
+ echo "$BODY" | grep -q "FORGE:BUILDER:COMPLETE" && BUILDER_COMPLETE=true
168
+
169
+ echo "$BODY" | grep -q "FORGE:REVIEW_STARTED" && FOUND_REVIEW_STARTED=true
170
+ echo "$BODY" | grep -q "FORGE:TRAJECTORY" && FOUND_TRAJECTORY=true
171
+ echo "$BODY" | grep -q "FORGE:DECOMPOSED" && FOUND_DECOMPOSED=true && \
172
+ echo "$BODY" | grep -q "FORGE:DECOMPOSED:COMPLETE" && DECOMPOSED_COMPLETE=true
173
+
174
+ echo "$BODY" | grep -q "FORGE:GATE_FAILED" && FOUND_GATE_FAILED=true
175
+ echo "$BODY" | grep -q "FORGE:PUSH_BLOCKED" && FOUND_PUSH_BLOCKED=true
176
+ echo "$BODY" | grep -q "FORGE:ANCESTRY_FAILED" && FOUND_ANCESTRY_FAILED=true
177
+ done
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Phase 3: Discover Associated PR
183
+
184
+ ```bash
185
+ # Find PRs that reference this issue number in their body
186
+ PR_LIST=$(gh pr list $GH_FLAG --state all --limit 50 \
187
+ --json number,title,state,body,headRefName,baseRefName,mergedAt \
188
+ --jq "[.[] | select(.body | test(\"(#|Closes )${NUMBER}([^0-9]|$)\"))]")
189
+
190
+ PR_COUNT=$(echo "$PR_LIST" | jq 'length')
191
+
192
+ if [ "$PR_COUNT" -gt 0 ]; then
193
+ PR_NUMBER=$(echo "$PR_LIST" | jq -r '.[0].number')
194
+ PR_STATE=$(echo "$PR_LIST" | jq -r '.[0].state')
195
+ PR_MERGED=$(echo "$PR_LIST" | jq -r '.[0].mergedAt // "not merged"')
196
+ PR_BRANCH=$(echo "$PR_LIST" | jq -r '.[0].headRefName')
197
+ PR_BASE=$(echo "$PR_LIST" | jq -r '.[0].baseRefName')
198
+ echo "Associated PR: #$PR_NUMBER ($PR_STATE) on branch $PR_BRANCH → $PR_BASE"
199
+ echo "Merged: $PR_MERGED"
200
+
201
+ # Fetch PR comments and reviews for FORGE:REVIEWER
202
+ PR_REVIEWS=$(gh pr view "$PR_NUMBER" $GH_FLAG --json reviews,comments \
203
+ --jq '([.reviews[].body // ""] + [.comments[].body // ""]) |
204
+ map(select(test("FORGE:REVIEWER|APPROVED:|CHANGES REQUESTED:"; "i")))')
205
+ REVIEW_PRESENT=$(echo "$PR_REVIEWS" | jq 'length > 0')
206
+ else
207
+ echo "No PR associated with issue #$NUMBER"
208
+ PR_NUMBER=""
209
+ PR_STATE="none"
210
+ PR_MERGED="none"
211
+ REVIEW_PRESENT=false
212
+ fi
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Phase 4: Diagnose Failure Point
218
+
219
+ Walk the expected annotation sequence in order and identify the first gap or incomplete marker.
220
+
221
+ **Failure classification logic** (evaluate in this exact order — first match wins):
222
+
223
+ ### F0: Issue already in terminal state
224
+
225
+ ```
226
+ IF issue state == CLOSED AND workflow:merged label present:
227
+ → DIAGNOSIS: Pipeline completed successfully.
228
+ FORGE:TRAJECTORY should be present. If absent: see F8.
229
+ → REMEDIATION: None needed. Run /audit if the outcome was wrong.
230
+ ```
231
+
232
+ ### F1: Investigation interrupted
233
+
234
+ ```
235
+ IF FORGE:INVESTIGATOR present AND INVESTIGATION:COMPLETE absent:
236
+ → DIAGNOSIS: Investigation started but was interrupted before completion.
237
+ The pipeline will re-detect this and restart investigation on next /work-on run.
238
+ → REMEDIATION:
239
+ 1. Delete the incomplete investigator comment (find its ID from the comments list above)
240
+ gh api repos/{GH_REPO}/issues/comments/{COMMENT_ID} -X DELETE
241
+ 2. Re-run: /work-on {NUMBER}
242
+ ```
243
+
244
+ ### F2: Investigation never started
245
+
246
+ ```
247
+ IF FORGE:INVESTIGATOR absent AND issue state == OPEN:
248
+ → DIAGNOSIS: Pipeline has not started on this issue.
249
+ → REMEDIATION: /work-on {NUMBER}
250
+ ```
251
+
252
+ ### F3: Build never started (stuck at ready-to-build)
253
+
254
+ ```
255
+ IF INVESTIGATION:COMPLETE present
256
+ AND FORGE:CONTRACT absent
257
+ AND workflow:ready-to-build label present:
258
+ → DIAGNOSIS: Investigation completed but build phase never started.
259
+ Issue is queued but no agent picked it up.
260
+ → REMEDIATION: /work-on {NUMBER}
261
+ (work-on will detect the ready-to-build label and jump to Phase 3)
262
+ ```
263
+
264
+ ### F4: Build interrupted at contract phase
265
+
266
+ ```
267
+ IF INVESTIGATION:COMPLETE present
268
+ AND FORGE:CONTRACT absent
269
+ AND workflow:building label present:
270
+ → DIAGNOSIS: Build phase started (building label set) but builder contract was never posted.
271
+ Agent likely crashed or was interrupted during Phase 3C.
272
+ → REMEDIATION:
273
+ 1. Remove stale label: gh issue edit {NUMBER} $GH_FLAG --remove-label "workflow:building" --add-label "workflow:ready-to-build"
274
+ 2. Re-run: /work-on {NUMBER}
275
+ ```
276
+
277
+ ### F5: Context or architect phases incomplete
278
+
279
+ ```
280
+ IF FORGE:CONTRACT present AND FORGE:BUILDER absent:
281
+ → Check context and architect status:
282
+
283
+ CONTEXT PARTIAL (timed out):
284
+ IF FORGE:CONTEXT present AND FORGE:CONTEXT:COMPLETE absent:
285
+ → NOTE: Context gathering hit the 2-minute budget. Build will continue with partial context.
286
+ This is a warning, not a hard failure. If the build completed, this is expected.
287
+ If build stalled: re-run /work-on {NUMBER}
288
+
289
+ ARCHITECT PARTIAL (budget exceeded):
290
+ IF FORGE:ARCHITECT present AND FORGE:ARCHITECT:COMPLETE absent:
291
+ → NOTE: Architecture plan hit the 3-minute budget. Build continues with partial plan.
292
+ If build stalled: re-run /work-on {NUMBER}
293
+
294
+ BUILD STALLED (contract posted, no builder):
295
+ IF FORGE:CONTEXT:COMPLETE present AND FORGE:ARCHITECT:COMPLETE present AND FORGE:BUILDER absent:
296
+ → DIAGNOSIS: All pre-build phases completed but implementation never ran.
297
+ Agent was interrupted between Phase 3C.6 and Phase 3F.
298
+ → REMEDIATION: /work-on {NUMBER}
299
+ (work-on reads FORGE:BUILDER absence and resumes from implementation)
300
+
301
+ NEEDS-HUMAN (contract posted, needs-human label set):
302
+ IF needs-human label present:
303
+ → DIAGNOSIS: Builder encountered an unresolvable blocker and flagged for human intervention.
304
+ Read the most recent comment on the issue for the specific blocker details.
305
+ → REMEDIATION: Read the blocker comment, resolve manually, then remove the needs-human label
306
+ and run: /work-on {NUMBER}
307
+ ```
308
+
309
+ ### F6: Quality gate or push blocked
310
+
311
+ ```
312
+ IF FORGE:GATE_FAILED present:
313
+ → DIAGNOSIS: Quality gate failed after 3 iterations. Implementation has unresolved HIGH/MEDIUM findings.
314
+ → REMEDIATION:
315
+ 1. Read the FORGE:GATE_FAILED comment for the specific findings
316
+ 2. Fix the issues in the worktree branch
317
+ 3. Re-run quality gate: /quality-gate {FILES} --worktree {WORKTREE_PATH}
318
+ 4. When passing: git push and create PR manually, or re-run /work-on {NUMBER}
319
+
320
+ IF FORGE:PUSH_BLOCKED present:
321
+ → DIAGNOSIS: Branch push was blocked (force-push rejected or remote conflict).
322
+ → REMEDIATION:
323
+ 1. Read the FORGE:PUSH_BLOCKED comment for details
324
+ 2. Resolve the conflict or branch issue manually
325
+ 3. Re-run: /work-on {NUMBER}
326
+
327
+ IF FORGE:ANCESTRY_FAILED present:
328
+ → DIAGNOSIS: Post-commit ancestry audit found merge commits in the PR branch.
329
+ This indicates a git merge was used instead of rebase/cherry-pick.
330
+ → REMEDIATION:
331
+ 1. Rebase the branch onto origin/{base_branch}: git rebase origin/{base_branch} {branch}
332
+ 2. Force-push: git push --force-with-lease
333
+ 3. Re-run: /work-on {NUMBER}
334
+ ```
335
+
336
+ ### F7: Build complete but no PR
337
+
338
+ ```
339
+ IF FORGE:BUILDER:COMPLETE present AND no PR found:
340
+ → DIAGNOSIS: Implementation committed to branch but PR was never created.
341
+ Agent was interrupted between Phase 3M and Phase 4.
342
+ → REMEDIATION: /work-on {NUMBER}
343
+ (work-on detects FORGE:BUILDER without a PR and proceeds to Phase 4)
344
+
345
+ IF FORGE:BUILDER:COMPLETE present AND PR exists AND PR state == OPEN:
346
+ → DIAGNOSIS: PR was created but review was never started.
347
+ → REMEDIATION: /work-on {NUMBER}
348
+ (work-on detects open PR + workflow:in-review and proceeds to Phase 5)
349
+ ```
350
+
351
+ ### F8: Review incomplete or PR not merged
352
+
353
+ ```
354
+ IF FORGE:REVIEW_STARTED present AND PR state != MERGED:
355
+ → DIAGNOSIS: Review was initiated but the PR was not merged.
356
+ → Check PR state:
357
+ - CLOSED (not merged): PR was closed without merging. Re-open or create a new PR.
358
+ - OPEN: Review agent ran but did not auto-merge. Check for merge conflicts or blocking reviews.
359
+ → REMEDIATION:
360
+ - Merge conflicts: resolve manually on the branch, then:
361
+ gh pr merge {PR_NUMBER} $GH_FLAG --merge
362
+ - Auto-merge failure: gh pr merge {PR_NUMBER} $GH_FLAG --merge
363
+ - If PR was closed: re-run /work-on {NUMBER} to create a fresh PR
364
+
365
+ IF FORGE:REVIEW_STARTED present AND PR state == MERGED AND FORGE:TRAJECTORY absent:
366
+ → DIAGNOSIS: PR merged but pipeline close phase (Phase 6-7) did not complete.
367
+ Issue may still be open and labels may not be updated.
368
+ → REMEDIATION: Re-run /work-on {NUMBER}
369
+ (work-on detects merged PR + open issue and runs Phase 6 close & cleanup)
370
+ ```
371
+
372
+ ### F9: Decomposition path issues
373
+
374
+ ```
375
+ IF FORGE:DECOMPOSED present AND FORGE:DECOMPOSED:COMPLETE absent:
376
+ → DIAGNOSIS: Decomposition started but sub-issues were not fully created.
377
+ → REMEDIATION: Re-run /work-on {NUMBER}
378
+
379
+ IF FORGE:DECOMPOSED:COMPLETE present AND workflow:decomposed label absent:
380
+ → DIAGNOSIS: Decomposition completed but label was not updated (minor state drift).
381
+ → REMEDIATION:
382
+ gh issue edit {NUMBER} $GH_FLAG --add-label "workflow:decomposed"
383
+ ```
384
+
385
+ ---
386
+
387
+ ## Phase 5: Label Cross-Reference
388
+
389
+ Validate that workflow labels are consistent with annotation presence. Mismatches indicate a crash mid-phase.
390
+
391
+ ```
392
+ Expected label states:
393
+ - workflow:investigating → FORGE:INVESTIGATOR present but INVESTIGATION:COMPLETE absent
394
+ - workflow:ready-to-build → INVESTIGATION:COMPLETE present, FORGE:CONTRACT absent
395
+ - workflow:building → FORGE:CONTRACT present, FORGE:BUILDER absent
396
+ - workflow:in-review → FORGE:BUILDER:COMPLETE present, FORGE:TRAJECTORY absent
397
+ - workflow:merged → FORGE:TRAJECTORY present, issue closed
398
+ - workflow:invalid → issue closed as invalid (no pipeline annotations expected)
399
+ - workflow:decomposed → FORGE:DECOMPOSED:COMPLETE present
400
+ ```
401
+
402
+ Report any inconsistency between actual labels and expected labels given annotation state. Inconsistencies are not always blockers — they're diagnostic signals.
403
+
404
+ ---
405
+
406
+ ## Phase 6: Output Diagnosis Report
407
+
408
+ Produce a structured, human-readable report. Present it directly — do NOT post it as a GitHub comment (this command is read-only).
409
+
410
+ ```
411
+ ╔══════════════════════════════════════════════════════════════╗
412
+ ║ DIAGNOSIS: Issue #{NUMBER} — {TITLE}
413
+ ╚══════════════════════════════════════════════════════════════╝
414
+
415
+ State: {OPEN|CLOSED}
416
+ Labels: {WORKFLOW_LABELS}
417
+ PR: {#PR_NUMBER (STATE) | none found}
418
+
419
+ ── Annotation Chain ──────────────────────────────────────────
420
+
421
+ Phase 1 — Investigation
422
+ ├── FORGE:INVESTIGATOR {✅ present | ❌ missing}
423
+ └── INVESTIGATION:COMPLETE {✅ complete | ⚠ interrupted | ❌ missing}
424
+
425
+ Phase 3C — Builder Contract
426
+ └── FORGE:CONTRACT {✅ present | ❌ missing}
427
+
428
+ Phase 3C.5 — Context
429
+ ├── FORGE:CONTEXT {✅ present | ❌ missing}
430
+ └── FORGE:CONTEXT:COMPLETE {✅ complete | ⚠ partial (timed out) | ❌ missing}
431
+
432
+ Phase 3C.6 — Architecture
433
+ ├── FORGE:ARCHITECT {✅ present | ❌ missing}
434
+ └── FORGE:ARCHITECT:COMPLETE {✅ complete | ⚠ partial (budget exceeded) | ❌ missing}
435
+
436
+ Phase 3M — Build
437
+ ├── FORGE:BUILDER {✅ present | ❌ missing}
438
+ └── FORGE:BUILDER:COMPLETE {✅ complete | ⚠ incomplete | ❌ missing}
439
+
440
+ Phase 5 — Review
441
+ ├── FORGE:REVIEW_STARTED {✅ present | ❌ missing}
442
+ └── FORGE:REVIEWER (PR) {✅ present | ⚠ no review found | ❌ no PR}
443
+
444
+ Phase 7 — Trajectory
445
+ └── FORGE:TRAJECTORY {✅ present | ❌ missing}
446
+
447
+ Alternative paths
448
+ ├── FORGE:DECOMPOSED {present | absent}
449
+ ├── FORGE:GATE_FAILED {present | absent}
450
+ ├── FORGE:PUSH_BLOCKED {present | absent}
451
+ └── FORGE:ANCESTRY_FAILED {present | absent}
452
+
453
+ ── Label Consistency ─────────────────────────────────────────
454
+
455
+ {For each label, state whether it's consistent with annotation chain}
456
+ {Flag any inconsistencies with ⚠}
457
+
458
+ ── Failure Diagnosis ─────────────────────────────────────────
459
+
460
+ FAILURE POINT: {F0–F9 class above | "No failure detected — pipeline complete"}
461
+ FAILURE DESCRIPTION: {One clear sentence explaining what failed and why}
462
+
463
+ ── Remediation ───────────────────────────────────────────────
464
+
465
+ {Exact commands to resume the pipeline from the failure point}
466
+ {If needs-human: specific action required and why}
467
+
468
+ ── Notes ─────────────────────────────────────────────────────
469
+
470
+ {Any additional context: partial annotations, decomposition sub-issues, etc.}
471
+ ```
472
+
473
+ ---
474
+
475
+ ## Related Commands
476
+
477
+ | Command | When to use it instead |
478
+ |---------|------------------------|
479
+ | `/work-on {NUMBER}` | Resume a stalled pipeline run (most remediations above) |
480
+ | `/audit` | Trace a pipeline failure that produced wrong output (not a stall) |
481
+ | `/pipeline-health` | Aggregate health metrics across all recent pipeline runs |
482
+ | `/cleanup` | Fix stale labels and orphaned issues at scale (not single-issue diagnosis) |
483
+ | `/incident-response` | P0 production incidents (not pipeline stalls) |