forge-cc 2.0.0 → 2.0.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.
@@ -1,3 +1,23 @@
1
+ ---
2
+ name: forge-build
3
+ hooks:
4
+ WorktreeCreate:
5
+ - hooks:
6
+ - type: command
7
+ command: "node \"$CLAUDE_PROJECT_DIR/node_modules/forge-cc/hooks/linear-worktree-create.js\""
8
+ PreToolUse:
9
+ - matcher: "Bash"
10
+ hooks:
11
+ - type: command
12
+ command: "node \"$CLAUDE_PROJECT_DIR/node_modules/forge-cc/hooks/linear-branch-enforce.js\""
13
+ PostToolUse:
14
+ - matcher: "Bash"
15
+ hooks:
16
+ - type: command
17
+ command: "node \"$CLAUDE_PROJECT_DIR/node_modules/forge-cc/hooks/linear-post-action.js\""
18
+ async: true
19
+ ---
20
+
1
21
  # /forge:build — Graph Execution with Adversarial Review
2
22
 
3
23
  Orchestrates requirement graph execution with worktree isolation, adversarial review, and Linear state transitions. Replaces `/forge:go`.
@@ -59,43 +79,55 @@ options:
59
79
 
60
80
  ### Step 1 — Execution Loop
61
81
 
62
- Execute requirements one at a time in priority order until the graph is complete.
82
+ Execute requirements in parallel waves using `computeWaves()`. Each wave contains requirements whose dependencies are satisfied. Requirements within a wave run in parallel; waves run sequentially.
63
83
 
64
84
  ```
65
- while (!isProjectComplete(index)) {
66
- ready = findReady(index)
67
- if (ready.length === 0) break // all blocked or discovered
68
-
69
- reqId = ready[0] // priority desc → group order → insertion order
70
- result = executeRequirement(index, reqId)
71
-
72
- if (result === "complete") {
73
- updateRequirementStatus(projectDir, slug, reqId, "complete")
74
- syncRequirementDone(client, index, reqId) // Issue → Done
75
- } else if (result === "failed") {
76
- handleFailure(index, reqId, result.errors)
77
- }
78
-
79
- // Reload index — status may have changed, corrections may have been applied
80
- index = loadIndex(projectDir, slug)
81
- }
82
-
83
- syncGraphProjectDone(client, index) // Project → Done if all complete
85
+ waves = computeWaves(index)
86
+
87
+ for each wave in waves:
88
+ // Filter to pending/ready requirements only — skip already-complete ones
89
+ waveReqs = wave.filter(reqId => index.requirements[reqId].status !== "complete")
90
+ if (waveReqs.length === 0) continue // entire wave already complete
91
+
92
+ if (waveReqs.length === 1):
93
+ // Sequential fallback — no team overhead for a single requirement
94
+ reqId = waveReqs[0]
95
+ Spawn a builder agent via Task tool with isolation: "worktree"
96
+ The builder executes Step 2 (build verify → adversarial review)
97
+
98
+ if (result === "complete"):
99
+ updateRequirementStatus(projectDir, slug, reqId, "complete")
100
+ mergeWorktree()
101
+ else if (result === "failed"):
102
+ handleFailure(index, reqId, result.errors) // Step 4
103
+
104
+ else:
105
+ // Parallel execution — spawn agent team for the wave
106
+ Create team via TeamCreate (team_name: "{slug}-wave-{N}")
107
+ For each reqId in waveReqs:
108
+ Create task via TaskCreate (subject: reqId, description: requirement prompt)
109
+ Spawn builder agent via Task tool with:
110
+ - isolation: "worktree"
111
+ - team_name: "{slug}-wave-{N}"
112
+ - The builder executes Step 2 independently
113
+
114
+ Coordinate: wait for all builders to complete
115
+ For each completed requirement:
116
+ updateRequirementStatus(projectDir, slug, reqId, "complete")
117
+ mergeWorktree()
118
+ For each failed requirement:
119
+ handleFailure(index, reqId, result.errors) // Step 4
120
+
121
+ // Between waves — checkpoint:
122
+ Restage all files (git add -A && git reset) // parallel agents disrupt each other's index
123
+ Run npx tsc --noEmit // catch integration issues before next wave
124
+ index = loadIndex(projectDir, slug) // pick up status changes and corrections
125
+ Check for discovered requirements or graph corrections (see Step 5)
84
126
  ```
