forgedock 1.0.0

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 (44) hide show
  1. package/LICENSE +244 -0
  2. package/README.md +251 -0
  3. package/bin/forgedock.mjs +232 -0
  4. package/commands/analytics.md +777 -0
  5. package/commands/audit-agents.md +410 -0
  6. package/commands/audit.md +410 -0
  7. package/commands/autopilot.md +432 -0
  8. package/commands/cleanup.md +264 -0
  9. package/commands/deploy-info.md +292 -0
  10. package/commands/failure-recon.md +375 -0
  11. package/commands/forge-stats.md +183 -0
  12. package/commands/geo-audit.md +343 -0
  13. package/commands/incident-response.md +384 -0
  14. package/commands/issue.md +506 -0
  15. package/commands/milestone.md +599 -0
  16. package/commands/orchestrate.md +1044 -0
  17. package/commands/pipeline-health.md +2343 -0
  18. package/commands/qa-sweep.md +237 -0
  19. package/commands/quality-gate.md +777 -0
  20. package/commands/review-pr-agents.md +1711 -0
  21. package/commands/review-pr-staging.md +325 -0
  22. package/commands/review-pr.md +888 -0
  23. package/commands/rollback.md +253 -0
  24. package/commands/security-audit.md +529 -0
  25. package/commands/sync-ecosystem.md +527 -0
  26. package/commands/validate.md +131 -0
  27. package/commands/work-on/build/architect.md +291 -0
  28. package/commands/work-on/build/context.md +349 -0
  29. package/commands/work-on/build/implement.md +280 -0
  30. package/commands/work-on/build/validate.md +292 -0
  31. package/commands/work-on/build.md +262 -0
  32. package/commands/work-on/close.md +350 -0
  33. package/commands/work-on/decompose.md +254 -0
  34. package/commands/work-on/investigate.md +437 -0
  35. package/commands/work-on/review.md +245 -0
  36. package/commands/work-on-monolithic.md +298 -0
  37. package/commands/work-on.md +1089 -0
  38. package/docs/CODEX.md +92 -0
  39. package/docs/WORKFLOW.md +104 -0
  40. package/package.json +45 -0
  41. package/scripts/verify-env-vars.sh +201 -0
  42. package/scripts/verify-host-headers.sh +117 -0
  43. package/scripts/verify-route-registration.sh +118 -0
  44. package/scripts/verify-sops-chain.sh +163 -0
