@garygentry/feature-forge 0.1.4 → 0.1.5

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 (188) hide show
  1. package/README.md +1 -1
  2. package/adapters/GENERATION-REPORT.md +5 -1
  3. package/adapters/claude/references/forge-config-schema.json +36 -10
  4. package/adapters/claude/references/pipeline-state-schema.json +4 -0
  5. package/adapters/claude/references/process-overview.md +14 -4
  6. package/adapters/claude/references/shared-conventions.md +46 -0
  7. package/adapters/claude/references/templates/specs-hygiene/AGENTS.md +23 -0
  8. package/adapters/claude/references/templates/specs-hygiene/CLAUDE.md +22 -0
  9. package/adapters/claude/skills/forge-0-epic/SKILL.md +7 -5
  10. package/adapters/claude/skills/forge-1-prd/SKILL.md +4 -2
  11. package/adapters/claude/skills/forge-5-loop/SKILL.md +18 -16
  12. package/adapters/claude/skills/forge-5-loop/references/result-reporting.md +13 -0
  13. package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +40 -0
  14. package/adapters/claude/skills/forge-6-docs/SKILL.md +10 -0
  15. package/adapters/claude/skills/forge-bootstrap/SKILL.md +240 -0
  16. package/adapters/claude/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
  17. package/adapters/claude/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
  18. package/adapters/claude/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
  19. package/adapters/claude/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
  20. package/adapters/claude/skills/forge-bootstrap/references/templates/go/main.go +12 -0
  21. package/adapters/claude/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
  22. package/adapters/claude/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
  23. package/adapters/claude/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
  24. package/adapters/claude/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
  25. package/adapters/claude/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
  26. package/adapters/claude/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
  27. package/adapters/claude/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
  28. package/adapters/claude/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
  29. package/adapters/claude/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
  30. package/adapters/claude/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
  31. package/adapters/claude/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
  32. package/adapters/claude/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
  33. package/adapters/claude/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
  34. package/adapters/claude/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
  35. package/adapters/claude/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
  36. package/adapters/claude/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
  37. package/adapters/claude/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
  38. package/adapters/claude/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
  39. package/adapters/codex/references/forge-config-schema.json +36 -10
  40. package/adapters/codex/references/pipeline-state-schema.json +4 -0
  41. package/adapters/codex/references/process-overview.md +14 -4
  42. package/adapters/codex/references/shared-conventions.md +46 -0
  43. package/adapters/codex/references/templates/specs-hygiene/AGENTS.md +23 -0
  44. package/adapters/codex/references/templates/specs-hygiene/CLAUDE.md +22 -0
  45. package/adapters/codex/skills/forge-0-epic/forge-0-epic.md +7 -5
  46. package/adapters/codex/skills/forge-1-prd/forge-1-prd.md +4 -2
  47. package/adapters/codex/skills/forge-5-loop/forge-5-loop.md +18 -16
  48. package/adapters/codex/skills/forge-5-loop/references/result-reporting.md +13 -0
  49. package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +40 -0
  50. package/adapters/codex/skills/forge-6-docs/forge-6-docs.md +10 -0
  51. package/adapters/codex/skills/forge-bootstrap/forge-bootstrap.md +239 -0
  52. package/adapters/codex/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
  53. package/adapters/codex/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
  54. package/adapters/codex/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
  55. package/adapters/codex/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
  56. package/adapters/codex/skills/forge-bootstrap/references/templates/go/main.go +12 -0
  57. package/adapters/codex/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
  58. package/adapters/codex/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
  59. package/adapters/codex/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
  60. package/adapters/codex/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
  61. package/adapters/codex/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
  62. package/adapters/codex/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
  63. package/adapters/codex/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
  64. package/adapters/codex/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
  65. package/adapters/codex/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
  66. package/adapters/codex/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
  67. package/adapters/codex/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
  68. package/adapters/codex/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
  69. package/adapters/codex/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
  70. package/adapters/codex/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
  71. package/adapters/codex/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
  72. package/adapters/codex/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
  73. package/adapters/codex/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
  74. package/adapters/codex/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
  75. package/adapters/copilot/references/forge-config-schema.json +36 -10
  76. package/adapters/copilot/references/pipeline-state-schema.json +4 -0
  77. package/adapters/copilot/references/process-overview.md +14 -4
  78. package/adapters/copilot/references/shared-conventions.md +46 -0
  79. package/adapters/copilot/references/templates/specs-hygiene/AGENTS.md +23 -0
  80. package/adapters/copilot/references/templates/specs-hygiene/CLAUDE.md +22 -0
  81. package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +7 -5
  82. package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +4 -2
  83. package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +18 -16
  84. package/adapters/copilot/skills/forge-5-loop/references/result-reporting.md +13 -0
  85. package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +40 -0
  86. package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +10 -0
  87. package/adapters/copilot/skills/forge-bootstrap/forge-bootstrap.md +239 -0
  88. package/adapters/copilot/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
  89. package/adapters/copilot/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
  90. package/adapters/copilot/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
  91. package/adapters/copilot/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
  92. package/adapters/copilot/skills/forge-bootstrap/references/templates/go/main.go +12 -0
  93. package/adapters/copilot/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
  94. package/adapters/copilot/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
  95. package/adapters/copilot/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
  96. package/adapters/copilot/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
  97. package/adapters/copilot/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
  98. package/adapters/copilot/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
  99. package/adapters/copilot/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
  100. package/adapters/copilot/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
  101. package/adapters/copilot/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
  102. package/adapters/copilot/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
  103. package/adapters/copilot/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
  104. package/adapters/copilot/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
  105. package/adapters/copilot/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
  106. package/adapters/copilot/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
  107. package/adapters/copilot/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
  108. package/adapters/copilot/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
  109. package/adapters/copilot/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
  110. package/adapters/copilot/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
  111. package/adapters/cursor/references/forge-config-schema.json +36 -10
  112. package/adapters/cursor/references/pipeline-state-schema.json +4 -0
  113. package/adapters/cursor/references/process-overview.md +14 -4
  114. package/adapters/cursor/references/shared-conventions.md +46 -0
  115. package/adapters/cursor/references/templates/specs-hygiene/AGENTS.md +23 -0
  116. package/adapters/cursor/references/templates/specs-hygiene/CLAUDE.md +22 -0
  117. package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +7 -5
  118. package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +4 -2
  119. package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +18 -16
  120. package/adapters/cursor/skills/forge-5-loop/references/result-reporting.md +13 -0
  121. package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +40 -0
  122. package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +10 -0
  123. package/adapters/cursor/skills/forge-bootstrap/forge-bootstrap.mdc +240 -0
  124. package/adapters/cursor/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
  125. package/adapters/cursor/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
  126. package/adapters/cursor/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
  127. package/adapters/cursor/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
  128. package/adapters/cursor/skills/forge-bootstrap/references/templates/go/main.go +12 -0
  129. package/adapters/cursor/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
  130. package/adapters/cursor/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
  131. package/adapters/cursor/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
  132. package/adapters/cursor/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
  133. package/adapters/cursor/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
  134. package/adapters/cursor/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
  135. package/adapters/cursor/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
  136. package/adapters/cursor/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
  137. package/adapters/cursor/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
  138. package/adapters/cursor/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
  139. package/adapters/cursor/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
  140. package/adapters/cursor/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
  141. package/adapters/cursor/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
  142. package/adapters/cursor/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
  143. package/adapters/cursor/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
  144. package/adapters/cursor/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
  145. package/adapters/cursor/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
  146. package/adapters/cursor/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
  147. package/adapters/gemini/gemini-extension.json +4 -0
  148. package/adapters/gemini/references/forge-config-schema.json +36 -10
  149. package/adapters/gemini/references/pipeline-state-schema.json +4 -0
  150. package/adapters/gemini/references/process-overview.md +14 -4
  151. package/adapters/gemini/references/shared-conventions.md +46 -0
  152. package/adapters/gemini/references/templates/specs-hygiene/AGENTS.md +23 -0
  153. package/adapters/gemini/references/templates/specs-hygiene/CLAUDE.md +22 -0
  154. package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +7 -5
  155. package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +4 -2
  156. package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +18 -16
  157. package/adapters/gemini/skills/forge-5-loop/references/result-reporting.md +13 -0
  158. package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +40 -0
  159. package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +10 -0
  160. package/adapters/gemini/skills/forge-bootstrap/forge-bootstrap.md +239 -0
  161. package/adapters/gemini/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
  162. package/adapters/gemini/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
  163. package/adapters/gemini/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
  164. package/adapters/gemini/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
  165. package/adapters/gemini/skills/forge-bootstrap/references/templates/go/main.go +12 -0
  166. package/adapters/gemini/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
  167. package/adapters/gemini/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
  168. package/adapters/gemini/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
  169. package/adapters/gemini/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
  170. package/adapters/gemini/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
  171. package/adapters/gemini/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
  172. package/adapters/gemini/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
  173. package/adapters/gemini/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
  174. package/adapters/gemini/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
  175. package/adapters/gemini/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
  176. package/adapters/gemini/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
  177. package/adapters/gemini/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
  178. package/adapters/gemini/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
  179. package/adapters/gemini/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
  180. package/adapters/gemini/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
  181. package/adapters/gemini/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
  182. package/adapters/gemini/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
  183. package/adapters/gemini/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
  184. package/dist/manifest.d.ts +1 -1
  185. package/dist/rauf.d.ts +4 -4
  186. package/dist/rauf.js +3 -3
  187. package/dist/types.d.ts +1 -1
  188. package/package.json +1 -1