85
127
 
86
- **Execution order when multiple requirements are ready:**
87
-
88
- `findReady()` may return multiple requirement IDs. Order them by:
89
- 1. Priority descending (P0 before P1 before P2)
90
- 2. Group order (earlier groups first)
91
- 3. Insertion order (lower req number first)
92
-
93
- Execute `ready[0]` sequentially. Future parallel execution will use `computeWaves()`.
128
+ **Wave ordering:** `computeWaves(index)` returns `string[][]` — an array of waves, each wave an array of requirement IDs. Within each wave, requirements have no mutual dependencies and can run in parallel. Waves are ordered so that all dependencies of wave N are in waves 0..N-1.
94
129
 
95
- **Between requirements checkpoint:**
96
- - Re-run `loadIndex()` to pick up any status changes
97
- - Check for discovered requirements or graph corrections (see Step 5)
98
- - Restage all files at wave boundaries — parallel agents can disrupt each other's git index
130
+ **Always delegate to builder agents** for implementation work, even for sequential (single-requirement) waves. The point is preserving the orchestrator's context window, not just parallelism.
99
131
 
100
132
  ---
101
133
 
@@ -250,15 +282,28 @@ options:
250
282
 
251
283
  ---
252
284
 
253
- ### Step 6 — Completion
285
+ ### Step 6 — Ship and Codex Review
254
286
 
255
- When the execution loop ends, determine the final state:
287
+ When the execution loop ends and `isProjectComplete(index)` is true:
256
288
 
257
- **If `isProjectComplete(index)` is true:**
289
+ 1. **Ship the PR:**
290
+ ```bash
291
+ git push -u origin feat/{slug}
292
+ gh pr create --title "{project title}" --body "..."
293
+ ```
294
+ Push the branch and create a PR. The PostToolUse hook automatically links the PR to Linear issues and transitions the project to In Review — no manual `forge linear ship` needed.
258
295
 
259
- ```
260
- syncGraphProjectDone(client, index) // Project → Done in Linear
261
- ```
296
+ 2. **Codex Review:** If a PR was created, follow the **Codex Review Protocol** in `ref/codex-review.md`.
297
+
298
+ **This step is mandatory.** Do not skip to the summary step until the Codex review protocol completes (either comments were resolved or polling timed out with no review found).
299
+
300
+ ---
301
+
302
+ ### Step 7 — Completion
303
+
304
+ Determine the final state:
305
+
306
+ **If all requirements are complete:**
262
307
 
263
308
  Print the completion summary:
264
309
 
@@ -268,7 +313,7 @@ Print the completion summary:
268
313
  **Slug:** {slug}
269
314
  **Requirements completed:** {completed} / {total}
270
315
  **Waves executed:** {count}
271
- **Linear Project:** {project URL} — Done
316
+ **Linear Project:** {project URL} — In Review
272
317
 
273
318
  All requirements verified and merged.