@@ -0,0 +1,291 @@
1
+ ---
2
+ description: Pre-implementation architecture planning — traces ALL affected code paths and produces an ordered implementation plan before any code is written
3
+ argument-hint: [issue number] [--repo GH_REPO] [--gh-flag GH_FLAG] [--files AFFECTED_FILES]
4
+ ---
5
+
6
+ # work-on/build/architect — Multi-Path Implementation Planning
7
+
8
+ **Invoked by**: `work-on.md` Step 3C.6, between Context Gathering and Implement.
9
+ **Time budget**: Max 3 minutes. Skip any file read that times out.
10
+ **Output**: Post `<!-- FORGE:ARCHITECT -->` comment on the issue, then return structured plan to caller.
11
+
12
+ ---
13
+
14
+ ## Mission
15
+
16
+ Eliminate cross-path inconsistency bugs before any code is written. The single biggest class of production bugs is a change applied to one code path but not all sibling paths that share the same logic. This agent traces the FULL request/data flow from every entry point, identifies every file that must change, and produces an ordered implementation plan the builder follows exactly.
17
+
18
+ **Principle**: A builder with an explicit plan produces consistent changes. Consistent changes produce zero cross-path review findings.
19
+
20
+ ---
21
+
22
+ ## Inputs
23
+
24
+ Parse from $ARGUMENTS:
25
+ - `{NUMBER}` — issue number (required, positional first arg)
26
+ - `--repo {GH_REPO}` — GitHub repo (e.g. `RapierCraft/AlterLab`)
27
+ - `--gh-flag {GH_FLAG}` — gh CLI repo flag (e.g. `-R RapierCraft/AlterLab`)
28
+ - `--repo-path {REPO_PATH}` — local filesystem path to the worktree (e.g. `/path/to/.claude/worktrees/fix/issue-121`); used by Phase A1 grep commands
29
+ - `--files {AFFECTED_FILES}` — space-separated list of files from investigation report (passed by `build.md` Phase B4)
30
+
31
+ Also read from the calling context (in-memory, passed by parent agent):
32
+ - `{INVESTIGATION_REPORT}` — full text of FORGE:INVESTIGATOR comment
33
+ - `{CONTEXT_BRIEFING}` — full text of FORGE:CONTEXT comment (empty string if context step was skipped)
34
+
35
+ If any of these are not passed directly, read them from GitHub (fallback/recovery path):
36
+
37
+ ```bash
38
+ # Read investigation report
39
+ gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
40
+ --jq '.[] | select(.body | contains("FORGE:INVESTIGATOR")) | .body'
41
+
42
+ # Read context briefing (may be absent — that's OK)
43
+ gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
44
+ --jq '.[] | select(.body | contains("FORGE:CONTEXT")) | .body'
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Resume Check
50
+
51
+ Before doing any work:
52
+
53
+ ```bash
54
+ gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
55
+ --jq '.[] | select(.body | contains("FORGE:ARCHITECT")) | .body'
56
+ ```
57
+
58
+ - If `<!-- FORGE:ARCHITECT -->` comment exists AND `<!-- FORGE:ARCHITECT:COMPLETE -->` is present in the SAME comment → plan already complete, return existing plan to caller, EXIT.
59
+ - If `<!-- FORGE:ARCHITECT -->` comment exists BUT `<!-- FORGE:ARCHITECT:COMPLETE -->` is ABSENT → plan was interrupted, delete the partial comment and restart:
60
+ ```bash
61
+ COMMENT_ID=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
62
+ --jq '.[] | select(.body | contains("FORGE:ARCHITECT")) | .id')
63
+ gh api repos/{GH_REPO}/issues/comments/$COMMENT_ID -X DELETE
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Phase A1: Read Entry Points
69
+
70
+ Identify every entry point that initiates the affected logic. Start from the files named in the investigation report.
71
+
72
+ For each affected file, read it and identify:
73
+ 1. The primary function/method being changed
74
+ 2. All callers of that function (grep for usages)
75
+ 3. All sibling implementations (same interface, different path — e.g. HTTP vs worker vs relay)
76
+
77
+ ```bash
78
+ # Find all callers of the primary function
79
+ grep -r "{PRIMARY_FUNCTION}" {REPO_PATH} \
80
+ --include="*.py" --include="*.ts" --include="*.tsx" \
81
+ -l | grep -v "__pycache__" | grep -v ".pyc"
82
+
83
+ # Find sibling implementations (same base class or interface)
84
+ grep -r "class.*{BASE_CLASS}\|implements.*{INTERFACE}" {REPO_PATH} \
85
+ --include="*.py" --include="*.ts" \
86
+ -l | grep -v "__pycache__"
87
+ ```
88
+
89
+ Read the 3–5 most relevant files identified. Do NOT read more than 8 files total — this is a planning step, not a deep audit.
90
+
91
+ ---
92
+
93
+ ## Phase A2: Trace the Data Flow
94
+
95
+ From each entry point identified in A1, trace what happens to the data being changed:
96
+
97
+ 1. **Entry**: Where does the data first arrive? (API endpoint, queue consumer, webhook handler)
98
+ 2. **Transform**: What functions process it? Which fields are read/written?
99
+ 3. **Persist or relay**: Is it saved to DB? Forwarded to another service? Queued?
100
+ 4. **Exit**: Where does it leave the system? (response body, downstream call, emitted event)
101
+
102
+ For each step in the flow, check:
103
+ - Does the proposed change need to propagate here?
104
+ - Is there a validation or coercion that must be updated consistently?
105
+ - Is there a test that covers this path?
106
+
107
+ Produce a table of ALL files/functions that must change to maintain consistency.
108
+
109
+ ---
110
+
111
+ ## Phase A2.5: Pipeline Phase-Dependency Check
112
+
113
+ **Skip if**: None of the `{AFFECTED_FILES}` are Forge pipeline command files (i.e., no file matches `commands/**/*.md`). When skipped, proceed directly to A3.
114
+
115
+ **Applies when**: The change touches one or more files in `commands/` — these files define the pipeline's phase contracts, and a change to one phase frequently requires coordinated updates to sibling or downstream phases.
116
+
117
+ ### Why This Phase Exists
118
+
119
+ GATE_LOGIC defects (phase-ordering errors, dropped functionality, missing implementations) are the #1 review finding category in the Forge pipeline. They occur when a change is applied to one pipeline phase but the downstream phases that depend on that phase's output contract are not updated. Code-level grep (A1) cannot catch these because pipeline dependencies are expressed in markdown artefact contracts — comment markers, structured output blocks, Skill() invocation signatures, and label state machine transitions — not in code imports.
120
+
121
+ ### Steps
122
+
123
+ **P1: Identify artefact contracts produced by the changed file**
124
+
125
+ For each affected `commands/*.md` file, identify what it produces that other phases consume:
126
+
127
+ 1. **Comment markers** — HTML comment markers the phase writes to GitHub (e.g., `<!-- FORGE:ARCHITECT -->`, `<!-- FORGE:ARCHITECT:COMPLETE -->`). Search for `<!-- FORGE:` patterns in the affected file.
128
+ 2. **Structured output blocks** — named result blocks returned to the caller (e.g., `BUILD_RESULT:`, `VALIDATE_RESULT:`, `IMPLEMENT_RESULT:`). Search for lines ending in `:` that start a return block.
129
+ 3. **Skill() invocation signatures** — parameters the file passes when invoking subcommands (e.g., `Skill("work-on:build:architect", args="... --files ...")`). Search for `Skill(` calls.
130
+ 4. **Label state machine transitions** — `gh issue edit ... --add-label ... --remove-label ...` calls that define which label is set at the end of this phase.
131
+
132
+ **P2: Find downstream phases that consume these artefacts**
133
+
134
+ For each artefact identified in P1:
135
+
136
+ ```bash
137
+ # Find which pipeline files reference this comment marker or output field
138
+ grep -r "{MARKER_OR_FIELD}" /path/to/repo/commands/ \
139
+ --include="*.md" -l | grep -v {AFFECTED_FILE}
140
+
141
+ # Example: if FORGE:ARCHITECT is the marker
142
+ grep -r "FORGE:ARCHITECT" commands/ --include="*.md" -l
143
+ ```
144
+
145
+ For each consumer file found: note the file and the specific phase/section that reads the artefact.
146
+
147
+ **P3: Check for invocation signature changes**
148
+
149
+ If the change modifies what parameters a phase accepts (adds, removes, or renames a `--flag` in its Inputs section), find all callers:
150
+
151
+ ```bash
152
+ grep -r "Skill.*{SUBCOMMAND_NAME}" commands/ --include="*.md" -l
153
+ ```
154
+
155
+ For each caller: verify the invocation still matches the new signature. Flag any caller that passes a parameter that is being renamed or removed.
156
+
157
+ **P4: Emit phase-dependency checklist**
158
+
159
+ For each downstream phase identified in P2 and P3, emit a checklist item. These items are appended to the `### Consistency Checks` section of the `<!-- FORGE:ARCHITECT -->` comment output:
160
+
161
+ ```
162
+ - [ ] {DOWNSTREAM_FILE} Phase {N}: still reads `{ARTEFACT}` correctly after this change
163
+ - [ ] {CALLER_FILE} Phase {N}: invocation of `{SUBCOMMAND}` passes correct params after signature change
164
+ - [ ] Label state: `{LABEL}` set at end of changed phase matches what `{CONSUMER_FILE}` Phase {N} expects as entry condition
165
+ ```
166
+
167
+ If no downstream phases are found (the change is additive only — new sections, new checklist items, no existing contract modified), emit:
168
+ ```
169
+ - [ ] Phase-dependency check: ADDITIVE ONLY — no existing artefact contracts modified; no downstream updates required
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Phase A3: Consistency Rules
175
+
176
+ Identify invariants that ALL affected paths must satisfy. These become the builder's consistency checklist.
177
+
178
+ Common invariants to check:
179
+ - **Null handling**: All paths handle missing field the same way (None vs empty string vs omission)
180
+ - **Validation**: All paths apply the same size/type/format constraints
181
+ - **Logging**: All paths log the same fields at the same level
182
+ - **Error response**: All paths return the same error shape for the same failure mode
183
+ - **Auth check**: All paths enforce the same permission model
184
+
185
+ For each invariant: state the rule and note which files it applies to.
186
+
187
+ ---
188
+
189
+ ## Phase A4: Sequence the Implementation
190
+
191
+ Order the changes to minimize breakage during implementation:
192
+
193
+ 1. **Schema/type changes first** — any shared types, Pydantic models, TypeScript interfaces
194
+ 2. **Core logic** — the primary path (usually the API router or main function)
195
+ 3. **Secondary paths** — worker consumers, relay handlers, batch endpoints
196
+ 4. **Tests** — update or add tests for each changed path
197
+ 5. **Config/env** — any new environment variables or feature flags
198
+
199
+ Rules for ordering:
200
+ - A file that is imported by others must be changed before its importers
201
+ - Tests change last (after the code they test is stable)
202
+ - If two paths are independent, order by risk (higher risk first so review catches it early)
203
+
204
+ ---
205
+
206
+ ## Phase A5: Risk Assessment
207
+
208
+ For each non-obvious interaction or potential failure mode:
209
+ - State the risk in one sentence
210
+ - Rate it: HIGH / MEDIUM / LOW
211
+ - Suggest a mitigation or check
212
+
213
+ Focus on:
214
+ - Files that have changed recently (check `git log --oneline -10 -- {FILE}`)
215
+ - Paths that are called in both sync and async contexts
216
+ - Any place where the change touches a serialization boundary (JSON in/out, DB read/write)
217
+ - Unused or dormant code that the change might activate
218
+
219
+ ---
220
+
221
+ ## Output Format
222
+
223
+ Post the following as a GitHub comment on `{NUMBER}`:
224
+
225
+ ```bash
226
+ gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:ARCHITECT -->
227
+ ## Implementation Plan for #{NUMBER}
228
+
229
+ ### Affected Paths (ALL must be updated)
230
+ | # | File | Function/Class | Change Required | Why |
231
+ |---|------|----------------|-----------------|-----|
232
+ | 1 | {FILE} | {FUNCTION} | {CHANGE} | {REASON} |
233
+
234
+ ### Implementation Order
235
+ 1. {FIRST_CHANGE} — {WHY_FIRST}
236
+ 2. {SECOND_CHANGE} — {WHY_SECOND}
237
+ ...
238
+
239
+ ### Consistency Checks
240
+ <!-- Builder must verify each of these before committing -->
241
+ - [ ] {INVARIANT_1}
242
+ - [ ] {INVARIANT_2}
243
+ - [ ] {INVARIANT_3}
244
+
245
+ ### Risk Assessment
246
+ | Risk | Severity | Mitigation |
247
+ |------|----------|------------|
248
+ | {RISK_DESCRIPTION} | HIGH/MEDIUM/LOW | {MITIGATION} |
249
+
250
+ ### Files to Read Before Coding
251
+ <!-- Builder MUST read these files before writing any code -->
252
+ - \`{FILE}\` — {WHY_READ_IT}
253
+
254
+ <!-- FORGE:ARCHITECT:COMPLETE -->
255
+ "
256
+ ```
257
+
258
+ ---
259
+
260
+ ## Timing Rules
261
+
262
+ - Each file read: skip if the file exceeds 500 lines and only the first 100 lines are needed for structure
263
+ - Each `grep -r` call: timeout after 10s, skip if exceeded
264
+ - Total wall time budget: **3 minutes**. If budget exceeded, post partial results with `<!-- FORGE:ARCHITECT:PARTIAL -->` marker instead of `COMPLETE`.
265
+
266
+ ---
267
+
268
+ ## Skip Conditions
269
+
270
+ Skip this entire step (post nothing, return empty plan to caller) if:
271
+ - Issue creates only **new files** with no callers to find (e.g. a new command file with no existing integration point yet)
272
+ - Issue is a 1-file config or docs edit with no code logic
273
+ - Issue title starts with "docs:" or "chore:"
274
+ - `{AFFECTED_FILES}` is empty
275
+
276
+ When skipped, the builder proceeds with investigation report + context briefing only.
277
+
278
+ ---
279
+
280
+ ## Integration Point in work-on.md
281
+
282
+ This module runs at **Step 3C.6** — after Context Gathering, before Implement:
283
+
284
+ ```
285
+ 3C → Builder Contract posted
286
+ 3C.5 → Context Gathering (FORGE:CONTEXT comment)
287
+ 3C.6 → [THIS MODULE] Architecture Planning (FORGE:ARCHITECT comment)
288
+ 3F → Implement (builder reads plan, implements ALL affected paths)
289
+ ```
290
+
291
+ The builder agent reads the `<!-- FORGE:ARCHITECT -->` comment as its **primary input** before writing any code. The raw issue body is secondary context. If the architect step was skipped, the builder falls back to investigation report + contract.
@@ -0,0 +1,349 @@
1
+ ---
2
+ description: Pre-implementation context gathering — surfaces historical findings, bug patterns, and related code paths before the builder writes any code
3
+ argument-hint: [issue number] [affected_files...] [--functions function_names...]
4
+ ---
5
+
6
+ # work-on/build/context — Pre-Implementation Context Gathering
7
+
8
+ **Invoked by**: `work-on.md` Step 3C.5, between Builder Contract and Implement.
9
+ **Time budget**: Max 2 minutes of queries. Skip any query that times out.
10
+ **Output**: Post `<!-- FORGE:CONTEXT -->` comment on the issue, then return structured briefing to caller.
11
+
12
+ ---
13
+
14
+ ## Mission
15
+
16
+ Surface what went wrong in this area before the builder writes a single line of code. The builder starts with the investigator report and contract — this step adds institutional memory: what did review agents catch last time someone touched these files, what bugs recurred, what other paths must stay consistent. When prior investigation Gists are linked in the issue body, fetch and summarize them so the builder has cross-issue context without manual lookups. When a milestone-level index Gist exists, use it to discover all investigation Gists for the milestone — providing full cross-issue context from a single URL. <!-- Updated: forge#341 -->
17
+
18
+ **Principle**: A builder with context produces fewer review findings. Fewer findings = fewer fix cycles = lower token cost.
19
+
20
+ ---
21
+
22
+ ## Inputs
23
+
24
+ Parse from `$ARGUMENTS`:
25
+ - `{NUMBER}` — issue number (positional, required)
26
+ - `--repo {GH_REPO}` — GitHub repo (e.g. `RapierCraft/AlterLab`)
27
+ - `--gh-flag {GH_FLAG}` — gh CLI repo flag (e.g. `-R RapierCraft/AlterLab`)
28
+ - `--repo-path {REPO_PATH}` — local filesystem path to the worktree (e.g. `/path/to/.claude/worktrees/fix/issue-121`); used by Phase C3 grep commands
29
+ - `{AFFECTED_FILES}` — space-separated file paths (positional, after `{NUMBER}`, before any `--functions` flag)
30
+ - `--functions {FUNCTION_NAMES}` — space-separated function/class names extracted from the Builder Contract deliverables table (optional)
31
+
32
+ **Graceful skip for empty FUNCTION_NAMES**: If `--functions` is absent or `{FUNCTION_NAMES}` is empty, Phase C3 produces zero for-loop iterations and is effectively skipped — no error, no output for that phase. This is expected behavior when the contract does not name specific functions.
33
+
34
+ ---
35
+
36
+ ## Phase C0: Prior Investigation Findings (from Gists)
37
+
38
+ Scan the issue body for `<!-- FORGE:PRIOR_GIST: {url} -->` annotations embedded by the decompose or orchestrate phases (GIST-02). Also check for `<!-- FORGE:MILESTONE_INDEX: {url} -->` annotations — these reference a milestone-level index Gist (GIST-04) that aggregates all investigation Gist URLs for a milestone into a single reference. Both annotation types reference Knowledge Gists created during upstream investigation (GIST-01) and contain structured findings — verdict, root cause, recommendation, affected files — that the builder needs before writing code.
39
+
40
+ **Time budget**: 30 seconds total for all Gist fetches. Each individual fetch times out after 15 seconds.
41
+
42
+ **Skip if**: Issue body contains no `FORGE:PRIOR_GIST` or `FORGE:MILESTONE_INDEX` annotations, AND the issue's milestone description contains no `FORGE:MILESTONE_INDEX` annotation. Zero iterations, no output — this is expected for issues without prior investigation context.
43
+
44
+ ### Step 0: Check for milestone index Gist
45
+
46
+ Before scanning individual Gist annotations, check if the issue's milestone has an index Gist. If so, fetch the index and extract individual Gist URLs from the table rows.
47
+
48
+ ```bash
49
+ ISSUE_BODY=$(gh issue view {NUMBER} -R {GH_REPO} --json body --jq '.body')
50
+ MILESTONE_NUM=$(gh issue view {NUMBER} -R {GH_REPO} --json milestone --jq '.milestone.number // empty')
51
+
52
+ MILESTONE_INDEX_URL=""
53
+ INDEX_GIST_URLS=""
54
+
55
+ # Check issue body for milestone index annotation
56
+ MILESTONE_INDEX_URL=$(echo "$ISSUE_BODY" \
57
+ | grep -oP '(?<=<!-- FORGE:MILESTONE_INDEX: )https://[^ ]+(?= -->)' \
58
+ | head -1)
59
+
60
+ # If not in issue body, check milestone description
61
+ if [ -z "$MILESTONE_INDEX_URL" ] && [ -n "$MILESTONE_NUM" ]; then
62
+ MILESTONE_DESC=$(gh api repos/{GH_REPO}/milestones/${MILESTONE_NUM} --jq '.description // ""' 2>/dev/null)
63
+ MILESTONE_INDEX_URL=$(echo "$MILESTONE_DESC" \
64
+ | grep -oP '(?<=<!-- FORGE:MILESTONE_INDEX: )https://[^ ]+(?= -->)' \
65
+ | head -1)
66
+ fi
67
+
68
+ # If found, fetch the index and extract individual Gist URLs from table rows
69
+ if [ -n "$MILESTONE_INDEX_URL" ]; then
70
+ INDEX_GIST_ID=$(echo "$MILESTONE_INDEX_URL" | grep -oP '[a-f0-9]{20,}' | tail -1)
71
+ if [ -n "$INDEX_GIST_ID" ]; then
72
+ INDEX_CONTENT=$(timeout 15 gh gist view "$INDEX_GIST_ID" --raw 2>/dev/null)
73
+ if [ -n "$INDEX_CONTENT" ]; then
74
+ # Extract Gist URLs from table rows (format: | ... | https://gist.github.com/... | ... |)
75
+ INDEX_GIST_URLS=$(echo "$INDEX_CONTENT" \
76
+ | grep -oP 'https://gist\.github\.com/[a-f0-9/]+' \
77
+ | head -10)
78
+ echo "Milestone index fetched: found $(echo "$INDEX_GIST_URLS" | wc -l) investigation Gist(s)"
79
+ else
80
+ echo "WARNING: Failed to fetch milestone index Gist — falling back to individual annotations"
81
+ fi
82
+ fi
83
+ fi
84
+ ```
85
+
86
+ ### Step 1: Detect Gist URLs in issue body
87
+
88
+ ```bash
89
+ GIST_URLS=$(echo "$ISSUE_BODY" \
90
+ | grep -oP '(?<=<!-- FORGE:PRIOR_GIST: )https://[^ ]+(?= -->)' \
91
+ | head -5)
92
+
93
+ # Merge with any URLs discovered from milestone index (deduplicate)
94
+ if [ -n "$INDEX_GIST_URLS" ]; then
95
+ GIST_URLS=$(echo -e "${GIST_URLS}\n${INDEX_GIST_URLS}" | sort -u | head -5)
96
+ fi
97
+
98
+ if [ -z "$GIST_URLS" ]; then
99
+ echo "No FORGE:PRIOR_GIST or FORGE:MILESTONE_INDEX annotations found — skipping Phase C0"
100
+ # → Continue to Phase C1
101
+ fi
102
+ ```
103
+
104
+ **Max Gists**: 5 per issue. If more than 5 are present (from combined individual + index sources), process only the first 5 to stay within time budget.
105
+
106
+ ### Step 2: Fetch and summarize each Gist
107
+
108
+ For each Gist URL, extract the Gist ID (last path segment) and fetch the raw content:
109
+
110
+ ```bash
111
+ GIST_SUMMARIES=""
112
+
113
+ for url in $GIST_URLS; do
114
+ # Extract Gist ID from URL (last path segment, strip any trailing slash)
115
+ GIST_ID=$(echo "$url" | grep -oP '[a-f0-9]{20,}' | tail -1)
116
+
117
+ if [ -z "$GIST_ID" ]; then
118
+ echo "WARNING: Could not extract Gist ID from URL: $url — skipping"
119
+ continue
120
+ fi
121
+
122
+ # Fetch Gist content with timeout
123
+ GIST_CONTENT=$(timeout 15 gh gist view "$GIST_ID" --raw 2>/dev/null)
124
+
125
+ if [ -z "$GIST_CONTENT" ]; then
126
+ echo "WARNING: Failed to fetch Gist $GIST_ID — skipping (deleted, private, or network error)"
127
+ GIST_SUMMARIES="${GIST_SUMMARIES}
128
+ - **Gist ${GIST_ID}** (${url}): _Fetch failed — Gist may be deleted or inaccessible_"
129
+ continue
130
+ fi
131
+
132
+ # Extract key sections for summary (~2K chars target per Gist)
133
+ VERDICT=$(echo "$GIST_CONTENT" | grep -oP '(?<=verdict: )\w+' | head -1)
134
+ TASK_TYPE=$(echo "$GIST_CONTENT" | grep -oP '(?<=task_type: ).+' | head -1)
135
+ SEVERITY=$(echo "$GIST_CONTENT" | grep -oP '(?<=severity: )\w+' | head -1)
136
+ SOURCE_ISSUE=$(echo "$GIST_CONTENT" | grep -oP '(?<=issue: )\d+' | head -1)
137
+
138
+ # Extract structured sections: Root Cause, Recommendation, Affected Files
139
+ ROOT_CAUSE=$(echo "$GIST_CONTENT" \
140
+ | sed -n '/^### Root Cause/,/^### /p' \
141
+ | head -10 | tail -n +2 | head -8)
142
+ RECOMMENDATION=$(echo "$GIST_CONTENT" \
143
+ | sed -n '/^### Recommendation/,/^### /p' \
144
+ | head -10 | tail -n +2 | head -8)
145
+ AFFECTED_FILES=$(echo "$GIST_CONTENT" \
146
+ | sed -n '/^### Affected Files/,/^### /p' \
147
+ | head -10 | tail -n +2 | head -8)
148
+
149
+ GIST_SUMMARIES="${GIST_SUMMARIES}
150
+
151
+ #### Investigation #${SOURCE_ISSUE:-unknown} (${VERDICT:-unknown} / ${SEVERITY:-unknown})
152
+ **Source**: ${url}
153
+ **Task type**: ${TASK_TYPE:-unknown}
154
+
155
+ **Root Cause**:
156
+ ${ROOT_CAUSE:-_Not extracted — read Gist directly_}
157
+
158
+ **Recommendation**:
159
+ ${RECOMMENDATION:-_Not extracted — read Gist directly_}
160
+
161
+ **Affected Files**:
162
+ ${AFFECTED_FILES:-_Not extracted — read Gist directly_}"
163
+ done
164
+ ```
165
+
166
+ ### Step 3: Store for output
167
+
168
+ If `GIST_SUMMARIES` is non-empty, it will be included in the `### Prior Investigation Findings` section of the FORGE:CONTEXT comment (see Output Format below). If empty (all fetches failed or no annotations found), the section is omitted from the output.
169
+
170
+ ---
171
+
172
+ ## Phase C1: Past Review Findings on These Files
173
+
174
+ Query closed issues with `review-finding` label, searching by filename:
175
+
176
+ ```bash
177
+ for file in {AFFECTED_FILES}; do
178
+ basename=$(basename "$file" .py)
179
+ gh issue list -R {GH_REPO} \
180
+ --state closed \
181
+ --label "review-finding" \
182
+ --search "$basename" \
183
+ --limit 10 \
184
+ --json number,title,body \
185
+ --jq '.[] | {
186
+ number,
187
+ title,
188
+ pattern: (.body | capture("\\*\\*Pattern\\*\\*: *(?<p>[^\\n]+)").p // null),
189
+ prevention: (.body | capture("\\*\\*Prevention\\*\\*: *(?<v>[^\\n]+)").v // null),
190
+ root_cause: (.body | capture("\\*\\*Root cause\\*\\*: *(?<rc>[^\\n]+)").rc // (.body | capture("Root Cause[^\\n]*\\n(?<rc>[^\\n]+)").rc // "see body"))
191
+ }'
192
+ done
193
+ ```
194
+
195
+ Keep findings where the filename or function name appears in the title or body. Discard false matches (same word, different module).
196
+
197
+ **Pattern extraction note**: Issues created by `/review-pr` after the feedback-loop feature include structured `**Pattern**`, `**Root cause**`, and `**Prevention**` fields in the `## Pattern Metadata` section. Extract all three when present — they are the primary signal. Fall back to `root_cause` regex for older issues that predate this feature.
198
+
199
+ **Max results**: 10 findings total across all files.
200
+
201
+ ---
202
+
203
+ ## Phase C2: Past Bugs in the Same Module
204
+
205
+ Mine git log for commit messages referencing issues, then fetch those issues:
206
+
207
+ ```bash
208
+ # Step 1: find issue numbers from git history on affected files
209
+ git log --oneline -30 -- {AFFECTED_FILES} \
210
+ | grep -oP '#\d+' \
211
+ | sort -u \
212
+ | head -8
213
+
214
+ # Step 2: for each issue number found, fetch title and any root cause annotation
215
+ gh issue view {RELATED_NUMBER} -R {GH_REPO} \
216
+ --json number,title,body,labels \
217
+ --jq '{number, title, labels: [.labels[].name], snippet: (.body[:300])}'
218
+ ```
219
+
220
+ Filter: keep only `bug`, `fix`, or `review-finding` labeled issues. Skip feature issues — they add noise without bug signal.
221
+
222
+ **Max results**: 5 issues.
223
+
224
+ ---
225
+
226
+ ## Phase C3: Related Code Paths
227
+
228
+ Identify callers, importers, and sibling implementations that must stay consistent with the changed code:
229
+
230
+ ```bash
231
+ # Python: find importers of modified functions/classes
232
+ for fn in {FUNCTION_NAMES}; do
233
+ grep -r "$fn" {REPO_PATH} \
234
+ --include="*.py" \
235
+ -l \
236
+ | grep -v "__pycache__" \
237
+ | grep -v {AFFECTED_FILES} \
238
+ | head -5
239
+ done
240
+
241
+ # TypeScript: find usages
242
+ for fn in {FUNCTION_NAMES}; do
243
+ grep -r "$fn" {REPO_PATH}/web/src \
244
+ --include="*.ts" --include="*.tsx" \
245
+ -l \
246
+ | head -5
247
+ done
248
+ ```
249
+
250
+ For each related file found: note the file path and the nature of the relationship (caller, sibling, test).
251
+
252
+ **Max results**: 8 related files.
253
+
254
+ ---
255
+
256
+ ## Phase C4: Successful Similar Implementations
257
+
258
+ Find merged PRs that touched the same domain with a successful outcome — use as a positive pattern reference:
259
+
260
+ ```bash
261
+ gh pr list -R {GH_REPO} \
262
+ --state merged \
263
+ --search "{domain_keywords}" \
264
+ --limit 5 \
265
+ --json number,title,files \
266
+ --jq '.[] | {number, title, file_count: (.files | length)}'
267
+ ```
268
+
269
+ Use 2-3 keywords from the issue title. If no results, skip this phase — do not block on it.
270
+
271
+ ---
272
+
273
+ ## Output Format
274
+
275
+ Post the following as a GitHub comment on `{NUMBER}`:
276
+
277
+ ```bash
278
+ gh issue comment {NUMBER} -R {GH_REPO} --body "<!-- FORGE:CONTEXT -->
279
+ ## Implementation Context for #{NUMBER}
280
+
281
+ ### Prior Investigation Findings
282
+ <!-- Summarized Knowledge Gist content from upstream investigations (Phase C0).
283
+ If no FORGE:PRIOR_GIST annotations were found in the issue body: omit this section entirely.
284
+ If Gist fetches failed: include the failure note so the builder knows context was attempted. -->
285
+ {GIST_SUMMARIES}
286
+
287
+ ### Known Pitfalls for This Area
288
+ <!-- Structured prevention rules extracted from past review-finding issues (Pattern Metadata section).
289
+ If a finding has a Prevention field, list it here. Builder MUST read these before writing code.
290
+ If none: 'No structured pitfalls recorded — first time these files are touched or all findings predate the feedback loop.' -->
291
+ - **{PATTERN}** (`{FILE}`): {PREVENTION}
292
+
293
+ ### Historical Findings on These Files
294
+ <!-- List of past review-finding issues from C1. If none: 'No prior findings.' -->
295
+ - #{NUM}: \"{TITLE}\" — root cause: {ROOT_CAUSE}
296
+
297
+ ### Past Bugs in This Module
298
+ <!-- List of closed bug issues from git log mining. If none: 'No prior bugs found in git history.' -->
299
+ - #{NUM}: \"{TITLE}\" — root cause: {SNIPPET}
300
+
301
+ ### Related Code Paths (must stay consistent)
302
+ <!-- Files that import or call the changed functions. Builder must read and validate these. -->
303
+ - \`{FILE}\` — {RELATIONSHIP}
304
+
305
+ ### Patterns That Cause Bugs Here
306
+ <!-- Synthesize from C1+C2: recurring bug types (e.g. 'String/int coercion at JSON boundaries — 3 prior incidents'). If none: 'No recurring patterns identified.' -->
307
+
308
+ ### Successful Similar Implementations
309
+ <!-- Positive patterns from C4. If none: 'No similar merged PRs found.' -->
310
+ - PR #{NUM}: \"{TITLE}\" — {FILE_COUNT} files, notes: {OBSERVATION}
311
+
312
+ <!-- FORGE:CONTEXT:COMPLETE -->
313
+ "
314
+ ```
315
+
316
+ ---
317
+
318
+ ## Timing Rules
319
+
320
+ - Phase C0 `gh gist view` calls: timeout after 15s each, 30s total budget for all Gist fetches
321
+ - Each `gh issue list` call: timeout after 20s, skip if exceeded
322
+ - Each `gh pr list` call: timeout after 20s, skip if exceeded
323
+ - Each `grep -r` call: timeout after 10s, skip if exceeded
324
+ - Total wall time budget: **2 minutes** (C0 through C4 combined). If budget exceeded, post partial results with `<!-- FORGE:CONTEXT:PARTIAL -->` marker instead of `COMPLETE`.
325
+
326
+ ---
327
+
328
+ ## Skip Conditions
329
+
330
+ Skip this entire step (post nothing, return empty briefing) if:
331
+ - Issue is a 1-file config or docs edit with no code logic
332
+ - The affected files have zero git history (new files being created)
333
+ - `{AFFECTED_FILES}` is empty (investigation produced no file list)
334
+
335
+ ---
336
+
337
+ ## Integration Point in work-on.md
338
+
339
+ This module runs at **Step 3C.5** — after Builder Contract is posted, before Implement:
340
+
341
+ ```
342
+ 3C → Builder Contract posted
343
+ 3C.5 → [THIS MODULE] Context gathering (max 2 min)
344
+ 3F → Implement (builder now has context briefing)
345
+ ```
346
+
347
+ The builder agent reads the `<!-- FORGE:CONTEXT -->` comment before writing any code. If the context step was skipped, the builder proceeds with investigation report + contract only.
348
+
349
+ When prior investigation Gists are available (Phase C0), the `### Prior Investigation Findings` section gives the builder cross-issue context — root causes, recommendations, and affected files from upstream investigations — without requiring manual Gist lookups. When a milestone-level index Gist exists (GIST-04), Phase C0 can resolve the index to discover all investigation Gists for the milestone from a single URL — providing full milestone-wide context automatically. <!-- Updated: forge#341 -->