package/README.md CHANGED
@@ -53,7 +53,7 @@ Claude Code users can alternatively install via the plugin marketplace:
53
53
 
54
54
  The default loop runner is [**rauf**](https://github.com/garygentry/rauf), published as
55
55
  [`@garygentry/rauf`](https://www.npmjs.com/package/@garygentry/rauf). The installer runs a
56
- read-only resolvability preflight on the pin (`@garygentry/rauf@0.7.0`) and records it; pass
56
+ read-only resolvability preflight on the pin (`@garygentry/rauf@0.8.0`) and records it; pass
57
57
  `--skip-rauf` to defer the check (e.g. offline installs). Install the rauf CLI itself with
58
58
  `npx @garygentry/rauf` or its
59
59
  [binary script](https://github.com/garygentry/rauf#install). See the
@@ -31,6 +31,7 @@ _No dropped constructs — every canonical construct is representable in this ag
31
31
  | `skills/forge-4-backlog/SKILL.md` | `argument-hint` | no confirmed Codex invocation-hint field (TQ-1) |
32
32
  | `skills/forge-5-loop/SKILL.md` | `argument-hint` | no confirmed Codex invocation-hint field (TQ-1) |
33
33
  | `skills/forge-6-docs/SKILL.md` | `argument-hint` | no confirmed Codex invocation-hint field (TQ-1) |
34
+ | `skills/forge-bootstrap/SKILL.md` | `argument-hint` | no confirmed Codex invocation-hint field (TQ-1) |
34
35
  | `skills/forge-fix/SKILL.md` | `argument-hint` | no confirmed Codex invocation-hint field (TQ-1) |
35
36
  | `skills/forge-verify/SKILL.md` | `argument-hint` | no confirmed Codex invocation-hint field (TQ-1) |
36
37
  | `skills/forge/SKILL.md` | `argument-hint` | no confirmed Codex invocation-hint field (TQ-1) |
@@ -58,6 +59,7 @@ _No dropped constructs — every canonical construct is representable in this ag
58
59
  | `skills/forge-4-backlog/SKILL.md` | `argument-hint` | no known Copilot invocation-hint field (TQ-1) |
59
60
  | `skills/forge-5-loop/SKILL.md` | `argument-hint` | no known Copilot invocation-hint field (TQ-1) |
60
61
  | `skills/forge-6-docs/SKILL.md` | `argument-hint` | no known Copilot invocation-hint field (TQ-1) |
62
+ | `skills/forge-bootstrap/SKILL.md` | `argument-hint` | no known Copilot invocation-hint field (TQ-1) |
61
63
  | `skills/forge-fix/SKILL.md` | `argument-hint` | no known Copilot invocation-hint field (TQ-1) |
62
64
  | `skills/forge-verify/SKILL.md` | `argument-hint` | no known Copilot invocation-hint field (TQ-1) |
63
65
  | `skills/forge/SKILL.md` | `argument-hint` | no known Copilot invocation-hint field (TQ-1) |
@@ -85,6 +87,7 @@ _No dropped constructs — every canonical construct is representable in this ag
85
87
  | `skills/forge-4-backlog/SKILL.md` | `argument-hint` | no Cursor .mdc invocation-hint field |
86
88
  | `skills/forge-5-loop/SKILL.md` | `argument-hint` | no Cursor .mdc invocation-hint field |
87
89
  | `skills/forge-6-docs/SKILL.md` | `argument-hint` | no Cursor .mdc invocation-hint field |
90
+ | `skills/forge-bootstrap/SKILL.md` | `argument-hint` | no Cursor .mdc invocation-hint field |
88
91
  | `skills/forge-fix/SKILL.md` | `argument-hint` | no Cursor .mdc invocation-hint field |
89
92
  | `skills/forge-verify/SKILL.md` | `argument-hint` | no Cursor .mdc invocation-hint field |
90
93
  | `skills/forge/SKILL.md` | `argument-hint` | no Cursor .mdc invocation-hint field |
@@ -112,6 +115,7 @@ _No dropped constructs — every canonical construct is representable in this ag
112
115
  | `skills/forge-4-backlog/SKILL.md` | `argument-hint` | Gemini manifest hint field unconfirmed (TQ-1) |
113
116
  | `skills/forge-5-loop/SKILL.md` | `argument-hint` | Gemini manifest hint field unconfirmed (TQ-1) |
114
117
  | `skills/forge-6-docs/SKILL.md` | `argument-hint` | Gemini manifest hint field unconfirmed (TQ-1) |
118
+ | `skills/forge-bootstrap/SKILL.md` | `argument-hint` | Gemini manifest hint field unconfirmed (TQ-1) |
115
119
  | `skills/forge-fix/SKILL.md` | `argument-hint` | Gemini manifest hint field unconfirmed (TQ-1) |
116
120
  | `skills/forge-verify/SKILL.md` | `argument-hint` | Gemini manifest hint field unconfirmed (TQ-1) |
117
121
  | `skills/forge/SKILL.md` | `argument-hint` | Gemini manifest hint field unconfirmed (TQ-1) |
@@ -121,7 +125,7 @@ _No dropped constructs — every canonical construct is representable in this ag
121
125
  These files are transported byte-for-byte from canon into every `adapters/<agent>/` bundle and intentionally carry **no** provenance header (a header would break byte-identity / corrupt parsed files):
122
126
 
123
127
  - `scripts/forge-root.sh` → `adapters/<agent>/scripts/forge-root.sh` (mode 0755, byte-identical — REQ-GEN-05).
124
- - the whole repo-root `references/` tree (14 files: 9 root + `stacks/`×5) → `adapters/<agent>/references/` (verbatim — REQ-GEN-04 / D5).
128
+ - the whole repo-root `references/` tree (16 files: 9 root + `stacks/`×5 + `templates/specs-hygiene/`×2) → `adapters/<agent>/references/` (verbatim — REQ-GEN-04 / D5).
125
129
  - each skill's own `references/` subdir → `adapters/<agent>/skills/<name>/references/` (verbatim, where present).
126
130
 
127
131
  Regenerate all adapter output with `python3 scripts/build-adapters.py`.
@@ -15,8 +15,8 @@
15
15
  "description": "Root directory for generated architecture documentation."
16
16
  },
17
17
  "backlogDir": {
18
- "type": "string",
19
- "description": "Optional override for backlog location. If set, backlog.json is written here instead of with the feature specs. Default behavior: backlog.json is written to {specsDir}/{feature}/backlog.json."
18
+ "type": ["string", "null"],
19
+ "description": "Optional override for backlog location. If set, backlog.json is written here instead of with the feature specs. Default behavior (null): backlog.json is written to {specsDir}/{feature}/backlog.json."
20
20
  },
21
21
  "gitCommitAfterStage": {
22
22
  "type": "boolean",
@@ -28,17 +28,27 @@
28
28
  "default": "forge",
29
29
  "description": "Prefix for conventional commit messages, e.g., forge(auth): complete PRD"
30
30
  },
31
- "stack": {
31
+ "branchPerFeature": {
32
+ "type": "boolean",
33
+ "default": true,
34
+ "description": "Offer to create an isolated git branch when a feature/epic starts on the default branch (main/master). Gated only on the project using git — independent of gitCommitAfterStage. When false, forge never prompts for a branch and works on whatever branch is checked out. See the Branch Setup block in references/shared-conventions.md."
35
+ },
36
+ "branchPrefix": {
32
37
  "type": "string",
33
- "description": "Detected or configured project stack identifier. Selects guidance from references/stacks/{stack}.md. Set during forge-2-tech or manually. Examples: 'typescript', 'python', 'go', 'rust'."
38
+ "default": "forge/",
39
+ "description": "Prefix for the branch name suggested by Branch Setup, e.g. 'forge/' yields 'forge/{feature}' or 'forge/{epic}'. Ignored when branchPerFeature is false."
40
+ },
41
+ "stack": {
42
+ "type": ["string", "null"],
43
+ "description": "Detected or configured project stack identifier. Selects guidance from references/stacks/{stack}.md. Set during forge-2-tech or manually (null until then). Examples: 'typescript', 'python', 'go', 'rust'."
34
44
  },
35
45
  "typeCheckCommand": {
36
- "type": "string",
37
- "description": "Command to verify type correctness or lint. Examples: 'bun run typecheck', 'mypy .', 'go vet ./...'. Used in acceptance criteria and verification."
46
+ "type": ["string", "null"],
47
+ "description": "Command to verify type correctness or lint. Null until set. Examples: 'bun run typecheck', 'mypy .', 'go vet ./...'. Used in acceptance criteria and verification."
38
48
  },
39
49
  "testCommand": {
40
- "type": "string",
41
- "description": "Command to run tests. Examples: 'bun test', 'pytest', 'go test ./...'. Used in acceptance criteria and verification."
50
+ "type": ["string", "null"],
51
+ "description": "Command to run tests. Null until set. Examples: 'bun test', 'pytest', 'go test ./...'. Used in acceptance criteria and verification."
42
52
  },
43
53
  "loopIterationMultiplier": {
44
54
  "type": "number",
@@ -46,6 +56,22 @@
46
56
  "minimum": 1,
47
57
  "description": "Multiplier applied to pending backlog item count to calculate loop iterations. Higher values allow more retries. Default: 1.5 (e.g., 10 items = 15 iterations)."
48
58
  },
59
+ "workspaces": {
60
+ "type": "array",
61
+ "description": "Monorepo members. Absent for single-package projects.",
62
+ "items": {
63
+ "type": "object",
64
+ "required": ["name", "path", "stack"],
65
+ "additionalProperties": false,
66
+ "properties": {
67
+ "name": {"type": "string"},
68
+ "path": {"type": "string", "description": "Repo-relative member dir"},
69
+ "stack": {"type": "string"},
70
+ "typeCheckCommand": {"type": ["string", "null"]},
71
+ "testCommand": {"type": ["string", "null"]}
72
+ }
73
+ }
74
+ },
49
75
  "loopRunner": {
50
76
  "type": "object",
51
77
  "description": "The autonomous loop runner feature-forge drives. Defaults to rauf when absent (forge-5 states 'defaulting to rauf loop runner'). Every command is a template — {bin}, {backlogDir}, {specsDir}, {iterations} are substituted at call time — so an alternative ralph-style runner conforming to rauf's SPEC-BACKLOG-TOOL-CONTRACT.md can be swapped in without editing any skill. See references/ralph-loop-contract.md.",
@@ -147,8 +173,8 @@
147
173
  },
148
174
  "installHint": {
149
175
  "type": "string",
150
- "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.7.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.7.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
151
- "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.7.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
176
+ "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.8.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.8.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
177
+ "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.8.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
152
178
  },
153
179
  "schemaVersion": {
154
180
  "type": "string",
@@ -18,6 +18,10 @@
18
18
  "type": "string",
19
19
  "description": "Back-pointer to the owning epic's name. Absent for standalone features. The epic-manifest.json is canonical on conflict (REQ-STATE-01)."
20
20
  },
21
+ "branch": {
22
+ "type": "string",
23
+ "description": "Git branch this feature's pipeline work is intended to land on, recorded by the Branch Setup block (shared-conventions.md) at the entry stage. Absent when the project isn't a git repo or branchPerFeature is false. Downstream stages and forge-5-loop compare the current branch against this to detect drift back onto the default branch before committing."
24
+ },
21
25
  "createdAt": {
22
26
  "type": "string",
23
27
  "format": "date-time"
@@ -2,12 +2,20 @@
2
2
 
3
3
  This document describes the end-to-end feature development pipeline managed by the feature-forge plugin. All forge skills reference this document to understand the overall flow and their position within it.
4
4
 
5
+ The pipeline compiles a fuzzy feature idea into a machine-executable `backlog.json`. Each stage narrows the idea down and adds structure, verification gates catch gaps before they reach later stages, and a swappable autonomous loop runner (rauf by default) implements the backlog in fresh per-item sessions.
6
+
5
7
  ## Pipeline Stages
6
8
 
7
9
  ```
8
- forge-1-prd → forge-2-tech → forge-3-specs → forge-verify → forge-4-backlog → forge-verify → forge-5-loop → forge-verify → forge-6-docs
10
+ [forge-0-epic] → forge-1-prd → forge-2-tech → forge-3-specs → forge-verify → forge-4-backlog → forge-verify → forge-5-loop → forge-verify → forge-6-docs
11
+ (optional)
9
12
  ```
10
13
 
14
+ ### Stage 0: Epic (`/feature-forge:forge-0-epic <epic>`), optional
15
+ **Input:** A change too large for one feature
16
+ **Output:** `{specsDir}/{epic}/epic-manifest.json` + `EPIC.md` + one member-feature dir per feature
17
+ **Method:** Decomposition interview splitting the change into member features with declared dependencies and `exposes`/`consumes` contracts. Purely additive: single-feature flows are unchanged. See [docs/architecture/epic-orchestration/README.md](../docs/architecture/epic-orchestration/README.md).
18
+
11
19
  ### Stage 1: PRD (`/feature-forge:forge-1-prd <feature>`)
12
20
  **Input:** User's feature idea and domain knowledge
13
21
  **Output:** `{specsDir}/{feature}/PRD.md`
@@ -35,13 +43,13 @@ After verification, fixes can be applied via:
35
43
 
36
44
  ### Stage 4: Backlog (`/feature-forge:forge-4-backlog <feature>`)
37
45
  **Input:** Full spec suite
38
- **Output:** `{specsDir}/{feature}/backlog.json` (or `{backlogDir}/backlog.json` if backlogDir is configured)
46
+ **Output:** `{specsDir}/{feature}/backlog.json` (or `{backlogDir}/{feature}/backlog.json` if backlogDir is configured)
39
47
  **Method:** Generate structured backlog items with spec references, acceptance criteria, and dependencies. Backlog is collocated with feature specs by default.
40
48
 
41
49
  ### Stage 5: Rauf Loop (`/feature-forge:forge-5-loop <feature>`)
42
50
  **Input:** `backlog.json` from Stage 4
43
51
  **Output:** Implemented source code (committed per-item by rauf)
44
- **Method:** Execute the rauf autonomous coding loop against the feature's backlog. Spawns a fresh Claude Code session per backlog item with full spec context.
52
+ **Method:** Execute the autonomous coding loop against the feature's backlog. Spawns a fresh session per backlog item with full spec context. rauf is the default runner but is swappable via the `loopRunner` block in `forge.config.json`; see [`references/ralph-loop-contract.md`](./ralph-loop-contract.md).
45
53
 
46
54
  ### Stage 6: Documentation (`/feature-forge:forge-6-docs <feature>`)
47
55
  **Input:** Specs + implementation
@@ -71,7 +79,9 @@ Read `forge.config.json` from project root for path overrides. See `references/f
71
79
 
72
80
  ## Git Workflow
73
81
 
74
- Recommended: create a `forge/{feature}` branch before starting the pipeline. All forge commits go to this branch. After implementation, merge to your development branch.
82
+ Recommended: forge work lives on an isolated `forge/{feature}` (or `forge/{epic}`) branch so all commits land together and review as one branch. The entry stages (`forge-1-prd`, `forge-0-epic`) detect whether you're on the default branch (main/master) and **strongly recommend** creating that branch when you are — still letting you decline and stay. The chosen branch is recorded in `.pipeline-state.json`, and `forge-5-loop` re-checks it before the autonomous loop starts committing per item. After implementation, merge to your development branch.
83
+
84
+ To customize: `branchPrefix` (default `forge/`) sets the branch name, and `branchPerFeature: false` disables the prompt entirely (forge then works on whatever branch is checked out). Branch Setup is gated only on the project using git — independent of `gitCommitAfterStage`.
75
85
 
76
86
  If you prefer manual commit control, set `gitCommitAfterStage: false` in `forge.config.json`.
77
87
 
@@ -48,6 +48,8 @@ Extract these config values (use defaults if not present):
48
48
  - `backlogDir` (default: null — backlog lives at `{specsDir}/{feature}/backlog.json`; when `backlogDir` is configured, forge-4 composes `{backlogDir}/{feature}/`)
49
49
  - `gitCommitAfterStage` (default: true)
50
50
  - `commitPrefix` (default: `forge`)
51
+ - `branchPerFeature` (default: true)
52
+ - `branchPrefix` (default: `forge/`)
51
53
  - `loopIterationMultiplier` (default: `1.5`)
52
54
  - `loopRunner` (optional object — the loop runner to drive; **defaults to rauf** when absent, with every command templated. See `references/forge-config-schema.json` and `references/ralph-loop-contract.md`.)
53
55
 
@@ -79,6 +81,27 @@ A directory counts as a **feature** only if it directly contains a `.pipeline-st
79
81
 
80
82
  **Compatibility:** for a standalone feature the resolver returns its flat path with no epic logic engaged (REQ-COMPAT-01/02) — standalone-feature behavior is unchanged. A pre-existing latent name collision is reported for manual cleanup by the navigator / forge-verify epic mode (CHECK-E08), not by aborting an unrelated command whose name resolves to exactly one dir (tech-spec §3.4).
81
83
 
84
+ ## Specs Directory Hygiene
85
+
86
+ Whenever a stage creates the specs tree for the first time (the first PRD or epic written under `{specsDir}/`), ensure a spec-directory agent-instruction file exists at the **specsDir root**. This tells coding agents in the project that the specs here are pre-implementation artifacts — not live contracts to enforce against the code. It is **idempotent: never overwrite an existing file** (the project may have edited it).
87
+
88
+ Run this after creating the feature/epic directory, before the stage's git commit:
89
+
90
+ ```bash
91
+ R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
92
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
93
+ mkdir -p "<specsDir>"
94
+ [ -f "<specsDir>/AGENTS.md" ] || cp "$R/references/templates/specs-hygiene/AGENTS.md" "<specsDir>/AGENTS.md"
95
+ ```
96
+
97
+ If the host is Claude (the `AskUserQuestion` tool is available), also ensure the Claude-framed variant:
98
+
99
+ ```bash
100
+ [ -f "<specsDir>/CLAUDE.md" ] || cp "$R/references/templates/specs-hygiene/CLAUDE.md" "<specsDir>/CLAUDE.md"
101
+ ```
102
+
103
+ Stage any file this writes (`{specsDir}/AGENTS.md`, and `{specsDir}/CLAUDE.md` when written) as part of the stage's existing git commit.
104
+
82
105
  ## Epic Context Injection
83
106
 
84
107
  After resolving the feature directory, check the feature's `.pipeline-state.json` for an `epic` back-pointer. **If absent, skip this block entirely** (standalone feature — REQ-COMPAT-01; standalone-feature behavior is unchanged). **If present**, load exactly the following context, and nothing transitive (REQ-CTX-01):
@@ -110,6 +133,29 @@ When loading upstream artifacts as prerequisites, check `basedOnVersions` in the
110
133
 
111
134
  > "This stage was built against {upstream} v{old}, but {upstream} is now at v{new}. The current artifacts may be outdated. Consider re-running this stage, or use --force to proceed with potentially stale inputs."
112
135
 
136
+ ## Branch Setup
137
+
138
+ Invoke this block at the **very start** of a pipeline entry point — `forge-1-prd` (standalone feature) and `forge-0-epic` (epic) — **before** any directory resolution or interview, so the rest of the run lands on the intended branch. `{label}` is the feature name (forge-1-prd) or epic name (forge-0-epic); `{scope}` is `feature` or `epic` correspondingly.
139
+
140
+ **Gate.** Run this block only when the project uses git (a `.git` directory resolves) **and** `branchPerFeature` is true. It is **independent of `gitCommitAfterStage`** — branch isolation matters whether or not forge auto-commits. If `branchPerFeature` is false, skip silently.
141
+
142
+ **Epic-member inheritance.** In `forge-1-prd`, if the feature has an `epic` back-pointer (an `epic` field resolves via Epic Context Injection, or the directory is nested under an epic), the epic already established the branch in `forge-0-epic`. Skip the prompt — inherit the current branch.
143
+
144
+ **Detection, then a branch-aware prompt:**
145
+
146
+ 1. Read the current branch: `git rev-parse --abbrev-ref HEAD`.
147
+ 2. Determine the default branch: `git symbolic-ref --quiet refs/remotes/origin/HEAD` (strip to the last path segment); if that fails, fall back to `main`, else `master` — whichever the repo has.
148
+ 3. **If the current branch is NOT the default branch** (the user is already on a topic/`{branchPrefix}*` branch) → record it (see below) and proceed silently. Do not prompt.
149
+ 4. **If the current branch IS the default branch** → use `AskUserQuestion` with a **strong recommendation** (still optional):
150
+
151
+ > "You're on `{defaultBranch}`. Strongly recommended: create `{branchPrefix}{label}` so this {scope}'s work stays isolated and reviewable as one branch. Create it?"
152
+ > Options: **Create `{branchPrefix}{label}` (recommended)** · **Stay on `{defaultBranch}`**
153
+
154
+ - **Create** → `git switch -c {branchPrefix}{label}` (or `git checkout -b` if `switch` is unavailable). If the branch already exists, `git switch {branchPrefix}{label}`.
155
+ - **Stay** → proceed on the default branch; note that subsequent commits (and any `forge-5-loop` run) will land directly on `{defaultBranch}`.
156
+
157
+ **Record the branch.** After this block resolves, write the resulting branch name to the feature's `.pipeline-state.json` top-level `branch` field (create/update it when the state file is first written for this stage). Downstream stages and `forge-5-loop` read it to detect drift back onto the default branch.
158
+
113
159
  ## Git Commit Protocol
114
160
 
115
161
  When `gitCommitAfterStage` is true, follow this exact order to avoid state inconsistency:
@@ -0,0 +1,23 @@
1
+ # Agent Instructions — `specs/` (feature-forge)
2
+
3
+ This directory holds **pre-implementation design artifacts** produced by the
4
+ feature-forge pipeline (PRDs, technical specs, numbered implementation specs,
5
+ traceability matrices, and per-feature `backlog.json` files).
6
+
7
+ ## How to treat these specs
8
+
9
+ - **Specs are not live contracts.** They exist to plan the work and establish the
10
+ backlog. They are intentionally **not kept in sync** with the implementation as
11
+ the code evolves.
12
+ - **Do not flag spec↔code divergence.** Once a spec is finalized and its backlog has
13
+ been implemented, the code is the source of truth for behavior. Do not "fix" the
14
+ implementation to match a spec, or the spec to match the code, unless a human
15
+ explicitly asks for it.
16
+ - **Read freely; reference deliberately.** It is fine — encouraged, even — for
17
+ pipeline artifacts here (specs, `backlog.json`) to cite each other for provenance
18
+ and context. But implementation artifacts shipped into the project (source code,
19
+ generated skills/agents, configs, docs) should be self-contained and should **not**
20
+ reference files under `specs/`, which may be archived or deleted after a feature
21
+ ships.
22
+
23
+ This file was generated by feature-forge. Edit or remove it to suit your project.
@@ -0,0 +1,22 @@
1
+ # Claude Instructions — `specs/` (feature-forge)
2
+
3
+ This directory holds **pre-implementation design artifacts** produced by the
4
+ feature-forge pipeline (PRDs, technical specs, numbered implementation specs,
5
+ traceability matrices, and per-feature `backlog.json` files).
6
+
7
+ ## How to treat these specs
8
+
9
+ - **Specs are not live contracts.** They exist to plan the work and establish the
10
+ backlog. They are intentionally **not kept in sync** with the implementation as
11
+ the code evolves.
12
+ - **Do not flag spec↔code divergence.** Once a spec is finalized and its backlog has
13
+ been implemented, the code is the source of truth for behavior. Don't "fix" the
14
+ implementation to match a spec, or the spec to match the code, unless I explicitly
15
+ ask you to.
16
+ - **Read freely; reference deliberately.** It's fine — encouraged, even — for pipeline
17
+ artifacts here (specs, `backlog.json`) to cite each other for provenance and context.
18
+ But implementation artifacts shipped into the project (source code, generated
19
+ skills/agents, configs, docs) should be self-contained and should **not** reference
20
+ files under `specs/`, which may be archived or deleted after a feature ships.
21
+
22
+ This file was generated by feature-forge. Edit or remove it to suit your project.
@@ -87,11 +87,13 @@ python3 "$R/scripts/epic-manifest.py" check-name "{epic}" --specs-dir "{specsDir
87
87
 
88
88
  ## Creation Branch
89
89
 
90
- ### Step 1 — Branch Setup (optional)
90
+ ### Step 1 — Branch Setup
91
91
 
92
- If `gitCommitAfterStage` is true and the project uses git, use `AskUserQuestion`:
93
- "Create a `forge/{epic}` branch for this epic? (Recommended keeps epic work isolated.)"
94
- If yes, create and checkout the branch before proceeding.
92
+ Invoke the **Branch Setup** block in `references/shared-conventions.md` with `{label}` = `{epic}` and
93
+ `{scope}` = `epic`. It self-gates (skips when not a git repo or when `branchPerFeature` is false),
94
+ detects whether you're on the default branch, and strongly recommends — still optionally — creating
95
+ `{branchPrefix}{epic}` when you are. Each member feature's `forge-1-prd` inherits this branch rather
96
+ than prompting again.
95
97
 
96
98
  ### Step C1 — Epic Framing Interview
97
99
 
@@ -176,7 +178,7 @@ Compose the full `epic-manifest.json` per the 00 §2 schema, setting:
176
178
 
177
179
  Write the composed JSON to `{specsDir}/{epic}/epic-manifest.json` (creating the epic dir first).
178
180
  For the *initial* creation write the skill writes the file directly — atomic guarantees are only
179
- required for in-place mutation, which is the helper mutators' job. Then validate:
181
+ required for in-place mutation, which is the helper mutators' job. Creating the epic dir first creates `{specsDir}/`, so after writing the manifest invoke the **Specs Directory Hygiene** block in `references/shared-conventions.md` (idempotent; stage anything it writes with this stage's commit). Then validate:
180
182
 
181
183
  ```bash
182
184
  R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
@@ -16,7 +16,7 @@ Read and follow `references/shared-conventions.md` for feature name validation,
16
16
  ## Step 1: Read Configuration and Check State
17
17
 
18
18
  ### Branch Setup (if using git)
19
- If `gitCommitAfterStage` is true and the project uses git, use `AskUserQuestion` to offer: "Want me to create a `forge/{feature}` branch for this pipeline? (Recommendedkeeps forge work isolated.)" If yes, create and checkout the branch before proceeding.
19
+ Invoke the **Branch Setup** block in `references/shared-conventions.md` with `{label}` = `{feature}` and `{scope}` = `feature`. It self-gates (skips when not a git repo, when `branchPerFeature` is false, or for an epic member that inherits the epic's branch), detects whether you're on the default branch, and strongly recommends still optionally creating `{branchPrefix}{feature}` when you are. Do this before directory resolution.
20
20
 
21
21
  Set the working directory by invoking the **Feature Directory Resolution** block in `references/shared-conventions.md`, which yields `{resolvedFeatureDir}`. Note one PRD-specific caveat: at PRD time a brand-new standalone feature may have NO directory yet, so resolution is expected to fail `not-found` for a never-started standalone feature — in that case forge-1 creates `{specsDir}/{feature}/` as today. For an epic member the directory already exists (created empty by forge-0-epic with an `epic` back-pointer), so resolution succeeds and yields the nested path.
22
22
 
@@ -87,6 +87,8 @@ Once the interview is thorough, write `{resolvedFeatureDir}/PRD.md` following th
87
87
 
88
88
  Every requirement MUST have a unique ID (e.g., REQ-AUTH-01, REQ-PERF-01). These IDs are referenced by all downstream documents.
89
89
 
90
+ After writing the PRD (this is the point where `{specsDir}/{feature}/` is first created for a standalone feature), invoke the **Specs Directory Hygiene** block in `references/shared-conventions.md` to ensure `{specsDir}/AGENTS.md` (and `{specsDir}/CLAUDE.md` on the Claude host) exists. It is idempotent — it never overwrites an existing file.
91
+
90
92
  ## Step 5: Review with User
91
93
 
92
94
  Present the complete PRD to the user. Ask:
@@ -110,7 +112,7 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
110
112
  - Check downstream stages (`forge-2-tech`, `forge-3-specs`, `forge-4-backlog`, `forge-5-loop`, `forge-6-docs`). If any have `basedOnVersions` referencing an older version of `forge-1-prd`, set their status to `stale`.
111
113
  2. Use `AskUserQuestion` to ask: "Anything you want to note before we wrap? (preserved across sessions)"
112
114
  - If yes, store in the `notes` field
113
- 3. If `gitCommitAfterStage` is true, follow the Git Commit Protocol in `references/shared-conventions.md`: stage files, attempt commit with message `"{commitPrefix}({feature}): complete PRD v{n}"`, then set `stages.forge-1-prd.status` to `complete` with commit hash only on success. If commit fails, leave status as `in-progress`.
115
+ 3. If `gitCommitAfterStage` is true, follow the Git Commit Protocol in `references/shared-conventions.md`: stage files (including `{specsDir}/AGENTS.md` / `{specsDir}/CLAUDE.md` if the Specs Directory Hygiene step just wrote them), attempt commit with message `"{commitPrefix}({feature}): complete PRD v{n}"`, then set `stages.forge-1-prd.status` to `complete` with commit hash only on success. If commit fails, leave status as `in-progress`.
114
116
  5. Tell the user: "PRD complete. Next steps:\n - `/feature-forge:forge-verify {feature}` to verify the PRD\n - `/feature-forge:forge-2-tech {feature}` to start the tech spec\n - `/feature-forge:forge {feature}` to see full pipeline status"
115
117
 
116
118
  ## Gotchas
@@ -101,13 +101,8 @@ For the version-too-old case, phrase it concretely, e.g.: "Your rauf is {reporte
101
101
 
102
102
  Check that `loopRunner.preconditionFile` (default `.rauf.json`) exists in the project root. If not:
103
103
 
104
- - **If `loopRunner.name == "rauf"` and a legacy `.ralph.json` (or `.ralph/` directory) exists**, this is an un-migrated Ralph project. STOP and tell the user:
105
-
106
- "This project is still on the legacy **Ralph** layout. Run `rauf migrate .` first (the loop runner only understands `.rauf/` and `RAUF_*` signals), then re-run `/feature-forge:forge-5-loop {feature}`."
107
-
108
- - **Otherwise**, STOP and show `loopRunner.setupHint` (default: "Run `rauf install .` …"), e.g.:
109
-
110
- "The loop runner isn't set up in this project ({preconditionFile} is missing). {setupHint}"
104
+ - **If `loopRunner.name == "rauf"` and a legacy `.ralph.json` (or `.ralph/` directory) exists**, this is an un-migrated Ralph project. STOP: "This project is still on the legacy **Ralph** layout. Run `rauf migrate .` first (the loop runner only understands `.rauf/` and `RAUF_*` signals), then re-run `/feature-forge:forge-5-loop {feature}`."
105
+ - **Otherwise**, STOP and show `loopRunner.setupHint` (default: "Run `rauf install .` …"), e.g. "The loop runner isn't set up in this project ({preconditionFile} is missing). {setupHint}"
111
106
 
112
107
  ### 1e. Backlog File Check
113
108
 
@@ -117,6 +112,10 @@ Resolve the backlog file path (matching forge-4-backlog's composition rule, item
117
112
 
118
113
  Verify the file exists on disk. If not, STOP and tell the user: "No backlog.json found at {path}. Run `/feature-forge:forge-4-backlog {feature}` to generate it."
119
114
 
115
+ ### 1f. Branch Pre-flight (if using git)
116
+
117
+ The runner commits each completed item straight onto the current branch, so guard against committing onto the default branch. Skip if not a git repo or `branchPerFeature` is false. Read the current branch (`git rev-parse --abbrev-ref HEAD`) and default branch (`git symbolic-ref --quiet refs/remotes/origin/HEAD`, else `main`/`master`). If `.pipeline-state.json` records a `branch` that differs from the current one, warn via `AskUserQuestion` (offer **switch back** or **proceed here**). Otherwise, if the current branch **is** the default, strongly recommend via `AskUserQuestion` creating/switching to `{branchPrefix}{feature}` (`git switch -c`, then record it to the state `branch` field) before the loop commits — still allowing **proceed on `{defaultBranch}`**. Never hard-stop.
118
+
120
119
  ## Step 2: Construct the Loop Command
121
120
 
122
121
  ### 2a. Analyze Backlog
@@ -180,6 +179,7 @@ For the full loop-runner contract — event-stream vs. log-fallback launch, the
180
179
  - **(b) Agent question.** Add an **"agent"** question to the same `AskUserQuestion` surface: **one option per advertised row** labelled `"{displayName} ({id}) — available/not found"`, **plus an explicit `"default (claude-cli)"` choice mapping to `run_selection = None`**. Resolve the pick (run > project, empty/whitespace unset, an explicit runner-default pick collapses to the default path) into `{resolved.agent, resolved.source}`. Precedence: `item.provider > --agent > project defaultAgent > runner default` (forge never reads a backlog item's provider).
181
180
  - **(c) Availability listing.** From the **same** parsed `agents[]` (no second probe), list `id` / `displayName` / available (`yes`/`no`, `detail` on unavailable rows).
182
181
  - **(d) Verdict** — only for a **non-default** resolved agent (default path `None`/`claude-cli` → no probe, byte-identical to today). Classify by **membership** then `available` (never by exit code): **UNKNOWN** (`∉` set) → **hard-reject BEFORE any loop side-effect**, error lists the **sorted** valid ids, **NO proceed-anyway**; **UNAVAILABLE** (member, `available False`) → warn with `detail`, `AskUserQuestion` offering **proceed-anyway OR choose-another** (re-presents the same `agents[]`), never silent; **AVAILABLE** → proceed, the validated id fills `{agent}`; **probe failure** (non-zero exit / unparseable / missing or empty `agents[]` / row lacking `id`) → surface it, offer **choose-another OR abort**, **never launch the non-default agent unvalidated** and never silently fall back to the default.
182
+ - **(d-model) Claude-only model-alias guard.** Runs **only** when the resolved agent is **non-default** (not the default / `claude-cli` path). Read the backlog.json (Step 1e path); collect items whose `model` is a **Claude-specific alias** (tier `opus`/`sonnet`/`haiku` or a `claude-*` id). **If none, skip silently.** Otherwise warn before launch via `AskUserQuestion` (NOT prose): `item.model` outranks `--agent`, so the alias is forwarded verbatim to `{agent}`, which will likely reject it (e.g. codex 400 *"The 'sonnet' model is not supported…"*) — every spawn exits 1 and rauf circuit-breaks (*"3 consecutive infra failures — halting"*) with no hint of the cause. Offer: **(1) Strip `model` for this run (recommended)** — rewrite backlog.json removing the `model` key from each affected item (persistent edit; re-run forge-4-backlog to restore), then proceed; **(2) Proceed as-is** — only safe if `{agent}` understands the pinned ids. forge touches only `model`, never `provider`. Full rationale: `references/runner-contract.md`.
183
183
  - **(e) Optional-flags line.** Replace the confirmation's optional-flags line with one that lists `--agent <id>` first plus the agent precedence pointer (`item.provider > --agent > project defaultAgent > runner default`) alongside the model precedence.
184
184
  - **(f) Resolved-agent line.** Add to the confirmation block: `Agent: {resolved.agent or claude-cli} (source: {sourceLabel})` — `sourceLabel`: `RUN` → `"per-run selection"`, `PROJECT` → `"project default (loopRunner.defaultAgent)"`, `DEFAULT` → `"runner default — claude-cli"`.
185
185
 
@@ -193,11 +193,11 @@ Before launching, update `{resolvedFeatureDir}/.pipeline-state.json`:
193
193
  - Set `currentStage` to `forge-5-loop`
194
194
  - Update `updatedAt`
195
195
 
196
- ### 3b. Launch Background Process
196
+ Then commit this state write before launching (mandatory). The runner refuses to run with uncommitted changes (*"…pass --force"*), and this marker is itself one — so an otherwise-clean repo fails its first launch unless committed. Commit it via the shared-conventions **Git Commit Protocol** (epic members: stage `{specsDir}/{epic}/`): `{commitPrefix}({feature}): forge-5-loop in-progress` — a launch precondition, required regardless of `gitCommitAfterStage`. Unrelated leftover changes still trip the refusal; surface it, never auto-pass `--force`. See `references/runner-contract.md`.
197
197
 
198
- Launch the loop **backgrounded** (`run_in_background: true`) so it survives session end and does not block the session, and prefer the machine-readable event stream (`loopRunner.eventStreamCommand`, default for rauf) redirected to a stable `events.ndjson` so the session can supervise it live; fall back to the plain `runCommand` (tailing the human log) when no `eventStreamCommand` is configured. The background task's exit notification is the single authoritative terminal signal (Step 4). For the exact launch commands (incl. the `mkdir -p` state-dir guard) and the event-stream vs. log-fallback detail, read `references/runner-contract.md`.
198
+ ### 3b. Launch Background Process
199
199
 
200
- Loop runs can take significant time (minutes to hours depending on backlog size).
200
+ Launch the loop **backgrounded** (`run_in_background: true`) so it survives session end and does not block the session, and prefer the machine-readable event stream (`loopRunner.eventStreamCommand`, default for rauf) redirected to a stable `events.ndjson` so the session can supervise it live; fall back to the plain `runCommand` (tailing the human log) when no `eventStreamCommand` is configured. The background task's exit notification is the single authoritative terminal signal (Step 4). Loop runs can take significant time (minutes to hours depending on backlog size). For the exact launch commands (incl. the `mkdir -p` state-dir guard) and the event-stream vs. log-fallback detail, read `references/runner-contract.md`.
201
201
 
202
202
  ### 3c. Inform User
203
203
 
@@ -246,7 +246,7 @@ Run the **status-json command** (`loopRunner.statusJsonCommand`) and read
246
246
  `backlogSummary` for the authoritative counts — it separates the three non-done
247
247
  outcomes: genuine `blocked`, `needsHuman`, and runner-`deferred` ("false blocks").
248
248
  Fall back to the **list command** (`loopRunner.listCommand`) if `statusJsonCommand`
249
- is not configured. You will already have most of this from the live tally in 3e.
249
+ is not configured. You will already have most of this from the live tally in 3e. If the run used a review flag (e.g. rauf's `--review`), also read any `review_completed` event (event stream, or `{loopRunner.stateDir}/events.ndjson`) for its `itemsCreated`/`summary` to surface in 4b — see `references/result-reporting.md`.
250
250
 
251
251
  ### 4b. Report Results
252
252
 
@@ -267,13 +267,15 @@ Update `{resolvedFeatureDir}/.pipeline-state.json`:
267
267
  2. If all items complete: set `currentStage` to `"forge-6-docs"`
268
268
  3. Update `updatedAt`
269
269
 
270
- **No git commit is needed** — the loop runner commits atomically per completed item during the run. The implementation code is already committed.
270
+ **No git commit is needed** — the loop runner commits implementation code atomically per completed item during the run. (Step 6's commit, epic members only, is of pipeline state / manifest — a distinct artifact.)
271
+
272
+ ## Step 5b: Offer Impl-Verify (standalone path)
271
273
 
272
- > **Note:** Step 5's "no git commit needed" remark refers to *implementation code*, which the runner commits per-item. The epic handoff's commit in Step 6 below is of *pipeline state / manifest* a distinct artifact and applies only to epic members.
274
+ **Gate:** run only if (a) the feature's `.pipeline-state.json` has **no** `epic` key **and** (b) Step 5 set `stages.forge-5-loop.status` to `complete`. Otherwise **skip** partial runs end as today, and epic members get the equivalent offer in Step 6.1 (do **not** prompt twice). This standalone counterpart to Step 6.1 nudges verification interactively rather than via the easily-missed "Next steps" text. Use `AskUserQuestion` (NOT inline prose) to offer: *"{feature}'s loop is complete. Recommended: run `/feature-forge:forge-verify {feature} impl` to audit the implementation before generating docs. Run it now, or skip to forge-6-docs?"* On **run**, hand off to `/feature-forge:forge-verify {feature} impl`. On **skip**, record `stages.forge-verify-impl.status` as `"skipped"` (mirrors `forge-4-backlog`'s skip handling) and point the user at `/feature-forge:forge-6-docs {feature}` — the forge-6-docs backstop re-surfaces the skip.
273
275
 
274
276
  ## Step 6: Epic Handoff
275
277
 
276
- **Gate:** only run this step if (a) the resolved feature's `.pipeline-state.json` has an `epic` key **and** (b) Step 5 set `stages.forge-5-loop.status` to `complete` (all backlog items done). If either is false, **skip** — standalone features and partial runs end exactly as today (REQ-COMPAT-01).
278
+ **Gate:** only run this step if (a) the resolved feature's `.pipeline-state.json` has an `epic` key **and** (b) Step 5 set `stages.forge-5-loop.status` to `complete` (all backlog items done). If either is false, **skip** — standalone completed features are handled by Step 5b, and partial runs end as today (REQ-COMPAT-01).
277
279
 
278
280
  1. **Offer impl-verify first (recommended, skippable).** Per the completion rule (`00-core-definitions.md §7`), a feature whose `forge-verify-impl.status == findings-reported` does **not** unblock dependents. Use `AskUserQuestion` (NOT inline prose) to offer:
279
281
 
@@ -297,7 +299,7 @@ Update `{resolvedFeatureDir}/.pipeline-state.json`:
297
299
  - rauf resolves `RAUF.md` with fallback: checks `{backlogDir}/.rauf/RAUF.md` first, then the project's `.rauf/RAUF.md`. As long as the runner is installed in the project, the prompt template will be found.
298
300
  - State files (state.json, {loopRunner.logFile}, etc.) are created at `{backlogDir}/{loopRunner.stateDir}/` — this is within the feature's spec directory and is expected. State is isolated per backlog dir, so concurrent features don't collide.
299
301
  - If the session disconnects during a long-running loop, the runner process continues independently. The user can check results later with the status / list commands.
300
- - Never run the run command in the foreground (without `run_in_background`) — it blocks and will hit the Bash tool timeout for any non-trivial backlog. "Don't block the foreground" is NOT "stay silent": supervise via the `Monitor` tool (3d), which is harness-driven, not a sleep loop. Never `sleep`/poll in the foreground to wait for the loop.
301
- - The `Monitor` must use `persistent: true` (not a bounded `timeout_ms`), watch the **structured** surface (`events.ndjson`), and never filter on raw `RAUF_*` tokens — they appear in agent prose and false-match. A `needs_human`/`blocked`/`review` signal does **not** pause the loop — the runner sets the item aside and keeps going; surface it live but don't tell the user the loop is waiting. See `references/runner-contract.md` for the full monitoring rules.
302
+ - Never run the run command in the foreground (without `run_in_background`) — it blocks and will hit the Bash tool timeout for any non-trivial backlog. "Don't block the foreground" is NOT "stay silent": supervise via the `Monitor` tool (3d), never `sleep`/poll in the foreground. The `Monitor` must use `persistent: true` (not a bounded `timeout_ms`), watch the **structured** surface (`events.ndjson`), and never filter on raw `RAUF_*` tokens — they appear in agent prose and false-match. A `needs_human`/`blocked`/`review` signal does **not** pause the loop the runner sets the item aside and keeps going; surface it live but don't tell the user the loop is waiting. See `references/runner-contract.md` for the full monitoring rules.
302
303
  - If a previous loop run left a stale lock, the user may need to pass `--force` to clear it. rauf will report this error clearly.
303
304
  - The version gate (1c) uses the `--json` form on purpose; never parse `rauf version`'s human output.
305
+ - **Implementation artifacts must not cite specs.** The loop should **read** the specs and `backlog.json` freely — they are the source of truth for what to build, and the backlog rightly references specs for provenance. But the artifacts the loop **writes into the target repo** (source code, generated `SKILL.md`/agent files, configs, code comments) must be **self-contained**: they must NOT reference feature-forge spec files (no `See specs/{feature}/NN-*.md`, no "source spec" provenance notes in shipped output). Specs are pre-implementation inputs that may be archived or deleted once the feature ships; the implementation must stand on its own. This applies only to shipped implementation output — never to the backlog or spec documents, which should keep citing specs.
@@ -13,6 +13,19 @@ Next steps:
13
13
  - /feature-forge:forge-6-docs {feature} Generate architecture docs
14
14
  ```
15
15
 
16
+ **Runner review pass.** A review flag (e.g. rauf's `--review`) makes the runner run
17
+ a post-loop review that **auto-creates and implements fix items** rather than handing
18
+ findings to the user — distinct from `forge-verify impl` (a clean-context audit that
19
+ writes a findings doc). When Step 4a captured a `review_completed` event, add a line
20
+ **above** "Next steps" so the pass's effect is visible and not mistaken for "nothing
21
+ happened":
22
+ ```
23
+ Runner review pass: {itemsCreated} fix item(s) created and implemented.
24
+ {summary}
25
+ ```
26
+ Omit this line when no `review_completed` event was emitted (no review flag passed).
27
+ The created items are already counted in the totals above.
28
+
16
29
  **Some items need a human:**
17
30
  ```
18
31
  Loop completed for {feature}.
@@ -70,6 +70,38 @@ The default / `claude-cli` path runs **no** probe (zero extra cost). See
70
70
  `04-availability-precheck.md` for the full pre-check, classification, and allow-list,
71
71
  and `02-config-schema-and-gating.md` for the capability gate.
72
72
 
73
+ > **Probe false-negative for Claude Code installs (advisory).** `rauf agents` may
74
+ > report `claude-cli` **unavailable** (e.g. *"credentials file not found:
75
+ > ~/.config/claude-code/credentials.json"*) even when a working `claude` CLI
76
+ > authenticates elsewhere — the probe's credential heuristic doesn't cover every
77
+ > install. This is a rauf probe concern, not something forge-5-loop fixes. The
78
+ > **default-agent path skips the probe entirely**, so an ordinary default run is
79
+ > unaffected; only an **explicit** `--agent claude-cli` would be flagged UNAVAILABLE,
80
+ > and the existing **proceed-anyway** path (above) covers it. Do not attempt to
81
+ > patch rauf's probe from here.
82
+
83
+ ### Claude-only model-alias guard (Step 2d, sub-step d-model)
84
+
85
+ When the resolved agent is **non-default** (not the default / `claude-cli` path),
86
+ forge must guard against a backlog whose items pin **Claude-specific** model aliases.
87
+ forge-4-backlog (via the rauf author-backlog skill) writes Claude tier aliases
88
+ (`opus` / `sonnet`) into each item's `model`. Because rauf's precedence puts
89
+ `item.model` **above** `--agent`, the alias is forwarded verbatim to the selected
90
+ agent; a non-Claude agent (e.g. codex) then 400s — *"The 'sonnet' model is not
91
+ supported when using Codex with a ChatGPT account."* — so **every** spawn exits 1 and
92
+ rauf reports *"Circuit breaker: 3 consecutive infra failures — halting"* with no hint
93
+ of the real cause. forge-5-loop therefore detects Claude-specific `model` aliases in
94
+ the backlog (tier aliases `opus`/`sonnet`/`haiku` or `claude-*` ids) and, before
95
+ launch, **warns** and offers (via `AskUserQuestion`) to **strip `model` for this run**
96
+ (remove the key from each affected item so each spawn uses the agent's own default) or
97
+ **proceed as-is**. forge only ever touches the `model` field — never `provider`. The
98
+ default / `claude-cli` path skips this guard (the aliases are valid there).
99
+
100
+ > **Follow-up (out of scope here — rauf repo).** The durable fix would be for the
101
+ > rauf `author-backlog` skill to keep `model` **provider-neutral** by default (or to
102
+ > document that writing a tier alias binds the backlog to Claude agents). That lives
103
+ > in the separate rauf plugin/repo, not feature-forge; tracked as a follow-up.
104
+
73
105
  ## Optional flags catalog (Step 2d, rauf)
74
106
 
75
107
  These are the optional flags the user may add to the rendered run command. If the
@@ -92,6 +124,14 @@ Launch the loop **backgrounded** so it survives session end and does not block t
92
124
  session, and prefer the machine-readable event stream so the session can supervise
93
125
  it live.
94
126
 
127
+ > **Clean-tree precondition.** rauf refuses to run with uncommitted changes
128
+ > (*"Refusing to run the loop with uncommitted changes… pass --force"*). Step 3a's
129
+ > in-progress `.pipeline-state.json` write is itself an uncommitted change, so it
130
+ > **must be committed before launch** (Step 3a) — otherwise the first launch on an
131
+ > otherwise-clean repo always fails. If the tree still has unrelated uncommitted
132
+ > changes after that commit, surface it and let the user commit/stash or pass
133
+ > `--force`; never auto-pass `--force`.
134
+
95
135
  - **If `loopRunner.eventStreamCommand` is configured (default for rauf):** render it
96
136
  (it appends `--ndjson` to the run) and launch via the Bash tool with
97
137
  `run_in_background: true`, redirecting stdout to a stable events file:
@@ -35,6 +35,10 @@ Check `{resolvedFeatureDir}/backlog.json` (or `{backlogDir}/{feature}/backlog.js
35
35
 
36
36
  Also check `.pipeline-state.json` for `stages.forge-5-loop`. If it exists and has status `in-progress` (some items incomplete), include this in the warning: "The rauf loop has not fully completed — {done}/{total} items done. Documentation may need updates after remaining items are implemented."
37
37
 
38
+ ### Impl-Verify Backstop
39
+
40
+ Check `.pipeline-state.json` for `stages.forge-verify-impl`. If it is **absent** or has status `"skipped"`, use `AskUserQuestion` to warn: "Implementation hasn't been verified yet. It's recommended to run `/feature-forge:forge-verify {feature} impl` first to audit the loop's output. Generate docs anyway?" This mirrors `forge-4-backlog`'s pre-stage verification check and backstops a skipped impl-verify regardless of how the loop ended. If `stages.forge-verify-impl` shows it already ran (`findings-applied`, `findings-reported`, or `passed`), proceed with no warning.
41
+
38
42
  ### Epic-Level Documentation (epic members only)
39
43
 
40
44
  If the resolved feature has an `epic` back-pointer in its `.pipeline-state.json`, run:
@@ -110,6 +114,11 @@ Present the plan and use `AskUserQuestion` to get the user's confirmation.
110
114
  - Specs are the source of truth for design intent; code is the source of truth for behavior
111
115
  - Read the actual source code to verify your documentation is correct
112
116
 
117
+ **Don't cite or link spec files in the generated docs.**
118
+ - Read the specs freely for context, but the docs you write are shipped implementation artifacts — they must be self-contained
119
+ - Never link or reference `PRD.md`, `tech-spec.md`, or the numbered implementation specs (`specs/{feature}/NN-*.md`); these are pre-implementation artifacts that may be archived or deleted
120
+ - Reference only the code, runtime contracts/configuration, and other generated docs. If you need to convey design intent, write it directly into the doc rather than pointing at a spec
121
+
113
122
  **Match existing conventions.**
114
123
  - If other features' docs use a specific heading structure, follow it
115
124
  - If they include diagrams, include diagrams
@@ -173,6 +182,7 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
173
182
  ## Gotchas
174
183
 
175
184
  - Don't just rephrase the specs. Documentation should explain the implemented system, not the planned system. Read the actual code.
185
+ - Don't cite spec files (PRD.md, tech-spec.md, numbered specs) as sources or "further reading" in the generated docs — specs are pre-implementation artifacts that may not survive. Keep the docs self-contained; link only to code, configuration, and other docs.
176
186
  - If the implementation doesn't exist yet (backlog hasn't been run), document based on specs but note prominently that docs are pre-implementation and may need updating.
177
187
  - API reference should include actual function signatures from the code, not from the spec (they may differ).
178
188
  - Don't generate docs that will immediately be stale. Focus on concepts, architecture, and patterns rather than line-by-line code walkthroughs.