274
319
  ```
@@ -295,16 +340,18 @@ All requirements verified and merged.
295
340
 
296
341
  ## Linear State Reference
297
342
 
298
- State transitions are driven by execution progress:
343
+ All state transitions are handled automatically by hooks and Linear's GitHub integration. No manual sync calls are needed during build execution.
299
344
 
300
- | Item | Transition | When |
301
- |------|-----------|------|
302
- | Issue | Planned → In Progress | Agent starts working on requirement |
303
- | Issue | In Progress Done | Requirement verified + merged |
304
- | Project | Planned → In Progress | First requirement starts |
305
- | Project | In Progress → Done | ALL requirements complete |
345
+ | Item | Transition | Triggered By |
346
+ |------|-----------|-------------|
347
+ | Issue | Planned → In Progress | **WorktreeCreate hook** fires when builder agent worktree is created |
348
+ | Project | Planned → In Progress | **WorktreeCreate hook** first requirement starts |
349
+ | Issue | In Progress → In Review | **Linear GitHub integration** — PR opened from branch containing issue identifier |
350
+ | Project | In Progress → In Review | **PostToolUse hook** fires when `gh pr create` succeeds |
351
+ | Issue | In Review → Completed | **Linear GitHub integration** — PR merged |
352
+ | Project | In Review → Completed | **PostToolUse hook** — fires when `gh pr merge` succeeds |
306
353
 
307
- **If any Linear transition fails:** Log a warning and continue. Never block execution on Linear API failures.
354
+ **If any Linear transition fails:** Hooks log warnings to stderr and continue. Never block execution on Linear API failures.
308
355
 
309
356
  ---
310
357
 
@@ -314,16 +361,17 @@ Keep these limits during execution to preserve the orchestrator's context window
314
361
 
315
362
  | Item | Budget |
316
363
  |------|--------|
317
- | Orchestrator context | Track progress only — delegate all implementation to builder agents |
364
+ | Orchestrator context | Track wave progress only — delegate all implementation to builder agents |
318
365
  | Builder prompt | Target requirement + completed dep artifacts + overview + transitive deps |
319
366
  | Review prompt | Requirement file + actual files on disk — no diffs, no builder summaries |
320
- | Between-requirement checkpoint | Reload index, check discoveries, restage files |
367
+ | Between-wave checkpoint | Restage files, run `tsc --noEmit`, reload index, check discoveries |
321
368
 
322
369
  ---
323
370
 
324
371
  ## Key References
325
372
 
326
373
  - `ref/adversarial-review.md` — Full review protocol (reviewer receives requirement file + actual files on disk, NOT diff/builder summary; stub detection; PASS/FAIL output)
374
+ - `ref/codex-review.md` — Codex auto-review polling, evaluation, and resolution protocol
327
375
  - `ref/graph-correction.md` — Mid-execution correction protocol (discovered reqs, missing edges, file scope, group ordering; checkpoint timing; auto-apply rules)
328
376
  - `ref/requirement-sizing.md` — Sizing rules (hard/soft limits, splitting guide)
329
377
 
@@ -152,13 +152,13 @@ For each project's issues, call `client.createIssueBatch()`:
152
152
  description: "{issue description}",
153
153
  teamId: teamId,
154
154
  projectId: "{project's Linear ID}",
155
- stateId: "{Planned state ID}"
155
+ stateId: "{Backlog state ID}"
156
156
  }
157
157
  ]
158
158
  }
159
159
  ```
160
160
 
161
- To get the "Planned" state ID, look up the team's workflow states and find the one named "Planned". If "Planned" does not exist, fall back to "Backlog".
161
+ To get the "Backlog" state ID, look up the team's workflow states and find the one with category "backlog". If not found, fall back to "Triage".
162
162
 
163
163
  **Error handling:**
164
164
  - If a project creation fails, report it but continue with remaining projects
@@ -183,7 +183,7 @@ Print a summary of everything created:
183
183
  {for each project with issues:}
184
184
  - {project name}: {count} issues
185
185
 
186
- **Linear state:** All projects and issues created at "Planned"
186
+ **Linear state:** All projects and issues created at "Backlog"
187
187
  ```
188
188
 
189
189
  If any items failed, include a failures section:
@@ -198,7 +198,7 @@ If any items failed, include a failures section:
198
198
 
199
199
  | Item | Created State |
200
200
  |---------|--------------|
201
- | Project | Planned |
202
- | Issue | Planned |
201
+ | Project | Backlog |
202
+ | Issue | Backlog |
203
203
 
204
- Do NOT set any item to "In Progress", "Todo", or "Backlog". Everything starts at "Planned" the user promotes items when ready.
204
+ Everything starts at "Backlog" captured ideas haven't been planned yet. The plan skill transitions to "Planned" when requirements are defined.
@@ -160,6 +160,10 @@ Print the current state and preserve the worktree for later:
160
160
  **Remaining issues:** {list}
161
161
  ```
162
162
 
163
+ **Codex Review (if a PR exists for this graph):** After completing the fix, if a PR was previously created via `forge linear ship`, follow the **Codex Review Protocol** in `ref/codex-review.md`.
164
+
165
+ **This step is mandatory.** Do not skip to the resume step until the Codex review protocol completes (either comments were resolved or polling timed out with no review found).
166
+
163
167
  ---
164
168
 
165
169
  ### Step 5 — Resume Build (optional)
@@ -192,6 +196,7 @@ options:
192
196
  ## Key References
193
197
 
194
198
  - `ref/adversarial-review.md` — Full review protocol (reviewer receives requirement file + actual files on disk, NOT diff/builder summary; stub detection; PASS/FAIL output)
199
+ - `ref/codex-review.md` — Codex auto-review polling, evaluation, and resolution protocol
195
200
  - `ref/graph-correction.md` — Mid-execution correction protocol (for context on how graph state evolves)
