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