@izkac/forgekit 0.3.11 → 0.3.13
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/bin/forge.mjs +107 -107
- package/bin/forgekit.mjs +83 -83
- package/bin/review.mjs +81 -81
- package/package.json +1 -1
- package/scripts/prepack.mjs +78 -78
- package/scripts/run-tests.mjs +50 -50
- package/src/adr.mjs +236 -236
- package/src/adr.test.mjs +170 -170
- package/src/change.mjs +327 -234
- package/src/change.test.mjs +145 -83
- package/src/cleanup-sessions.mjs +84 -84
- package/src/config.mjs +103 -103
- package/src/defer.mjs +75 -75
- package/src/doctor.mjs +350 -341
- package/src/doctor.test.mjs +114 -114
- package/src/init.mjs +680 -621
- package/src/install.mjs +815 -815
- package/src/install.test.mjs +180 -180
- package/src/integrity-check.mjs +60 -60
- package/src/integrity.mjs +682 -682
- package/src/integrity.test.mjs +566 -566
- package/src/lib.mjs +143 -143
- package/src/models.defaults.json +41 -41
- package/src/new-session.mjs +99 -99
- package/src/openspec-overlays/README.md +19 -19
- package/src/openspec-overlays/openspec-apply-change-footer.md +14 -14
- package/src/openspec-overlays/opsx-apply-completion-step.md +1 -1
- package/src/openspec-overlays/opsx-apply-implement-step.md +11 -11
- package/src/paths.mjs +92 -92
- package/src/plan-engine.mjs +321 -278
- package/src/plan-engine.test.mjs +447 -283
- package/src/preferences.defaults.json +78 -78
- package/src/preferences.mjs +438 -438
- package/src/preferences.test.mjs +174 -174
- package/src/record-evidence.mjs +204 -204
- package/src/resolve-model.mjs +312 -312
- package/src/resolve-model.test.mjs +194 -194
- package/src/review/cli.test.mjs +117 -117
- package/src/review/export.mjs +172 -172
- package/src/review/export.test.mjs +197 -197
- package/src/review/fixtures/valid-review.json +42 -42
- package/src/review/lib.mjs +894 -894
- package/src/review/lib.test.mjs +266 -266
- package/src/review/schema.json +196 -196
- package/src/review/signals.test.mjs +62 -62
- package/src/score-cli.mjs +68 -68
- package/src/score.mjs +568 -566
- package/src/score.test.mjs +366 -340
- package/src/session-reminder.mjs +207 -207
- package/src/session-status.mjs +70 -70
- package/src/set-models.mjs +186 -186
- package/src/set-phase.mjs +205 -205
- package/src/set-prefs.mjs +294 -294
- package/src/specs-sync.mjs +234 -0
- package/src/specs-sync.test.mjs +114 -0
- package/src/spine.mjs +93 -93
- package/src/triage-prompt.mjs +175 -175
- package/src/triage-prompt.test.mjs +50 -50
- package/src/vendor-openspec-overlays.mjs +176 -176
- package/src/vendor-openspec-overlays.test.mjs +62 -62
- package/vendor/skills/archive-to-adr/SKILL.md +149 -149
- package/vendor/skills/forge/SKILL.md +136 -136
- package/vendor/skills/forge/docs/forge.md +650 -647
- package/vendor/skills/forge/phases/brainstorm.md +23 -23
- package/vendor/skills/forge/phases/finish.md +90 -87
- package/vendor/skills/forge/phases/implement.md +77 -77
- package/vendor/skills/forge/phases/plan-openspec.md +60 -60
- package/vendor/skills/forge/phases/plan-specs.md +163 -117
- package/vendor/skills/forge/phases/review.md +25 -25
- package/vendor/skills/forge/phases/verify.md +124 -124
- package/vendor/skills/forge/references/forge-layout.md +85 -85
- package/vendor/skills/forge/references/pace.md +115 -115
- package/vendor/skills/forge/references/plan-routing.md +52 -51
- package/vendor/skills/forge/references/runtime-integrity.md +232 -225
- package/vendor/skills/forge/references/substantial-work.md +37 -37
- package/vendor/skills/forge/references/test-evidence.md +30 -30
- package/vendor/skills/forge/references/test-strategy.md +68 -68
- package/vendor/skills/forge/skills/subagent-driven-development/SKILL.md +87 -87
- package/vendor/skills/forge/subagents/final-reviewer-prompt.md +56 -56
- package/vendor/skills/forge/subagents/implementer-prompt.md +38 -38
- package/vendor/skills/git-resolve-adr-conflict/SKILL.md +132 -132
- package/vendor/skills/thorough-code-review/SKILL.md +290 -290
- package/vendor/skills/thorough-code-review/examples.md +133 -133
- package/vendor/skills/thorough-code-review/reference/accepted-risks.md +26 -26
- package/vendor/skills/thorough-code-review/reference/lenses.md +96 -96
- package/vendor/skills/thorough-code-review/reference/phase1-scout.md +62 -62
- package/vendor/skills/thorough-code-review/reference/phase2-skeptic.md +105 -105
- package/vendor/skills/thorough-code-review/reference/report-schema.json +222 -222
- package/vendor/skills/thorough-code-review/reference/report-template.md +115 -115
- package/vendor/skills/thorough-code-review/reference/severity-rubric.md +49 -49
- package/vendor/skills/thorough-code-review/reference/signals-preflight.md +55 -55
- package/vendor/templates/adr/README.md +7 -7
- package/vendor/templates/adr/decisions.md +141 -141
- package/vendor/templates/adr/hooks/check-pending-adrs.mjs +74 -74
- package/vendor/templates/adr/hooks/check-pending-adrs.sh +3 -3
- package/vendor/templates/adr/hooks/openspec-archive-agent-message.mjs +52 -52
- package/vendor/templates/adr/hooks/openspec-archive-agent-message.sh +3 -3
- package/vendor/templates/project/claude/commands/forge-apply.md +75 -75
- package/vendor/templates/project/claude/commands/forge-brainstorm.md +7 -7
- package/vendor/templates/project/claude/commands/forge-build.md +17 -17
- package/vendor/templates/project/claude/commands/forge-plan.md +12 -12
- package/vendor/templates/project/claude/commands/forge-skip.md +14 -14
- package/vendor/templates/project/claude/commands/forge-status.md +16 -16
- package/vendor/templates/project/claude/commands/forge.md +16 -16
- package/vendor/templates/project/claude/hooks/forge-prompt-hook.mjs +73 -73
- package/vendor/templates/project/claude/hooks/forge-session-start.mjs +19 -19
- package/vendor/templates/project/claude/hooks/forge-triage-hook.mjs +77 -77
- package/vendor/templates/project/cursor/commands/forge-apply.md +75 -75
- package/vendor/templates/project/cursor/commands/forge-brainstorm.md +10 -10
- package/vendor/templates/project/cursor/commands/forge-build.md +17 -17
- package/vendor/templates/project/cursor/commands/forge-plan.md +15 -15
- package/vendor/templates/project/cursor/commands/forge-skip.md +14 -14
- package/vendor/templates/project/cursor/commands/forge-status.md +16 -16
- package/vendor/templates/project/cursor/commands/forge.md +16 -16
- package/vendor/templates/project/cursor/hooks/forge-session-start.mjs +30 -30
- package/vendor/templates/project/cursor/hooks/forge-session-start.sh +3 -3
|
@@ -1,647 +1,650 @@
|
|
|
1
|
-
# Forge — disciplined development workflow
|
|
2
|
-
|
|
3
|
-
Forge is an **OpenSpec-native**, **self-contained** development pipeline.
|
|
4
|
-
All workflow skills (brainstorm, TDD, subagents, verify, review) live under the
|
|
5
|
-
Forge skill’s `skills/` folder — **no Superpowers plugin required**.
|
|
6
|
-
|
|
7
|
-
It does not stop at green unit tests or checked-off tasks: **runtime integrity**
|
|
8
|
-
requires a named production path for every claimed capability, and (for
|
|
9
|
-
jobs/workers) a closed product loop before `forge phase done`. See
|
|
10
|
-
[Runtime integrity](#runtime-integrity).
|
|
11
|
-
|
|
12
|
-
**Using Forgekit for the first time?** Start with the tutorial:
|
|
13
|
-
[**How to use Forgekit**](https://github.com/izkac/forgekit/blob/main/docs/usage.md) (install → init → `/forge:apply` → examples).
|
|
14
|
-
|
|
15
|
-
**Skill:** `forge` (Cursor, Claude Code, Codex CLI)
|
|
16
|
-
**Commands:** `/forge`, `/forge:*` (after `forge init`; Cursor and Claude Code)
|
|
17
|
-
**Scratch space:** `.forge/` (gitignored except README)
|
|
18
|
-
**CLI:** `@izkac/forgekit` → `forgekit` (install) · `forge` (workflow) · `review` (standalone deep review)
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Install
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
# Preferred — once per machine
|
|
26
|
-
npm i -g @izkac/forgekit
|
|
27
|
-
forgekit install --skills forge --agents cursor,claude
|
|
28
|
-
# or: forge install # alias → --skills forge
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
# Once per project
|
|
33
|
-
forge init --cursor --claude # commands, rules, hooks, .forge/
|
|
34
|
-
forge init --overlay # optional OpenSpec vendor patches
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Hooks call `forge` on PATH. Merge the generated `forge-hooks.snippet.json`
|
|
38
|
-
into your agent settings if hooks are not picked up automatically.
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## When Forge runs
|
|
43
|
-
|
|
44
|
-
**Default:** agents **triage** every task. Substantial work enters Forge
|
|
45
|
-
automatically unless the user explicitly skips with **`/forge:skip`**.
|
|
46
|
-
|
|
47
|
-
### Substantial work (enter Forge)
|
|
48
|
-
|
|
49
|
-
**Forge = OpenSpec.** Enter the full flow only when the work warrants a tracked OpenSpec change — when **any** of:
|
|
50
|
-
|
|
51
|
-
- New feature or behavior change
|
|
52
|
-
- Multi-file or multi-package change
|
|
53
|
-
- Public API, contract, or config schema change
|
|
54
|
-
- Cross-product / ecosystem impact
|
|
55
|
-
- User invokes `/forge`, `/forge:brainstorm`, `/forge:plan`, or `/forge:build`
|
|
56
|
-
- Work would likely need an ADR or new OpenSpec capability when done
|
|
57
|
-
|
|
58
|
-
### Trivial work (skip Forge)
|
|
59
|
-
|
|
60
|
-
Execute directly when **all** of:
|
|
61
|
-
|
|
62
|
-
- Question, explanation, or read-only review
|
|
63
|
-
- Typo, comment, or purely cosmetic edit
|
|
64
|
-
- Single localized change with no contract impact
|
|
65
|
-
- User explicitly says **`/forge:skip`** for this task
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## End-to-end decision tree
|
|
70
|
-
|
|
71
|
-
This doc uses an **ASCII tree only** — no Mermaid. Lightweight viewers (e.g.
|
|
72
|
-
MarkView) render Mermaid flowcharts with broken fills and connectors; ASCII
|
|
73
|
-
works everywhere.
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
User request
|
|
77
|
-
│
|
|
78
|
-
├─ /forge:skip? ── yes ──► Direct execution (no Forge session)
|
|
79
|
-
│
|
|
80
|
-
└─ no
|
|
81
|
-
│
|
|
82
|
-
└─ OpenSpec-worthy / substantial? ── no ──► Direct execution
|
|
83
|
-
│
|
|
84
|
-
yes
|
|
85
|
-
│
|
|
86
|
-
▼
|
|
87
|
-
Start / resume Forge session
|
|
88
|
-
│
|
|
89
|
-
▼
|
|
90
|
-
Phase: Brainstorm
|
|
91
|
-
│
|
|
92
|
-
├─ design not approved ──► (loop back to Brainstorm)
|
|
93
|
-
│
|
|
94
|
-
└─ design approved
|
|
95
|
-
│
|
|
96
|
-
▼
|
|
97
|
-
Phase: Plan (OpenSpec)
|
|
98
|
-
│
|
|
99
|
-
▼
|
|
100
|
-
/opsx:propose
|
|
101
|
-
openspec/changes/<name>/
|
|
102
|
-
│
|
|
103
|
-
▼
|
|
104
|
-
Phase: Implement
|
|
105
|
-
│
|
|
106
|
-
┌─────────────┴─────────────┐
|
|
107
|
-
│ PER TASK (loop until done) │
|
|
108
|
-
│ 1. Subagent implementer │
|
|
109
|
-
│ 2. TDD (scoped tests) │
|
|
110
|
-
│ 3. Reviewer (pace): │
|
|
111
|
-
│ thorough=per task │
|
|
112
|
-
│ standard=per group │
|
|
113
|
-
│ └─ fail ──► retry │
|
|
114
|
-
│ (tier 2 narrow evidence) │
|
|
115
|
-
└─────────────┬─────────────┘
|
|
116
|
-
▼
|
|
117
|
-
Verify: audit tier 2 + tier 3 (scope from pace)
|
|
118
|
-
+ forge e2e run (green, or BLOCKED)
|
|
119
|
-
+ forge integrity-check
|
|
120
|
-
│
|
|
121
|
-
▼
|
|
122
|
-
Final review (pace) — spine + product loop
|
|
123
|
-
│
|
|
124
|
-
▼
|
|
125
|
-
/opsx:archive (+ project ADR follow-up if any)
|
|
126
|
-
│
|
|
127
|
-
▼
|
|
128
|
-
forge phase done ← integrity gate (refuses if incomplete)
|
|
129
|
-
Done + cleanup .forge session
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
**Jobs / workers / queues:** spine is mandatory for *every* change (`forge spine
|
|
133
|
-
init` — rows or `notApplicable`). Spine rows also require executable acceptance
|
|
134
|
-
steps (`forge e2e init` at plan, green `forge e2e run` before done). Async work
|
|
135
|
-
also needs wiring + product-loop tasks. See [Runtime integrity](#runtime-integrity).
|
|
136
|
-
|
|
137
|
-
### Triage (top of tree)
|
|
138
|
-
|
|
139
|
-
| Check | Outcome |
|
|
140
|
-
| ----- | ------- |
|
|
141
|
-
| User sent `/forge:skip` | Direct execution |
|
|
142
|
-
| Not substantial / not tracked-change-worthy | Direct execution |
|
|
143
|
-
| Otherwise | Enter Forge session (tracked change) |
|
|
144
|
-
|
|
145
|
-
### Planning engine (per project)
|
|
146
|
-
|
|
147
|
-
Forge always produces a tracked change; the **engine** is project config
|
|
148
|
-
(`.forge/config.json` → `plan.engine`, set by `forge init`):
|
|
149
|
-
|
|
150
|
-
| Engine | Change location | Tooling |
|
|
151
|
-
| ------ | --------------- | ------- |
|
|
152
|
-
| `openspec` | `openspec/changes/<name>/` | OpenSpec CLI + `/opsx:*` vendor skills |
|
|
153
|
-
| `specs` |
|
|
154
|
-
|
|
155
|
-
Selection flow: `forgekit install` asks once for a user default
|
|
156
|
-
(`~/.forgekit/config.json` → `plan.engine`); `forge init`
|
|
157
|
-
(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
init
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
|
170
|
-
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
| **
|
|
184
|
-
| **
|
|
185
|
-
| **
|
|
186
|
-
| **
|
|
187
|
-
|
|
188
|
-
**
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
e2e.json
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
**
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
|
245
|
-
|
|
|
246
|
-
| `/forge
|
|
247
|
-
| `/forge:
|
|
248
|
-
| `/forge:
|
|
249
|
-
| `/forge:
|
|
250
|
-
| `/forge:
|
|
251
|
-
| `/forge:
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
|
259
|
-
|
|
|
260
|
-
| `/opsx:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
forge
|
|
271
|
-
forge
|
|
272
|
-
|
|
273
|
-
forge
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
forge
|
|
277
|
-
|
|
278
|
-
forge
|
|
279
|
-
|
|
280
|
-
forge prefs
|
|
281
|
-
forge
|
|
282
|
-
|
|
283
|
-
forge
|
|
284
|
-
forge
|
|
285
|
-
forge
|
|
286
|
-
forge
|
|
287
|
-
forge
|
|
288
|
-
forge
|
|
289
|
-
forge
|
|
290
|
-
forge
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
forge models
|
|
319
|
-
|
|
320
|
-
forge
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
|
338
|
-
|
|
339
|
-
| `
|
|
340
|
-
| `
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
|
350
|
-
|
|
351
|
-
| **review.
|
|
352
|
-
| **
|
|
353
|
-
| **
|
|
354
|
-
| **
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
|
420
|
-
|
|
421
|
-
| `forge
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
`
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
|
438
|
-
|
|
|
439
|
-
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
"
|
|
463
|
-
"
|
|
464
|
-
"
|
|
465
|
-
"
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
"
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
"
|
|
472
|
-
"
|
|
473
|
-
"
|
|
474
|
-
"
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
{ "name": "
|
|
498
|
-
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
results
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
-
|
|
568
|
-
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
|
589
|
-
|
|
|
590
|
-
|
|
|
591
|
-
|
|
|
592
|
-
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
|
602
|
-
|
|
|
603
|
-
|
|
|
604
|
-
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
|
617
|
-
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
|
625
|
-
|
|
|
626
|
-
| `/forge
|
|
627
|
-
| `/forge:
|
|
628
|
-
| `/forge:
|
|
629
|
-
| `/forge:
|
|
630
|
-
| `/forge:
|
|
631
|
-
| `/forge:
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
1
|
+
# Forge — disciplined development workflow
|
|
2
|
+
|
|
3
|
+
Forge is an **OpenSpec-native**, **self-contained** development pipeline.
|
|
4
|
+
All workflow skills (brainstorm, TDD, subagents, verify, review) live under the
|
|
5
|
+
Forge skill’s `skills/` folder — **no Superpowers plugin required**.
|
|
6
|
+
|
|
7
|
+
It does not stop at green unit tests or checked-off tasks: **runtime integrity**
|
|
8
|
+
requires a named production path for every claimed capability, and (for
|
|
9
|
+
jobs/workers) a closed product loop before `forge phase done`. See
|
|
10
|
+
[Runtime integrity](#runtime-integrity).
|
|
11
|
+
|
|
12
|
+
**Using Forgekit for the first time?** Start with the tutorial:
|
|
13
|
+
[**How to use Forgekit**](https://github.com/izkac/forgekit/blob/main/docs/usage.md) (install → init → `/forge:apply` → examples).
|
|
14
|
+
|
|
15
|
+
**Skill:** `forge` (Cursor, Claude Code, Codex CLI)
|
|
16
|
+
**Commands:** `/forge`, `/forge:*` (after `forge init`; Cursor and Claude Code)
|
|
17
|
+
**Scratch space:** `.forge/` (gitignored except README)
|
|
18
|
+
**CLI:** `@izkac/forgekit` → `forgekit` (install) · `forge` (workflow) · `review` (standalone deep review)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Preferred — once per machine
|
|
26
|
+
npm i -g @izkac/forgekit
|
|
27
|
+
forgekit install --skills forge --agents cursor,claude
|
|
28
|
+
# or: forge install # alias → --skills forge
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Once per project
|
|
33
|
+
forge init --cursor --claude # commands, rules, hooks, .forge/
|
|
34
|
+
forge init --overlay # optional OpenSpec vendor patches
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Hooks call `forge` on PATH. Merge the generated `forge-hooks.snippet.json`
|
|
38
|
+
into your agent settings if hooks are not picked up automatically.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## When Forge runs
|
|
43
|
+
|
|
44
|
+
**Default:** agents **triage** every task. Substantial work enters Forge
|
|
45
|
+
automatically unless the user explicitly skips with **`/forge:skip`**.
|
|
46
|
+
|
|
47
|
+
### Substantial work (enter Forge)
|
|
48
|
+
|
|
49
|
+
**Forge = OpenSpec.** Enter the full flow only when the work warrants a tracked OpenSpec change — when **any** of:
|
|
50
|
+
|
|
51
|
+
- New feature or behavior change
|
|
52
|
+
- Multi-file or multi-package change
|
|
53
|
+
- Public API, contract, or config schema change
|
|
54
|
+
- Cross-product / ecosystem impact
|
|
55
|
+
- User invokes `/forge`, `/forge:brainstorm`, `/forge:plan`, or `/forge:build`
|
|
56
|
+
- Work would likely need an ADR or new OpenSpec capability when done
|
|
57
|
+
|
|
58
|
+
### Trivial work (skip Forge)
|
|
59
|
+
|
|
60
|
+
Execute directly when **all** of:
|
|
61
|
+
|
|
62
|
+
- Question, explanation, or read-only review
|
|
63
|
+
- Typo, comment, or purely cosmetic edit
|
|
64
|
+
- Single localized change with no contract impact
|
|
65
|
+
- User explicitly says **`/forge:skip`** for this task
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## End-to-end decision tree
|
|
70
|
+
|
|
71
|
+
This doc uses an **ASCII tree only** — no Mermaid. Lightweight viewers (e.g.
|
|
72
|
+
MarkView) render Mermaid flowcharts with broken fills and connectors; ASCII
|
|
73
|
+
works everywhere.
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
User request
|
|
77
|
+
│
|
|
78
|
+
├─ /forge:skip? ── yes ──► Direct execution (no Forge session)
|
|
79
|
+
│
|
|
80
|
+
└─ no
|
|
81
|
+
│
|
|
82
|
+
└─ OpenSpec-worthy / substantial? ── no ──► Direct execution
|
|
83
|
+
│
|
|
84
|
+
yes
|
|
85
|
+
│
|
|
86
|
+
▼
|
|
87
|
+
Start / resume Forge session
|
|
88
|
+
│
|
|
89
|
+
▼
|
|
90
|
+
Phase: Brainstorm
|
|
91
|
+
│
|
|
92
|
+
├─ design not approved ──► (loop back to Brainstorm)
|
|
93
|
+
│
|
|
94
|
+
└─ design approved
|
|
95
|
+
│
|
|
96
|
+
▼
|
|
97
|
+
Phase: Plan (OpenSpec)
|
|
98
|
+
│
|
|
99
|
+
▼
|
|
100
|
+
/opsx:propose
|
|
101
|
+
openspec/changes/<name>/
|
|
102
|
+
│
|
|
103
|
+
▼
|
|
104
|
+
Phase: Implement
|
|
105
|
+
│
|
|
106
|
+
┌─────────────┴─────────────┐
|
|
107
|
+
│ PER TASK (loop until done) │
|
|
108
|
+
│ 1. Subagent implementer │
|
|
109
|
+
│ 2. TDD (scoped tests) │
|
|
110
|
+
│ 3. Reviewer (pace): │
|
|
111
|
+
│ thorough=per task │
|
|
112
|
+
│ standard=per group │
|
|
113
|
+
│ └─ fail ──► retry │
|
|
114
|
+
│ (tier 2 narrow evidence) │
|
|
115
|
+
└─────────────┬─────────────┘
|
|
116
|
+
▼
|
|
117
|
+
Verify: audit tier 2 + tier 3 (scope from pace)
|
|
118
|
+
+ forge e2e run (green, or BLOCKED)
|
|
119
|
+
+ forge integrity-check
|
|
120
|
+
│
|
|
121
|
+
▼
|
|
122
|
+
Final review (pace) — spine + product loop
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
/opsx:archive (+ project ADR follow-up if any)
|
|
126
|
+
│
|
|
127
|
+
▼
|
|
128
|
+
forge phase done ← integrity gate (refuses if incomplete)
|
|
129
|
+
Done + cleanup .forge session
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Jobs / workers / queues:** spine is mandatory for *every* change (`forge spine
|
|
133
|
+
init` — rows or `notApplicable`). Spine rows also require executable acceptance
|
|
134
|
+
steps (`forge e2e init` at plan, green `forge e2e run` before done). Async work
|
|
135
|
+
also needs wiring + product-loop tasks. See [Runtime integrity](#runtime-integrity).
|
|
136
|
+
|
|
137
|
+
### Triage (top of tree)
|
|
138
|
+
|
|
139
|
+
| Check | Outcome |
|
|
140
|
+
| ----- | ------- |
|
|
141
|
+
| User sent `/forge:skip` | Direct execution |
|
|
142
|
+
| Not substantial / not tracked-change-worthy | Direct execution |
|
|
143
|
+
| Otherwise | Enter Forge session (tracked change) |
|
|
144
|
+
|
|
145
|
+
### Planning engine (per project)
|
|
146
|
+
|
|
147
|
+
Forge always produces a tracked change; the **engine** is project config
|
|
148
|
+
(`.forge/config.json` → `plan.engine`, set by `forge init`):
|
|
149
|
+
|
|
150
|
+
| Engine | Change location | Tooling |
|
|
151
|
+
| ------ | --------------- | ------- |
|
|
152
|
+
| `openspec` | `openspec/changes/<name>/` | OpenSpec CLI + `/opsx:*` vendor skills |
|
|
153
|
+
| `specs` | `<plan.dir>/changes/<name>/` (dir from `plan.dir`, default `specs`) | Built-in — OpenSpec-format markdown (proposal / design / tasks / deltas) |
|
|
154
|
+
|
|
155
|
+
Selection flow: `forgekit install` asks once for a user default
|
|
156
|
+
(`~/.forgekit/config.json` → `plan.engine`); `forge init` uses that default
|
|
157
|
+
(or asks Planning engine? when unset), auto-detects `openspec/config.yaml`,
|
|
158
|
+
and offers `openspec init` when OpenSpec is chosen but missing. Choosing
|
|
159
|
+
OpenSpec always writes `plan.engine: openspec` — setup failure or declining
|
|
160
|
+
immediate init does **not** fall back to the built-in specs engine
|
|
161
|
+
(`--openspec` / `--no-openspec` skip prompts; `--plan-dir` sets the specs
|
|
162
|
+
engine root, e.g. `openspec` to reuse a vendor tree). Migration later: keep
|
|
163
|
+
the same tree and flip `plan.engine`, or run `openspec init` if starting fresh.
|
|
164
|
+
|
|
165
|
+
### Planning (after brainstorm)
|
|
166
|
+
|
|
167
|
+
Proceed directly to the configured engine's propose flow — do not ask for a plan mode.
|
|
168
|
+
|
|
169
|
+
| Step | What happens |
|
|
170
|
+
| ---- | ------------ |
|
|
171
|
+
| **Propose** | `/opsx:propose` → `openspec/changes/<name>/` (openspec) or author `specs/changes/<name>/{proposal,tasks}.md` per [plan-specs.md](../phases/plan-specs.md) (specs) |
|
|
172
|
+
| **User approval** | Confirm proposal, design, tasks before implement |
|
|
173
|
+
| **Implement** | `/forge:apply` or `/forge:build` against `tasks.md` |
|
|
174
|
+
|
|
175
|
+
See the Forge skill’s [references/plan-routing.md](../references/plan-routing.md).
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Phases
|
|
180
|
+
|
|
181
|
+
| Phase | What happens | Skills / commands |
|
|
182
|
+
| ----- | ------------ | ----------------- |
|
|
183
|
+
| **triage** | Substantial? Skip allowed? Bootstrap session | `forge` skill |
|
|
184
|
+
| **brainstorm** | Explore intent, approaches, approval | `skills/brainstorming` |
|
|
185
|
+
| **plan** | Tracked-change propose; **`forge spine init` every change** (rows or `notApplicable`); rows → `forge e2e init` (steps are a plan deliverable); wiring + product-loop tasks when async | [plan-routing.md](../references/plan-routing.md) |
|
|
186
|
+
| **implement** | Subagent per task, TDD, tier 2 evidence; update spine rows; `forge defer` for deferred wiring | **`/forge:apply`** (OpenSpec) or `/forge:build` + `skills/subagent-driven-development` + `skills/test-driven-development` + [test-strategy](../references/test-strategy.md) |
|
|
187
|
+
| **verify** | Audit tier 2; tier 3; green `forge e2e run`; `forge integrity-check` | `skills/verification-before-completion` + `verify-evidence.md` |
|
|
188
|
+
| **review** | Combined task reviewer (spec + quality) per task; final review (spine + executed e2e) | `skills/requesting-code-review` |
|
|
189
|
+
| **finish** | Archive (+ ADR if the project uses that); `forge phase done` (integrity gate); cleanup | `/opsx:archive`, `forge cleanup` |
|
|
190
|
+
|
|
191
|
+
**Standalone deep review (outside Forge):** for pre-merge audits with adversarial false-positive filtering, use the **thorough code review** skill — see [thorough-code-review.md](https://github.com/izkac/forgekit/blob/main/docs/thorough-code-review.md). Forge's `requesting-code-review` stays the per-task checkpoint during `/forge:build`.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## `.forge/` session layout
|
|
196
|
+
|
|
197
|
+
One session per substantial task. **Per-checkout** active pointer — works across
|
|
198
|
+
Cursor, Claude Code, and Codex without requiring a chat ID.
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
.forge/
|
|
202
|
+
active.json ← current session (gitignored)
|
|
203
|
+
models.local.json ← optional billing overlay
|
|
204
|
+
preferences.local.json ← optional pace overlay
|
|
205
|
+
sessions/
|
|
206
|
+
2026-06-05T143022Z-my-feature-a3f9b2/
|
|
207
|
+
session.json ← phase, planType, openspecChange, pace
|
|
208
|
+
status.json ← machine-readable progress
|
|
209
|
+
brainstorm/
|
|
210
|
+
notes.md
|
|
211
|
+
decisions.md
|
|
212
|
+
plan.md ← legacy throwaway plans only (deprecated)
|
|
213
|
+
verify-evidence.md ← tier 3 + loop narrative (or BLOCKED)
|
|
214
|
+
e2e-results.json ← forge e2e run results (steps hash + per-step outcomes)
|
|
215
|
+
deferrals.json ← forge defer registry (when used)
|
|
216
|
+
spine.json ← fallback if no tracked change dir
|
|
217
|
+
e2e.json ← fallback if no tracked change dir
|
|
218
|
+
scorecard.md / scorecard.json ← L2 session score (written at done/finish)
|
|
219
|
+
tasks/
|
|
220
|
+
01-first-task/
|
|
221
|
+
brief.md
|
|
222
|
+
test-evidence.md
|
|
223
|
+
task-review.md ← combined spec + quality verdict
|
|
224
|
+
reviews/
|
|
225
|
+
final-review.md
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
For OpenSpec / specs-engine changes, the canonical **spine matrix** and **e2e
|
|
229
|
+
steps** live next to the plan: `openspec/changes/<name>/spine.json` + `e2e.json`
|
|
230
|
+
(or `<specsDir>/changes/<name>/…`).
|
|
231
|
+
|
|
232
|
+
**Session ID:** `<UTC-compact>-<kebab-slug>-<6-hex>`
|
|
233
|
+
|
|
234
|
+
**Retention:** 14 days. Finished sessions (`phase: done|skipped`) are removed
|
|
235
|
+
on cleanup. Active session is never removed unless `--include-active`.
|
|
236
|
+
|
|
237
|
+
Optional `cursorChatId` on `session.json` when a hook can supply it — not
|
|
238
|
+
required for correctness.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Commands (project slash)
|
|
243
|
+
|
|
244
|
+
| Command | Purpose |
|
|
245
|
+
| ------- | ------- |
|
|
246
|
+
| `/forge` | Start or resume from active session / current phase |
|
|
247
|
+
| `/forge:brainstorm` | Brainstorm phase only |
|
|
248
|
+
| `/forge:plan` | Plan phase — tracked-change propose (engine from `.forge/config.json`) |
|
|
249
|
+
| `/forge:apply` | **Tracked-change implement** — subagent TDD + verify + review (preferred over `/opsx:apply`) |
|
|
250
|
+
| `/forge:build` | Implement phase (`tasks.md` from either engine) |
|
|
251
|
+
| `/forge:status` | Show active session progress |
|
|
252
|
+
| `/forge:harness` | Ensure a working, recorded project e2e harness (build proactively) |
|
|
253
|
+
| `/forge:analyze` | Agent-written improvement report over recent sessions |
|
|
254
|
+
| `/forge:skip` | **Explicit** opt-out of Forge for this task |
|
|
255
|
+
|
|
256
|
+
OpenSpec commands remain available standalone (OpenSpec-engine projects):
|
|
257
|
+
|
|
258
|
+
| Command | Purpose |
|
|
259
|
+
| ------- | ------- |
|
|
260
|
+
| `/opsx:propose` | Create OpenSpec change + artifacts |
|
|
261
|
+
| `/opsx:apply` | Vendor OpenSpec task loop — **re-overlay** with Forge via `forge overlay`; prefer **`/forge:apply`** |
|
|
262
|
+
| `/opsx:archive` | Archive completed change |
|
|
263
|
+
| `/opsx:explore` | Explore without committing to a change |
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## CLI (`forge`)
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
forge new <slug> [--signal "…"] # new session + set active (resolves pace; warn-only doctor)
|
|
271
|
+
forge status # active session JSON (+ effective pace)
|
|
272
|
+
forge phase <phase> […] # update phase / openspec / task counters
|
|
273
|
+
forge cleanup [--dry-run] # prune sessions >14 days or finished
|
|
274
|
+
forge evidence --task <nn>-<slug> --command "<cmd>" --exit 0 --summary "<text>"
|
|
275
|
+
# stamp tier-2 test-evidence.md
|
|
276
|
+
forge resolve-model --tier <fast|standard|capable>
|
|
277
|
+
# JSON model resolution (included billing by default)
|
|
278
|
+
forge models # print effective billing (does NOT write a file)
|
|
279
|
+
forge models included|metered # WRITE .forge/models.local.json
|
|
280
|
+
forge prefs # print effective pace (does NOT write a file)
|
|
281
|
+
forge prefs auto|thorough|standard|brisk|lite
|
|
282
|
+
# WRITE .forge/preferences.local.json
|
|
283
|
+
forge prefs --session-set lite # pin active session only
|
|
284
|
+
forge doctor # plan-engine readiness (OpenSpec or specs layout)
|
|
285
|
+
forge doctor --install # attempt npm install -g @fission-ai/openspec
|
|
286
|
+
forge spine init|check # capability→runtime spine matrix (spine.json in change dir)
|
|
287
|
+
forge e2e init|run|check # executable product-loop acceptance (e2e.json + e2e-results.json)
|
|
288
|
+
forge defer add|resolve|list # deferral registry — deferred wiring is tracked debt
|
|
289
|
+
forge integrity-check # mechanical gate: spine + deferrals + executed e2e
|
|
290
|
+
forge score [--write] [--md] # L2 session scorecard (also auto-written at phase done)
|
|
291
|
+
forge overlay # re-apply OpenSpec vendor overlays in this project
|
|
292
|
+
forge init […] # wire project commands / hooks / rules
|
|
293
|
+
forge install […] # alias → forgekit install --skills forge
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Meta install (skills × agents):
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
forgekit install
|
|
300
|
+
forgekit install --skills forge,thorough-code-review --agents cursor,claude
|
|
301
|
+
forgekit list
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Checkout-local overrides (per developer)
|
|
307
|
+
|
|
308
|
+
Forge has two **optional**, **gitignored** overlays under `.forge/`.
|
|
309
|
+
They appear on disk **only after you set them**. Bare get commands only print the
|
|
310
|
+
merged effective value from package defaults.
|
|
311
|
+
|
|
312
|
+
| Concern | Defaults (in `@izkac/forgekit`) | Local file (gitignored) | Get (print only) | Set (creates/updates file) |
|
|
313
|
+
| ------- | ----------------------------- | ----------------------- | ---------------- | -------------------------- |
|
|
314
|
+
| Subagent **billing** (`included` / `metered`) | `packages/cli/src/models.defaults.json` | `.forge/models.local.json` | `forge models` | `forge models included\|metered` |
|
|
315
|
+
| Forge **pace** (review / verify ceremony) | `packages/cli/src/preferences.defaults.json` | `.forge/preferences.local.json` | `forge prefs` | `forge prefs auto\|thorough\|…` |
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Example: you ran forge models and only saw "included" —
|
|
319
|
+
# that means the default lane is in effect. No models.local.json exists yet.
|
|
320
|
+
forge models --json # localExists: false until you set
|
|
321
|
+
forge models included # now creates .forge/models.local.json
|
|
322
|
+
|
|
323
|
+
forge prefs --session-set lite # pin active session only; no local file
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
These are **per-checkout** (each developer’s clone), not committed to git — same
|
|
327
|
+
idea as a personal `.env`.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Pace (thoroughness)
|
|
332
|
+
|
|
333
|
+
Forge ceremony (per-task review, final review, tier-3 verify, model bias, brainstorm
|
|
334
|
+
depth) is controlled by a **pace** preset. Default is **`auto`**: resolve once at
|
|
335
|
+
session start from risk signals, sticky for the session.
|
|
336
|
+
|
|
337
|
+
| Pace | Intent |
|
|
338
|
+
|------|--------|
|
|
339
|
+
| `auto` | Pick thorough / standard / brisk / lite from signals (default) |
|
|
340
|
+
| `thorough` | Always review **each task**; full-workspace tier 3 |
|
|
341
|
+
| `standard` | Review once per **OpenSpec group**; full-workspace tier 3 |
|
|
342
|
+
| `brisk` | Review high-risk tasks only; affected-workspace tier 3 |
|
|
343
|
+
| `lite` | Skip reviews for low-risk; audit tier-2 only at verify |
|
|
344
|
+
|
|
345
|
+
### Effort matrix (exact knobs)
|
|
346
|
+
|
|
347
|
+
Defaults from `packages/cli/src/preferences.defaults.json`:
|
|
348
|
+
|
|
349
|
+
| Knob | `thorough` | `standard` | `brisk` | `lite` |
|
|
350
|
+
|------|------------|------------|---------|--------|
|
|
351
|
+
| **review.perTask** | always | per-group | high-risk-only | never\* |
|
|
352
|
+
| **review.final** | always | always | high-risk-only | never\* |
|
|
353
|
+
| **review.depth** | full | full | spec-only | spec-only |
|
|
354
|
+
| **review.maxRounds** | 3 | 2 | 1 | 0 |
|
|
355
|
+
| **verify.tier3** | full-workspace | full-workspace | affected-only | audit-tier2-only |
|
|
356
|
+
| **models.bias** | default | default | prefer-fast | prefer-fast |
|
|
357
|
+
| **brainstorm.depth** | full | full | short (≤2–3 options) | minimal |
|
|
358
|
+
|
|
359
|
+
\*Hard floor: money / auth / contracts / migrations / secrets still get per-task review (and final if the session touched high-risk), even under `brisk` / `lite` / mid-group `standard`.
|
|
360
|
+
|
|
361
|
+
**`thorough` vs `standard`:** thorough reviews every task; standard reviews once per OpenSpec `tasks.md` group (`##` section), except high-risk tasks which still get an immediate per-task review.
|
|
362
|
+
|
|
363
|
+
**`auto`** is not a preset — it picks one of the four once at session start (sticky):
|
|
364
|
+
|
|
365
|
+
1. money / payment / auth / secret / migration / contract / gdpr → **thorough**
|
|
366
|
+
2. ecosystem / API / multi-file / shared package / worker / job queue / pipeline / etl / platform / orchestration / openspec → **standard**
|
|
367
|
+
3. docs / typo / rename / scaffold / changelog → **lite**
|
|
368
|
+
4. fix / tweak / toolbar / style / padding (explicitly small) → **brisk**
|
|
369
|
+
5. else (including empty / unrecognized) → **standard** (fail closed)
|
|
370
|
+
|
|
371
|
+
When `--tasks-total N` is set with **N ≥ 15** and resolved pace is still `brisk`/`lite` (not user-pinned), Forge escalates the session to **standard**.
|
|
372
|
+
|
|
373
|
+
**Unchanged on all paces:** tier-1 TDD + tier-2 evidence, no autonomous commit, OpenSpec when in Forge. Runtime integrity (below) applies at every pace.
|
|
374
|
+
|
|
375
|
+
Agent rules for each knob: [pace.md](../references/pace.md).
|
|
376
|
+
|
|
377
|
+
Prefs are gitignored (`.forge/preferences.local.json`), same pattern as `models.local.json`.
|
|
378
|
+
|
|
379
|
+
### OpenSpec doctor
|
|
380
|
+
|
|
381
|
+
`forge doctor` checks `openspec/config.yaml` and that `openspec` is on PATH.
|
|
382
|
+
If the CLI is missing, it warns and offers `npm install -g @fission-ai/openspec`
|
|
383
|
+
(`--install` to attempt). `forge new` runs doctor warn-only so a missing CLI does
|
|
384
|
+
not block session creation.
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Runtime integrity
|
|
389
|
+
|
|
390
|
+
Forge’s job is to ship **working product paths**, not green checkboxes over
|
|
391
|
+
orphan libraries. Integrity rules live in
|
|
392
|
+
[runtime-integrity.md](../references/runtime-integrity.md) and are
|
|
393
|
+
enforced by both skill prompts and the CLI.
|
|
394
|
+
|
|
395
|
+
### The problem it prevents
|
|
396
|
+
|
|
397
|
+
Without integrity, a large change can look “done” while the product is hollow:
|
|
398
|
+
|
|
399
|
+
- Libraries (matcher, BI exporter, …) are unit-tested and marked complete
|
|
400
|
+
- A worker job logs and marks `succeeded` (or a thin concat job writes a `.sav`)
|
|
401
|
+
- The UI can enqueue kinds nobody handles, or read collections nobody writes
|
|
402
|
+
- OpenSpec shows 57/57 — but upload → analyze → ratify → run never works
|
|
403
|
+
|
|
404
|
+
Integrity upgrades Forge from “no false job success” to **product-loop acceptance**.
|
|
405
|
+
|
|
406
|
+
### Rules (plain language)
|
|
407
|
+
|
|
408
|
+
1. **No stubs / false success** — a handler that only logs and succeeds is forbidden.
|
|
409
|
+
2. **Runtime owner required** — a library alone does not satisfy a capability; name the production caller (job, endpoint, CLI).
|
|
410
|
+
3. **Tests must fail on a no-op** — asserting “job status became succeeded” is not enough.
|
|
411
|
+
4. **Specs beat narrow tasks** — capability specs win when they conflict with a thin task reading.
|
|
412
|
+
5. **E2E = executed product loop** — produce → consume → decision changes output, run as `e2e.json` steps via `forge e2e run` (prose does not count). A single job slice (ingest → Parquet) is **not** platform E2E.
|
|
413
|
+
6. **Job-kind closure** — every product-surface job kind is wired end-to-end **or deleted** before complete. “Fail closed” is only a temporary `BLOCKED` state.
|
|
414
|
+
7. **Consumer–producer** — if UI/API reads it, production must write it (proven in evidence).
|
|
415
|
+
8. **Deferrals are tracked** — “wiring later” only via `forge defer`; unresolved deferrals block `done`.
|
|
416
|
+
|
|
417
|
+
### Mechanics
|
|
418
|
+
|
|
419
|
+
| Tool | Purpose |
|
|
420
|
+
|------|---------|
|
|
421
|
+
| `forge spine init\|check` | **Mandatory every change.** `spine.json`: rows **or** `notApplicable`. Not keyword-gated. |
|
|
422
|
+
| `forge e2e init\|run\|check` | **Mandatory when the spine has rows.** `e2e.json` step list executed by `forge e2e run`; results (`e2e-results.json`) carry a steps hash, so edits after a green run go stale |
|
|
423
|
+
| `forge defer add\|resolve\|list` | Deferred wiring as tracked debt in the session |
|
|
424
|
+
| `forge integrity-check` | Combined gate — also run automatically by `forge phase done\|finish` |
|
|
425
|
+
|
|
426
|
+
Defaults (`integrity.forbidStubs`, `specsBeatNarrowTasks`, `requireE2E`) live in
|
|
427
|
+
`preferences.defaults.json` and appear in `forge status`.
|
|
428
|
+
|
|
429
|
+
Escape hatch: `forge phase done --allow-incomplete "<reason>"` records an honest
|
|
430
|
+
exception in the session — it does not silently checkbox past gaps.
|
|
431
|
+
|
|
432
|
+
### What runs automatically every session
|
|
433
|
+
|
|
434
|
+
You do **not** paste a long definition-of-done prompt. After
|
|
435
|
+
`forgekit install --skills forge`, every Forge session gets:
|
|
436
|
+
|
|
437
|
+
| Automatic (CLI / hooks) | Agent-driven (skill phases — required) |
|
|
438
|
+
| ----------------------- | -------------------------------------- |
|
|
439
|
+
| Integrity reminder on every session/prompt hook | Plan: **`forge spine init` every change** — fill rows or `notApplicable`; rows → also `forge e2e init` |
|
|
440
|
+
| Pace `auto` fail-closed to **standard**; task-count escalation at ≥15 | Implement: update spine rows; `forge defer add` if wiring is deferred |
|
|
441
|
+
| `forge phase done\|finish` requires valid spine + green current e2e run + writes L2 scorecard | Verify: green `forge e2e run` when spine has rows (sync-only → prefer `notApplicable`) |
|
|
442
|
+
| `forge status` surfaces `integrity.*` defaults | After done: answer L3 ship-check in `scorecard.md` |
|
|
443
|
+
|
|
444
|
+
**Gates are automatic. Filling evidence is part of the normal phase flow.**
|
|
445
|
+
Skipping those steps fails at `forge phase done`, not silently.
|
|
446
|
+
|
|
447
|
+
### Worked example (jobs / workers change)
|
|
448
|
+
|
|
449
|
+
**Plan**
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
forge spine init
|
|
453
|
+
# edit openspec/changes/<name>/spine.json — one row per capability
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
```json
|
|
457
|
+
{
|
|
458
|
+
"change": "etl-surveydb-pipeline-closure",
|
|
459
|
+
"notApplicable": null,
|
|
460
|
+
"rows": [
|
|
461
|
+
{
|
|
462
|
+
"capability": "REQ-GOV-01 matching",
|
|
463
|
+
"library": "services/etl-core/src/etl_core/matcher.py",
|
|
464
|
+
"runtimeOwner": "worker job analyze_study",
|
|
465
|
+
"writes": "study_proposals",
|
|
466
|
+
"reads": "N/A",
|
|
467
|
+
"uiConsumer": "Proposals page",
|
|
468
|
+
"evidence": "tasks/12-analyze/test-evidence.md"
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
"capability": "REQ-OUT-BI star schema",
|
|
472
|
+
"library": "services/etl-core/src/etl_core/bi_star.py",
|
|
473
|
+
"runtimeOwner": "worker job harmonization_run",
|
|
474
|
+
"writes": "runs/<id>/bi/*.parquet",
|
|
475
|
+
"reads": "decisions tip + weight_map tips",
|
|
476
|
+
"uiConsumer": "Runs artifact download",
|
|
477
|
+
"evidence": "verify-evidence.md#product-loop"
|
|
478
|
+
}
|
|
479
|
+
]
|
|
480
|
+
}
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
Docs-only / no-runtime changes may set `"notApplicable": "docs-only change"` instead of rows.
|
|
484
|
+
|
|
485
|
+
Spine rows → also author the executable acceptance steps:
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
forge e2e init
|
|
489
|
+
# edit openspec/changes/<name>/e2e.json — the closed loop as commands
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
```json
|
|
493
|
+
{
|
|
494
|
+
"change": "etl-surveydb-pipeline-closure",
|
|
495
|
+
"notApplicable": null,
|
|
496
|
+
"steps": [
|
|
497
|
+
{ "name": "ingest", "cmd": "node scripts/e2e/ingest-fixture.mjs OP1086" },
|
|
498
|
+
{ "name": "analyze", "cmd": "node scripts/e2e/run-analyze.mjs", "expect": "proposals: [1-9]" },
|
|
499
|
+
{ "name": "ratify", "cmd": "node scripts/e2e/ratify-subset.mjs" },
|
|
500
|
+
{ "name": "run-assert", "cmd": "node scripts/e2e/assert-output-differs.mjs", "timeoutMs": 600000 }
|
|
501
|
+
]
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
Steps must assert domain side effects — a list that would pass against a
|
|
506
|
+
stubbed handler is invalid. `"notApplicable": "<reason>"` only when no command
|
|
507
|
+
can drive the loop.
|
|
508
|
+
|
|
509
|
+
**If wiring must wait for a later task**
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
forge defer add --task 9.7 --reason "analyze_study handler lands in 9.7"
|
|
513
|
+
# … when 9.7 is done:
|
|
514
|
+
forge defer resolve --task 9.7
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Verify** (required when spine has rows):
|
|
518
|
+
|
|
519
|
+
```bash
|
|
520
|
+
forge e2e run # executes the steps, writes e2e-results.json (session dir)
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Green run required; results go stale if `e2e.json` changes afterwards (steps
|
|
524
|
+
hash). Keep a short loop narrative under `## Product loop` in
|
|
525
|
+
`verify-evidence.md` as reviewer context — the gate checks the executed
|
|
526
|
+
results, not the heading.
|
|
527
|
+
|
|
528
|
+
Or an explicit `BLOCKED: …` line in `verify-evidence.md` — then `forge phase
|
|
529
|
+
done` refuses until unblocked or the user passes `--allow-incomplete`.
|
|
530
|
+
|
|
531
|
+
**Finish**
|
|
532
|
+
|
|
533
|
+
```bash
|
|
534
|
+
forge integrity-check # optional preview
|
|
535
|
+
forge phase done # same checks; exit 1 if incomplete
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## Subagent model
|
|
541
|
+
|
|
542
|
+
Each implementation task:
|
|
543
|
+
|
|
544
|
+
1. Coordinator writes `tasks/<nn>-<slug>/brief.md` (task text + file paths + constraints — **no chat history**).
|
|
545
|
+
2. **Implementer** subagent — must follow `skills/test-driven-development` first.
|
|
546
|
+
3. **Task reviewer** subagent (spec then quality) — unless pace skips low-risk tasks.
|
|
547
|
+
4. Mark task complete (`tasks.md` checkbox or session progress).
|
|
548
|
+
5. After all tasks: **verify** (tier 3 scope from pace) → **final reviewer** (unless pace skips) → finish.
|
|
549
|
+
|
|
550
|
+
Test tiers: [test-strategy.md](../references/test-strategy.md) — scoped TDD per task, narrow evidence per task, full workspace **once** at verify when pace requires it (not every task).
|
|
551
|
+
|
|
552
|
+
### Model selection (capability × billing)
|
|
553
|
+
|
|
554
|
+
Subagents resolve models through **two axes** so Cursor / Claude Code / Codex stay on **subscription/included** pools by default:
|
|
555
|
+
|
|
556
|
+
| Axis | Values | Default |
|
|
557
|
+
| ---- | ------ | ------- |
|
|
558
|
+
| Capability | `fast` · `standard` · `capable` | role-based |
|
|
559
|
+
| Billing | `included` · `metered` | **`included`** |
|
|
560
|
+
|
|
561
|
+
```bash
|
|
562
|
+
forge resolve-model --tier standard # JSON: { model, omitModel, billing, … }
|
|
563
|
+
forge models # print effective billing (no file write)
|
|
564
|
+
forge models metered # WRITE .forge/models.local.json
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
- Defaults: `packages/cli/src/models.defaults.json` (Cursor `included` = `inherit` → omit Task `model`).
|
|
568
|
+
- Local overlay is optional — see **Checkout-local overrides** above.
|
|
569
|
+
- **Never invent** host model slugs; honor `omitModel` / `model` from the resolver.
|
|
570
|
+
- Escalate **capability** within `included` on `BLOCKED`; switch to `metered` only on explicit user request.
|
|
571
|
+
- Keep the **parent** session on Auto/Composer (Cursor) or Max (Claude Code) — `inherit` follows the parent.
|
|
572
|
+
|
|
573
|
+
Guardrails in every subagent brief (honor the **project’s** agent docs too):
|
|
574
|
+
|
|
575
|
+
- No autonomous `git commit` / push unless the user asks
|
|
576
|
+
- Implementer runs tier 1 (scoped) + tier 2 (narrow) tests; coordinator saves `tasks/<nn>-<slug>/test-evidence.md` before marking task done
|
|
577
|
+
- Trace downstream consumers when contracts change
|
|
578
|
+
|
|
579
|
+
Prompt templates: [subagents/](../subagents/)
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
## Bundled skills (self-contained)
|
|
584
|
+
|
|
585
|
+
Forge vendors adapted Superpowers skills (MIT) under `skills/forge/skills/`.
|
|
586
|
+
See [skills/NOTICE.md](../skills/NOTICE.md).
|
|
587
|
+
|
|
588
|
+
| Skill | Purpose |
|
|
589
|
+
| ----- | ------- |
|
|
590
|
+
| brainstorming | Brainstorm phase |
|
|
591
|
+
| test-driven-development | Implement — per task |
|
|
592
|
+
| subagent-driven-development | Implement — orchestration |
|
|
593
|
+
| systematic-debugging | Blockers during implement |
|
|
594
|
+
| verification-before-completion | Verify phase |
|
|
595
|
+
| requesting-code-review | Review phase |
|
|
596
|
+
|
|
597
|
+
The bundled skills are a **maintained fork** of Superpowers (MIT — see `skills/NOTICE.md`), restructured for Forge (single task reviewer, tiered testing, trimmed prose). Do not re-vendor from upstream; edit `skills/forge/` in this repo and run `forgekit install --skills forge --force`.
|
|
598
|
+
|
|
599
|
+
## Relationship to OpenSpec
|
|
600
|
+
|
|
601
|
+
| Piece | Source | Policy |
|
|
602
|
+
| ----- | ------ | ------ |
|
|
603
|
+
| Brainstorm, TDD, subagents, verify, review | **skills/forge/skills/** (bundled) | Self-contained; Superpowers plugin not required |
|
|
604
|
+
| Planning sink | OpenSpec or built-in specs engine | Engine per project (`.forge/config.json`); no throwaway or direct modes for new work |
|
|
605
|
+
| OpenSpec skills | Vendor (`openspec-*`, `opsx:*`) | **Do not hand-edit** — run `forge overlay` after upgrade |
|
|
606
|
+
| OpenSpec implement | Forge **`/forge:apply`** | Full subagent TDD + verify + review; survives OpenSpec upgrades |
|
|
607
|
+
| Archive follow-up | Optional ADRs (`forge init --adr`) | When `.forge/config.json` has `adr.enabled`, run **archive-to-adr** (path from `adr.dir`, default `docs/adr`) |
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
611
|
+
## Agent surfaces
|
|
612
|
+
|
|
613
|
+
Same workflow across Cursor, Claude Code, and Codex CLI. Install the skill once
|
|
614
|
+
per machine with `forgekit install`; wire project commands/hooks with `forge init`.
|
|
615
|
+
|
|
616
|
+
| Agent | Skill (after install) | Project wiring (`forge init`) | Session hooks |
|
|
617
|
+
| ----- | --------------------- | ----------------------------- | ------------- |
|
|
618
|
+
| **Cursor** | `~/.cursor/skills/forge/` | commands, `forge.mdc`, SessionStart hook | SessionStart → active session reminder |
|
|
619
|
+
| **Claude Code** | `~/.claude/skills/forge/` | commands, `forge.md`, SessionStart + prompt hooks | SessionStart + substantial-work UserPromptSubmit + `/forge` UserPromptSubmit |
|
|
620
|
+
| **Codex CLI** | `~/.codex/skills/forge/` | thin rule | *(none — read skill on substantial work)* |
|
|
621
|
+
|
|
622
|
+
### Slash commands (Cursor + Claude Code)
|
|
623
|
+
|
|
624
|
+
| Command | Purpose |
|
|
625
|
+
| ------- | ------- |
|
|
626
|
+
| `/forge` | Start or resume current phase |
|
|
627
|
+
| `/forge:brainstorm` | Brainstorm only |
|
|
628
|
+
| `/forge:plan` | Tracked-change propose (engine from `.forge/config.json`) |
|
|
629
|
+
| `/forge:apply` | Tracked-change implement + verify + review (preferred) |
|
|
630
|
+
| `/forge:build` | Implement phase (`tasks.md` from either engine) |
|
|
631
|
+
| `/forge:status` | Session progress |
|
|
632
|
+
| `/forge:harness` | Ensure a working, recorded project e2e harness |
|
|
633
|
+
| `/forge:analyze` | Improvement report over recent sessions |
|
|
634
|
+
| `/forge:skip` | Explicit skip for this task |
|
|
635
|
+
|
|
636
|
+
### Codex CLI
|
|
637
|
+
|
|
638
|
+
No slash commands. On substantial work: read the **`forge`** skill, check
|
|
639
|
+
`forge status`, bootstrap with `forge new <slug>` when needed.
|
|
640
|
+
After brainstorm, proceed directly to the configured engine's propose flow — see
|
|
641
|
+
[plan-routing.md](../references/plan-routing.md).
|
|
642
|
+
User can say “skip forge” or `/forge:skip` to opt out.
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
## What we deliberately dropped from Superpowers
|
|
647
|
+
|
|
648
|
+
- `docs/superpowers/plans/` and `docs/superpowers/specs/` — use OpenSpec / `specs/changes/` + `.forge` (the built-in specs engine covers the no-OpenSpec case with an OpenSpec-compatible layout)
|
|
649
|
+
- Mandatory git worktree per brainstorm — optional
|
|
650
|
+
- Autonomous commits in subagent prompts — forbidden unless the user asks
|