196
201
 
197
202
  ## Graph Module API
@@ -251,7 +251,7 @@ options:
251
251
 
252
252
  ### Step 6 — Linear Sync
253
253
 
254
- Create the project and issues in Linear.
254
+ Create the project, milestones, and issues in Linear.
255
255
 
256
256
  1. **Load `.forge.json`** to get the `linearTeam` name.
257
257
 
@@ -260,18 +260,30 @@ Create the project and issues in Linear.
260
260
  - Description: content from `overview.md`
261
261
  - State: **Planned**
262
262
 
263
- 3. **Create Linear issues** — one per requirement:
263
+ 3. **Create milestones** — one per group in the graph:
264
+ - For each group in `_index.yaml`, call `ForgeLinearClient.createMilestone({ name: groupName, projectId })`
265
+ - Store the returned `milestoneId` as `linearMilestoneId` in the group's entry in `_index.yaml`
266
+ - Milestone progress auto-calculates in Linear based on child issue completion
267
+
268
+ 4. **Create Linear issues** — one per requirement:
264
269
  - Title: requirement title
265
270
  - Description: requirement body (context + technical approach)
266
271
  - State: **Planned**
267
272
  - Labels: group name
273
+ - `projectMilestoneId`: the group's `linearMilestoneId` from step 3
268
274
 
269
- 4. **Store Linear IDs** back into `_index.yaml`:
275
+ 5. **Store Linear IDs** back into `_index.yaml`:
270
276
  - Project ID at the top level
277
+ - Milestone IDs in each group entry (`linearMilestoneId`)
271
278
  - Issue ID in each requirement entry
272
279
  - Write via `writeIndex()`
273
280
 
274
- 5. **Commit the graph directory** to the current feature branch:
281
+ 6. **Transition project to Planned:**
282
+ ```bash
283
+ npx forge linear sync-planned --slug {slug}
284
+ ```
285
+
286
+ 7. **Commit the graph directory** to the current feature branch:
275
287
 
