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.
- package/README.md +21 -3
- package/bin/forgedock.mjs +1992 -540
- package/bin/github-app-manifest.json.license +2 -0
- package/bin/hooks/session-start.mjs +4 -5
- package/bin/registry.mjs +20 -0
- package/bin/tui.mjs +172 -96
- package/commands/adopt.md +433 -0
- package/commands/analytics.md +2 -0
- package/commands/audit-agents.md +2 -0
- package/commands/audit.md +2 -0
- package/commands/changelog.md +354 -0
- package/commands/cleanup.md +2 -0
- package/commands/compat-audit.md +330 -0
- package/commands/deploy-info.md +6 -5
- package/commands/diagnose.md +483 -0
- package/commands/explain.md +349 -0
- package/commands/forge-stats.md +2 -0
- package/commands/forgedock-init.md +2 -0
- package/commands/geo-audit.md +2 -0
- package/commands/incident-response.md +2 -0
- package/commands/issue.md +2 -0
- package/commands/milestone.md +2 -0
- package/commands/optimize.md +411 -0
- package/commands/orchestrate.md +118 -0
- package/commands/pipeline-health.md +60 -1
- package/commands/qa-sweep.md +2 -0
- package/commands/quality-gate.md +37 -0
- package/commands/replay.md +263 -0
- package/commands/resume.md +264 -0
- package/commands/review-pr-agents.md +5 -1
- package/commands/review-pr-staging.md +2 -0
- package/commands/review-pr.md +85 -3
- package/commands/rollback.md +2 -0
- package/commands/scope.md +280 -0
- package/commands/security-audit.md +2 -0
- package/commands/status.md +262 -0
- package/commands/sync-ecosystem.md +2 -0
- package/commands/validate.md +2 -0
- package/commands/work-on/build/architect.md +128 -18
- package/commands/work-on/build/context.md +130 -17
- package/commands/work-on/build/implement.md +2 -0
- package/commands/work-on/build/validate.md +2 -0
- package/commands/work-on/build.md +32 -7
- package/commands/work-on/close.md +85 -0
- package/commands/work-on/decompose.md +2 -0
- package/commands/work-on/investigate.md +30 -3
- package/commands/work-on/review.md +13 -1
- package/commands/work-on-monolithic.md +2 -0
- package/commands/work-on.md +624 -36
- package/docs/BRAND.md +51 -0
- package/docs/CONFIG.md +94 -0
- package/docs/articles/per-repo-adaptive-scripts-token-savings.md +174 -0
- package/docs/claude-breakpoints.json +47 -0
- package/docs/site/getting-started.md +21 -0
- package/package.json +3 -3
- package/scripts/classify-lane.sh +145 -0
- package/scripts/transition-label.sh +161 -0
- package/scripts/validate-pr-target.sh +30 -0
- package/templates/devdocs/README.md +72 -0
- package/templates/devdocs/agent/using-forgedock.md +3 -0
- package/templates/devdocs/agent/using-github.md +3 -0
- package/templates/devdocs/index.yaml +162 -0
- package/templates/devdocs/project/architecture.md +3 -0
- package/templates/devdocs/project/conventions.md +3 -0
- package/templates/devdocs/project/custom-instructions.md +3 -0
- package/templates/devdocs/project/glossary.md +3 -0
- package/templates/devdocs/project/stack.md +3 -0
- package/templates/devdocs/templates/commit-convention.md +3 -0
- package/templates/devdocs/templates/issue.md +3 -0
- package/templates/devdocs/templates/pull-request.md +3 -0
- package/templates/devdocs/templates/review-finding.md +3 -0
package/commands/deploy-info.md
CHANGED
|
@@ -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 -
|
|
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 -
|
|
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 -
|
|
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 -
|
|
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 -
|
|
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) |
|