276
288
  ```bash
277
289
  git add .planning/graph/{slug}/
@@ -121,6 +121,10 @@ options:
121
121
  - Transition the issue to **Done**
122
122
  - Add the commit SHA or PR URL as a comment on the issue
123
123
 
124
+ **Codex Review (if PR was created):** Follow the **Codex Review Protocol** in `ref/codex-review.md`.
125
+
126
+ **This step is mandatory.** Do not skip to the report step until the Codex review protocol completes (either comments were resolved or polling timed out with no review found).
127
+
124
128
  ---
125
129
 
126
130
  ### Step 7 — Report
@@ -0,0 +1,158 @@
1
+ # Codex Review Protocol
2
+
3
+ After a PR is created, poll for Codex auto-review comments, evaluate them, fix valid issues, and return to the user for merge approval.
4
+
5
+ **The agent must NEVER auto-merge a PR.** Always return to the user for merge approval.
6
+
7
+ ---
8
+
9
+ ## Step 1 — Check Prerequisites
10
+
11
+ Before polling, verify:
12
+ - `GITHUB_TOKEN` is set in the environment
13
+ - A PR was actually created in the previous step (you have the PR URL and number)
14
+
15
+ **If `GITHUB_TOKEN` is not set:** Skip this protocol entirely. Print: "Skipping Codex review — GITHUB_TOKEN not set." Proceed to the skill's summary step.
16
+
17
+ Extract the owner, repo, and PR number from the PR URL:
18
+ ```
19
+ # Example: https://github.com/troyhoffman-oss/forge-cc/pull/30
20
+ # owner=troyhoffman-oss, repo=forge-cc, pr=30
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Step 2 — Poll for Review
26
+
27
+ Run the Codex poll CLI command:
28
+
29
+ ```bash
30
+ npx forge codex-poll --owner {owner} --repo {repo} --pr {pr_number}
31
+ ```
32
+
33
+ This polls every 60 seconds for up to 8 minutes. The command outputs JSON:
34
+
35
+ **If Codex review found** (exit code 0):
36
+ ```json
37
+ {
38
+ "found": true,
39
+ "reviews": [{ "id": 123, "state": "commented", "body": "...", "user": "codex-bot" }],
40
+ "comments": [{ "id": 456, "body": "...", "path": "src/foo.ts", "user": "codex-bot" }]
41
+ }
42
+ ```
43
+
44
+ **If no review found** (exit code 1):
45
+ ```json
46
+ {
47
+ "found": false,
48
+ "error": "No Codex review found after 8 minutes"
49
+ }
50
+ ```
51
+
52
+ **If no review found:** This is not a failure. Print: "No Codex review received. Proceeding." Continue to the skill's summary step.
53
+
54
+ ---
55
+
56
+ ## Step 3 — Evaluate Comments
57
+
58
+ For each comment in the poll result, evaluate whether the feedback is valid:
59
+
60
+ 1. **Read the code** at the file path referenced in the comment (`path` field)
61
+ 2. **Understand the suggestion** — what is Codex recommending?
62
+ 3. **Assess validity** using your judgment. Categorize each comment as:
63
+
64
+ | Category | Meaning | Action |
65
+ |----------|---------|--------|
66
+ | **Valid** | The feedback identifies a real issue worth fixing | Fix the code |
67
+ | **Acknowledged** | The feedback is reasonable but a fix isn't appropriate (by design, out of scope, or would introduce other issues) | Reply explaining why |
68
+ | **Dismissed** | The feedback is incorrect or not applicable | Reply explaining why |
69
+
70
+ **Evaluation guidelines:**
71
+ - Security issues are almost always valid
72
+ - Performance suggestions are valid if the impact is meaningful
73
+ - Style preferences that contradict the project's existing conventions should be dismissed
74
+ - Suggestions that would break existing tests or APIs should be carefully evaluated
75
+
76
+ ---
77
+
78
+ ## Step 4 — Fix Valid Issues
79
+
80
+ For each comment categorized as **Valid**:
81
+
82
+ 1. Make the code change in the current branch
83
+ 2. Run verification to ensure the fix doesn't break anything:
84
+ ```bash
85
+ npx forge verify
86
+ ```
87
+ 3. If verification fails, fix the verification issue before proceeding
88
+ 4. Stage and commit the fix:
89
+ ```bash
90
+ git add {changed files}
91
+ git commit -m "Address Codex review: {brief description of fix}"
92
+ ```
93
+
94
+ After all valid fixes are committed:
95
+ ```bash
96
+ git push
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Step 5 — Reply and Resolve
102
+
103
+ For **each** Codex comment, reply on GitHub with what was done:
104
+
105
+ **For valid (fixed) comments:**
106
+ ```bash
107
+ gh api repos/{owner}/{repo}/pulls/{pr}/comments \
108
+ -F body="Fixed — {brief description of what was changed}. {commit SHA}" \
109
+ -F in_reply_to={comment_id}
110
+ ```
111
+
112
+ **For acknowledged comments:**
113
+ ```bash
114
+ gh api repos/{owner}/{repo}/pulls/{pr}/comments \
115
+ -F body="Acknowledged — {reason this wasn't fixed}." \
116
+ -F in_reply_to={comment_id}
117
+ ```
118
+
119
+ **For dismissed comments:**
120
+ ```bash
121
+ gh api repos/{owner}/{repo}/pulls/{pr}/comments \
122
+ -F body="Dismissed — {reason this doesn't apply}." \
123
+ -F in_reply_to={comment_id}
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Step 6 — Return to User
129
+
130
+ After all comments are addressed, present a summary and ask for merge approval:
131
+
132
+ ```
133
+ ## Codex Review Summary
134
+
135
+ **Comments found:** {total count}
136
+ - Fixed: {count}
137
+ - Acknowledged: {count}
138
+ - Dismissed: {count}
139
+
140
+ {For each comment, one line:}
141
+ - [{Valid/Acknowledged/Dismissed}] {file path}: {brief description}
142
+ ```
143
+
144
+ Then ask:
145
+
146
+ <AskUserQuestion>
147
+ question: "Codex review comments have been addressed. Ready to merge?"
148
+ options:
149
+ - "Merge the PR"
150
+ - "I want to review the changes first"
151
+ - "Don't merge — I'll handle it"
152
+ </AskUserQuestion>
153
+
154
+ **If "Merge the PR":** Merge using `gh pr merge {pr_number} --squash --delete-branch`
155
+
156
+ **If "I want to review first":** Print the PR URL and stop. Let the user review manually.
157
+
158
+ **If "Don't merge":** Print the PR URL and stop. Do not merge.