@garygentry/feature-forge 0.3.2 → 0.3.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 (389) hide show
  1. package/README.md +1 -1
  2. package/adapters/claude/.feature-forge-bundle.json +1 -1
  3. package/adapters/claude/agents/forge-verifier.md +3 -1
  4. package/adapters/claude/references/decisions/single-writer-threat-model.md +53 -0
  5. package/adapters/claude/references/epic-state-schema.json +50 -0
  6. package/adapters/claude/references/forge-config-schema.json +20 -2
  7. package/adapters/claude/references/forge-decisions-schema.json +33 -0
  8. package/adapters/claude/references/pipeline-state-schema.json +34 -2
  9. package/adapters/claude/references/ralph-loop-contract.md +6 -3
  10. package/adapters/claude/references/shared-conventions.md +15 -4
  11. package/adapters/claude/references/stage-exit-protocol.md +55 -11
  12. package/adapters/claude/scripts/epic-manifest.py +82 -4
  13. package/adapters/claude/scripts/fix-sweep.py +1180 -0
  14. package/adapters/claude/scripts/forge-session.py +1151 -32
  15. package/adapters/claude/skills/forge/SKILL.md +5 -5
  16. package/adapters/claude/skills/forge/references/pipeline-state-schema.json +34 -2
  17. package/adapters/claude/skills/forge/references/shared-conventions.md +15 -4
  18. package/adapters/claude/skills/forge/references/stage-exit-protocol.md +55 -11
  19. package/adapters/claude/skills/forge-0-epic/references/edit-mode.md +5 -1
  20. package/adapters/claude/skills/forge-0-epic/references/epic-manifest-subcommands.md +5 -0
  21. package/adapters/claude/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
  22. package/adapters/claude/skills/forge-0-epic/references/shared-conventions.md +15 -4
  23. package/adapters/claude/skills/forge-0-epic/references/stage-exit-protocol.md +55 -11
  24. package/adapters/claude/skills/forge-1-prd/SKILL.md +3 -1
  25. package/adapters/claude/skills/forge-1-prd/references/shared-conventions.md +15 -4
  26. package/adapters/claude/skills/forge-1-prd/references/stage-exit-protocol.md +55 -11
  27. package/adapters/claude/skills/forge-2-tech/SKILL.md +5 -1
  28. package/adapters/claude/skills/forge-2-tech/references/shared-conventions.md +15 -4
  29. package/adapters/claude/skills/forge-2-tech/references/stage-exit-protocol.md +55 -11
  30. package/adapters/claude/skills/forge-3-specs/SKILL.md +5 -1
  31. package/adapters/claude/skills/forge-3-specs/references/shared-conventions.md +15 -4
  32. package/adapters/claude/skills/forge-3-specs/references/stage-exit-protocol.md +55 -11
  33. package/adapters/claude/skills/forge-4-backlog/SKILL.md +41 -3
  34. package/adapters/claude/skills/forge-4-backlog/references/shared-conventions.md +15 -4
  35. package/adapters/claude/skills/forge-4-backlog/references/stage-exit-protocol.md +55 -11
  36. package/adapters/claude/skills/forge-5-loop/SKILL.md +36 -36
  37. package/adapters/claude/skills/forge-5-loop/references/agent-selection.md +16 -0
  38. package/adapters/claude/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  39. package/adapters/claude/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  40. package/adapters/claude/skills/forge-5-loop/references/result-reporting.md +40 -11
  41. package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +22 -4
  42. package/adapters/claude/skills/forge-5-loop/references/shared-conventions.md +15 -4
  43. package/adapters/claude/skills/forge-5-loop/references/stage-exit-protocol.md +55 -11
  44. package/adapters/claude/skills/forge-6-docs/SKILL.md +29 -6
  45. package/adapters/claude/skills/forge-6-docs/references/shared-conventions.md +15 -4
  46. package/adapters/claude/skills/forge-6-docs/references/stage-exit-protocol.md +55 -11
  47. package/adapters/claude/skills/forge-fix/SKILL.md +34 -0
  48. package/adapters/claude/skills/forge-fix/references/shared-conventions.md +15 -4
  49. package/adapters/claude/skills/forge-fix/references/stage-exit-protocol.md +55 -11
  50. package/adapters/claude/skills/forge-guide/references/forge-config-schema.json +20 -2
  51. package/adapters/claude/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  52. package/adapters/claude/skills/forge-guide/references/shared-conventions.md +15 -4
  53. package/adapters/claude/skills/forge-verify/SKILL.md +10 -11
  54. package/adapters/claude/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  55. package/adapters/claude/skills/forge-verify/references/findings-template.md +30 -0
  56. package/adapters/claude/skills/forge-verify/references/shared-conventions.md +15 -4
  57. package/adapters/claude/skills/forge-verify/references/stage-exit-protocol.md +55 -11
  58. package/adapters/claude/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  59. package/adapters/claude/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  60. package/adapters/claude/skills/forge-verify/references/verification-checklists/specs.md +43 -1
  61. package/adapters/codex/.feature-forge-bundle.json +1 -1
  62. package/adapters/codex/agents/forge-verifier.toml +3 -1
  63. package/adapters/codex/references/decisions/single-writer-threat-model.md +53 -0
  64. package/adapters/codex/references/epic-state-schema.json +50 -0
  65. package/adapters/codex/references/forge-config-schema.json +20 -2
  66. package/adapters/codex/references/forge-decisions-schema.json +33 -0
  67. package/adapters/codex/references/pipeline-state-schema.json +34 -2
  68. package/adapters/codex/references/process-overview.md +2 -2
  69. package/adapters/codex/references/ralph-loop-contract.md +6 -3
  70. package/adapters/codex/references/shared-conventions.md +44 -33
  71. package/adapters/codex/references/stage-exit-protocol.md +64 -20
  72. package/adapters/codex/scripts/epic-manifest.py +82 -4
  73. package/adapters/codex/scripts/fix-sweep.py +1180 -0
  74. package/adapters/codex/scripts/forge-session.py +1151 -32
  75. package/adapters/codex/skills/forge/SKILL.md +8 -8
  76. package/adapters/codex/skills/forge/references/pipeline-state-schema.json +34 -2
  77. package/adapters/codex/skills/forge/references/process-overview.md +2 -2
  78. package/adapters/codex/skills/forge/references/shared-conventions.md +44 -33
  79. package/adapters/codex/skills/forge/references/stage-exit-protocol.md +64 -20
  80. package/adapters/codex/skills/forge-0-epic/references/edit-mode.md +14 -10
  81. package/adapters/codex/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
  82. package/adapters/codex/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
  83. package/adapters/codex/skills/forge-0-epic/references/shared-conventions.md +44 -33
  84. package/adapters/codex/skills/forge-0-epic/references/stage-exit-protocol.md +64 -20
  85. package/adapters/codex/skills/forge-1-prd/SKILL.md +3 -1
  86. package/adapters/codex/skills/forge-1-prd/references/shared-conventions.md +44 -33
  87. package/adapters/codex/skills/forge-1-prd/references/stage-exit-protocol.md +64 -20
  88. package/adapters/codex/skills/forge-2-tech/SKILL.md +5 -1
  89. package/adapters/codex/skills/forge-2-tech/references/shared-conventions.md +44 -33
  90. package/adapters/codex/skills/forge-2-tech/references/stage-exit-protocol.md +64 -20
  91. package/adapters/codex/skills/forge-3-specs/SKILL.md +5 -1
  92. package/adapters/codex/skills/forge-3-specs/references/shared-conventions.md +44 -33
  93. package/adapters/codex/skills/forge-3-specs/references/stage-exit-protocol.md +64 -20
  94. package/adapters/codex/skills/forge-4-backlog/SKILL.md +41 -3
  95. package/adapters/codex/skills/forge-4-backlog/references/shared-conventions.md +44 -33
  96. package/adapters/codex/skills/forge-4-backlog/references/stage-exit-protocol.md +64 -20
  97. package/adapters/codex/skills/forge-5-loop/SKILL.md +36 -36
  98. package/adapters/codex/skills/forge-5-loop/references/agent-selection.md +17 -1
  99. package/adapters/codex/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  100. package/adapters/codex/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  101. package/adapters/codex/skills/forge-5-loop/references/result-reporting.md +40 -11
  102. package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +26 -8
  103. package/adapters/codex/skills/forge-5-loop/references/shared-conventions.md +44 -33
  104. package/adapters/codex/skills/forge-5-loop/references/stage-exit-protocol.md +64 -20
  105. package/adapters/codex/skills/forge-6-docs/SKILL.md +29 -6
  106. package/adapters/codex/skills/forge-6-docs/references/shared-conventions.md +44 -33
  107. package/adapters/codex/skills/forge-6-docs/references/stage-exit-protocol.md +64 -20
  108. package/adapters/codex/skills/forge-fix/SKILL.md +34 -0
  109. package/adapters/codex/skills/forge-fix/references/shared-conventions.md +44 -33
  110. package/adapters/codex/skills/forge-fix/references/stage-exit-protocol.md +64 -20
  111. package/adapters/codex/skills/forge-guide/SKILL.md +1 -1
  112. package/adapters/codex/skills/forge-guide/references/forge-config-schema.json +20 -2
  113. package/adapters/codex/skills/forge-guide/references/process-overview.md +2 -2
  114. package/adapters/codex/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  115. package/adapters/codex/skills/forge-guide/references/shared-conventions.md +44 -33
  116. package/adapters/codex/skills/forge-init/SKILL.md +1 -1
  117. package/adapters/codex/skills/forge-verify/SKILL.md +11 -12
  118. package/adapters/codex/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  119. package/adapters/codex/skills/forge-verify/references/findings-template.md +32 -2
  120. package/adapters/codex/skills/forge-verify/references/shared-conventions.md +44 -33
  121. package/adapters/codex/skills/forge-verify/references/stage-exit-protocol.md +64 -20
  122. package/adapters/codex/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  123. package/adapters/codex/skills/forge-verify/references/verification-checklists/epic.md +1 -1
  124. package/adapters/codex/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  125. package/adapters/codex/skills/forge-verify/references/verification-checklists/specs.md +43 -1
  126. package/adapters/copilot/.feature-forge-bundle.json +1 -1
  127. package/adapters/copilot/agents/forge-verifier.md +3 -1
  128. package/adapters/copilot/references/decisions/single-writer-threat-model.md +53 -0
  129. package/adapters/copilot/references/epic-state-schema.json +50 -0
  130. package/adapters/copilot/references/forge-config-schema.json +20 -2
  131. package/adapters/copilot/references/forge-decisions-schema.json +33 -0
  132. package/adapters/copilot/references/pipeline-state-schema.json +34 -2
  133. package/adapters/copilot/references/process-overview.md +2 -2
  134. package/adapters/copilot/references/ralph-loop-contract.md +6 -3
  135. package/adapters/copilot/references/shared-conventions.md +44 -33
  136. package/adapters/copilot/references/stage-exit-protocol.md +64 -20
  137. package/adapters/copilot/scripts/epic-manifest.py +82 -4
  138. package/adapters/copilot/scripts/fix-sweep.py +1180 -0
  139. package/adapters/copilot/scripts/forge-session.py +1151 -32
  140. package/adapters/copilot/skills/forge/forge.md +8 -8
  141. package/adapters/copilot/skills/forge/references/pipeline-state-schema.json +34 -2
  142. package/adapters/copilot/skills/forge/references/process-overview.md +2 -2
  143. package/adapters/copilot/skills/forge/references/shared-conventions.md +44 -33
  144. package/adapters/copilot/skills/forge/references/stage-exit-protocol.md +64 -20
  145. package/adapters/copilot/skills/forge-0-epic/references/edit-mode.md +14 -10
  146. package/adapters/copilot/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
  147. package/adapters/copilot/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
  148. package/adapters/copilot/skills/forge-0-epic/references/shared-conventions.md +44 -33
  149. package/adapters/copilot/skills/forge-0-epic/references/stage-exit-protocol.md +64 -20
  150. package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +3 -1
  151. package/adapters/copilot/skills/forge-1-prd/references/shared-conventions.md +44 -33
  152. package/adapters/copilot/skills/forge-1-prd/references/stage-exit-protocol.md +64 -20
  153. package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +5 -1
  154. package/adapters/copilot/skills/forge-2-tech/references/shared-conventions.md +44 -33
  155. package/adapters/copilot/skills/forge-2-tech/references/stage-exit-protocol.md +64 -20
  156. package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +5 -1
  157. package/adapters/copilot/skills/forge-3-specs/references/shared-conventions.md +44 -33
  158. package/adapters/copilot/skills/forge-3-specs/references/stage-exit-protocol.md +64 -20
  159. package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +41 -3
  160. package/adapters/copilot/skills/forge-4-backlog/references/shared-conventions.md +44 -33
  161. package/adapters/copilot/skills/forge-4-backlog/references/stage-exit-protocol.md +64 -20
  162. package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +36 -36
  163. package/adapters/copilot/skills/forge-5-loop/references/agent-selection.md +17 -1
  164. package/adapters/copilot/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  165. package/adapters/copilot/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  166. package/adapters/copilot/skills/forge-5-loop/references/result-reporting.md +40 -11
  167. package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +26 -8
  168. package/adapters/copilot/skills/forge-5-loop/references/shared-conventions.md +44 -33
  169. package/adapters/copilot/skills/forge-5-loop/references/stage-exit-protocol.md +64 -20
  170. package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +29 -6
  171. package/adapters/copilot/skills/forge-6-docs/references/shared-conventions.md +44 -33
  172. package/adapters/copilot/skills/forge-6-docs/references/stage-exit-protocol.md +64 -20
  173. package/adapters/copilot/skills/forge-fix/forge-fix.md +34 -0
  174. package/adapters/copilot/skills/forge-fix/references/shared-conventions.md +44 -33
  175. package/adapters/copilot/skills/forge-fix/references/stage-exit-protocol.md +64 -20
  176. package/adapters/copilot/skills/forge-guide/forge-guide.md +1 -1
  177. package/adapters/copilot/skills/forge-guide/references/forge-config-schema.json +20 -2
  178. package/adapters/copilot/skills/forge-guide/references/process-overview.md +2 -2
  179. package/adapters/copilot/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  180. package/adapters/copilot/skills/forge-guide/references/shared-conventions.md +44 -33
  181. package/adapters/copilot/skills/forge-init/forge-init.md +1 -1
  182. package/adapters/copilot/skills/forge-verify/forge-verify.md +11 -12
  183. package/adapters/copilot/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  184. package/adapters/copilot/skills/forge-verify/references/findings-template.md +32 -2
  185. package/adapters/copilot/skills/forge-verify/references/shared-conventions.md +44 -33
  186. package/adapters/copilot/skills/forge-verify/references/stage-exit-protocol.md +64 -20
  187. package/adapters/copilot/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  188. package/adapters/copilot/skills/forge-verify/references/verification-checklists/epic.md +1 -1
  189. package/adapters/copilot/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  190. package/adapters/copilot/skills/forge-verify/references/verification-checklists/specs.md +43 -1
  191. package/adapters/cursor/.feature-forge-bundle.json +1 -1
  192. package/adapters/cursor/agents/forge-verifier.mdc +3 -1
  193. package/adapters/cursor/references/decisions/single-writer-threat-model.md +53 -0
  194. package/adapters/cursor/references/epic-state-schema.json +50 -0
  195. package/adapters/cursor/references/forge-config-schema.json +20 -2
  196. package/adapters/cursor/references/forge-decisions-schema.json +33 -0
  197. package/adapters/cursor/references/pipeline-state-schema.json +34 -2
  198. package/adapters/cursor/references/process-overview.md +2 -2
  199. package/adapters/cursor/references/ralph-loop-contract.md +6 -3
  200. package/adapters/cursor/references/shared-conventions.md +44 -33
  201. package/adapters/cursor/references/stage-exit-protocol.md +64 -20
  202. package/adapters/cursor/scripts/epic-manifest.py +82 -4
  203. package/adapters/cursor/scripts/fix-sweep.py +1180 -0
  204. package/adapters/cursor/scripts/forge-session.py +1151 -32
  205. package/adapters/cursor/skills/forge/forge.mdc +8 -8
  206. package/adapters/cursor/skills/forge/references/pipeline-state-schema.json +34 -2
  207. package/adapters/cursor/skills/forge/references/process-overview.md +2 -2
  208. package/adapters/cursor/skills/forge/references/shared-conventions.md +44 -33
  209. package/adapters/cursor/skills/forge/references/stage-exit-protocol.md +64 -20
  210. package/adapters/cursor/skills/forge-0-epic/references/edit-mode.md +14 -10
  211. package/adapters/cursor/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
  212. package/adapters/cursor/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
  213. package/adapters/cursor/skills/forge-0-epic/references/shared-conventions.md +44 -33
  214. package/adapters/cursor/skills/forge-0-epic/references/stage-exit-protocol.md +64 -20
  215. package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +3 -1
  216. package/adapters/cursor/skills/forge-1-prd/references/shared-conventions.md +44 -33
  217. package/adapters/cursor/skills/forge-1-prd/references/stage-exit-protocol.md +64 -20
  218. package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +5 -1
  219. package/adapters/cursor/skills/forge-2-tech/references/shared-conventions.md +44 -33
  220. package/adapters/cursor/skills/forge-2-tech/references/stage-exit-protocol.md +64 -20
  221. package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +5 -1
  222. package/adapters/cursor/skills/forge-3-specs/references/shared-conventions.md +44 -33
  223. package/adapters/cursor/skills/forge-3-specs/references/stage-exit-protocol.md +64 -20
  224. package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +41 -3
  225. package/adapters/cursor/skills/forge-4-backlog/references/shared-conventions.md +44 -33
  226. package/adapters/cursor/skills/forge-4-backlog/references/stage-exit-protocol.md +64 -20
  227. package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +36 -36
  228. package/adapters/cursor/skills/forge-5-loop/references/agent-selection.md +17 -1
  229. package/adapters/cursor/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  230. package/adapters/cursor/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  231. package/adapters/cursor/skills/forge-5-loop/references/result-reporting.md +40 -11
  232. package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +26 -8
  233. package/adapters/cursor/skills/forge-5-loop/references/shared-conventions.md +44 -33
  234. package/adapters/cursor/skills/forge-5-loop/references/stage-exit-protocol.md +64 -20
  235. package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +29 -6
  236. package/adapters/cursor/skills/forge-6-docs/references/shared-conventions.md +44 -33
  237. package/adapters/cursor/skills/forge-6-docs/references/stage-exit-protocol.md +64 -20
  238. package/adapters/cursor/skills/forge-fix/forge-fix.mdc +34 -0
  239. package/adapters/cursor/skills/forge-fix/references/shared-conventions.md +44 -33
  240. package/adapters/cursor/skills/forge-fix/references/stage-exit-protocol.md +64 -20
  241. package/adapters/cursor/skills/forge-guide/forge-guide.mdc +1 -1
  242. package/adapters/cursor/skills/forge-guide/references/forge-config-schema.json +20 -2
  243. package/adapters/cursor/skills/forge-guide/references/process-overview.md +2 -2
  244. package/adapters/cursor/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  245. package/adapters/cursor/skills/forge-guide/references/shared-conventions.md +44 -33
  246. package/adapters/cursor/skills/forge-init/forge-init.mdc +1 -1
  247. package/adapters/cursor/skills/forge-verify/forge-verify.mdc +11 -12
  248. package/adapters/cursor/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  249. package/adapters/cursor/skills/forge-verify/references/findings-template.md +32 -2
  250. package/adapters/cursor/skills/forge-verify/references/shared-conventions.md +44 -33
  251. package/adapters/cursor/skills/forge-verify/references/stage-exit-protocol.md +64 -20
  252. package/adapters/cursor/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  253. package/adapters/cursor/skills/forge-verify/references/verification-checklists/epic.md +1 -1
  254. package/adapters/cursor/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  255. package/adapters/cursor/skills/forge-verify/references/verification-checklists/specs.md +43 -1
  256. package/adapters/gemini/.feature-forge-bundle.json +1 -1
  257. package/adapters/gemini/agents/forge-verifier.md +3 -1
  258. package/adapters/gemini/gemini-extension.json +1 -1
  259. package/adapters/gemini/references/decisions/single-writer-threat-model.md +53 -0
  260. package/adapters/gemini/references/epic-state-schema.json +50 -0
  261. package/adapters/gemini/references/forge-config-schema.json +20 -2
  262. package/adapters/gemini/references/forge-decisions-schema.json +33 -0
  263. package/adapters/gemini/references/pipeline-state-schema.json +34 -2
  264. package/adapters/gemini/references/process-overview.md +2 -2
  265. package/adapters/gemini/references/ralph-loop-contract.md +6 -3
  266. package/adapters/gemini/references/shared-conventions.md +44 -33
  267. package/adapters/gemini/references/stage-exit-protocol.md +64 -20
  268. package/adapters/gemini/scripts/epic-manifest.py +82 -4
  269. package/adapters/gemini/scripts/fix-sweep.py +1180 -0
  270. package/adapters/gemini/scripts/forge-session.py +1151 -32
  271. package/adapters/gemini/skills/forge/forge.md +8 -8
  272. package/adapters/gemini/skills/forge/references/pipeline-state-schema.json +34 -2
  273. package/adapters/gemini/skills/forge/references/process-overview.md +2 -2
  274. package/adapters/gemini/skills/forge/references/shared-conventions.md +44 -33
  275. package/adapters/gemini/skills/forge/references/stage-exit-protocol.md +64 -20
  276. package/adapters/gemini/skills/forge-0-epic/references/edit-mode.md +14 -10
  277. package/adapters/gemini/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
  278. package/adapters/gemini/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
  279. package/adapters/gemini/skills/forge-0-epic/references/shared-conventions.md +44 -33
  280. package/adapters/gemini/skills/forge-0-epic/references/stage-exit-protocol.md +64 -20
  281. package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +3 -1
  282. package/adapters/gemini/skills/forge-1-prd/references/shared-conventions.md +44 -33
  283. package/adapters/gemini/skills/forge-1-prd/references/stage-exit-protocol.md +64 -20
  284. package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +5 -1
  285. package/adapters/gemini/skills/forge-2-tech/references/shared-conventions.md +44 -33
  286. package/adapters/gemini/skills/forge-2-tech/references/stage-exit-protocol.md +64 -20
  287. package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +5 -1
  288. package/adapters/gemini/skills/forge-3-specs/references/shared-conventions.md +44 -33
  289. package/adapters/gemini/skills/forge-3-specs/references/stage-exit-protocol.md +64 -20
  290. package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +41 -3
  291. package/adapters/gemini/skills/forge-4-backlog/references/shared-conventions.md +44 -33
  292. package/adapters/gemini/skills/forge-4-backlog/references/stage-exit-protocol.md +64 -20
  293. package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +36 -36
  294. package/adapters/gemini/skills/forge-5-loop/references/agent-selection.md +17 -1
  295. package/adapters/gemini/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  296. package/adapters/gemini/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  297. package/adapters/gemini/skills/forge-5-loop/references/result-reporting.md +40 -11
  298. package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +26 -8
  299. package/adapters/gemini/skills/forge-5-loop/references/shared-conventions.md +44 -33
  300. package/adapters/gemini/skills/forge-5-loop/references/stage-exit-protocol.md +64 -20
  301. package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +29 -6
  302. package/adapters/gemini/skills/forge-6-docs/references/shared-conventions.md +44 -33
  303. package/adapters/gemini/skills/forge-6-docs/references/stage-exit-protocol.md +64 -20
  304. package/adapters/gemini/skills/forge-fix/forge-fix.md +34 -0
  305. package/adapters/gemini/skills/forge-fix/references/shared-conventions.md +44 -33
  306. package/adapters/gemini/skills/forge-fix/references/stage-exit-protocol.md +64 -20
  307. package/adapters/gemini/skills/forge-guide/forge-guide.md +1 -1
  308. package/adapters/gemini/skills/forge-guide/references/forge-config-schema.json +20 -2
  309. package/adapters/gemini/skills/forge-guide/references/process-overview.md +2 -2
  310. package/adapters/gemini/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  311. package/adapters/gemini/skills/forge-guide/references/shared-conventions.md +44 -33
  312. package/adapters/gemini/skills/forge-init/forge-init.md +1 -1
  313. package/adapters/gemini/skills/forge-verify/forge-verify.md +11 -12
  314. package/adapters/gemini/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  315. package/adapters/gemini/skills/forge-verify/references/findings-template.md +32 -2
  316. package/adapters/gemini/skills/forge-verify/references/shared-conventions.md +44 -33
  317. package/adapters/gemini/skills/forge-verify/references/stage-exit-protocol.md +64 -20
  318. package/adapters/gemini/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  319. package/adapters/gemini/skills/forge-verify/references/verification-checklists/epic.md +1 -1
  320. package/adapters/gemini/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  321. package/adapters/gemini/skills/forge-verify/references/verification-checklists/specs.md +43 -1
  322. package/adapters/pi/.feature-forge-bundle.json +1 -1
  323. package/adapters/pi/agents/forge-verifier.md +3 -1
  324. package/adapters/pi/references/decisions/single-writer-threat-model.md +53 -0
  325. package/adapters/pi/references/epic-state-schema.json +50 -0
  326. package/adapters/pi/references/forge-config-schema.json +20 -2
  327. package/adapters/pi/references/forge-decisions-schema.json +33 -0
  328. package/adapters/pi/references/pipeline-state-schema.json +34 -2
  329. package/adapters/pi/references/process-overview.md +2 -2
  330. package/adapters/pi/references/ralph-loop-contract.md +6 -3
  331. package/adapters/pi/references/shared-conventions.md +33 -22
  332. package/adapters/pi/references/stage-exit-protocol.md +63 -19
  333. package/adapters/pi/scripts/epic-manifest.py +82 -4
  334. package/adapters/pi/scripts/fix-sweep.py +1180 -0
  335. package/adapters/pi/scripts/forge-session.py +1151 -32
  336. package/adapters/pi/skills/forge/SKILL.md +5 -5
  337. package/adapters/pi/skills/forge/references/pipeline-state-schema.json +34 -2
  338. package/adapters/pi/skills/forge/references/process-overview.md +2 -2
  339. package/adapters/pi/skills/forge/references/shared-conventions.md +33 -22
  340. package/adapters/pi/skills/forge/references/stage-exit-protocol.md +63 -19
  341. package/adapters/pi/skills/forge-0-epic/references/edit-mode.md +8 -4
  342. package/adapters/pi/skills/forge-0-epic/references/epic-manifest-subcommands.md +6 -1
  343. package/adapters/pi/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
  344. package/adapters/pi/skills/forge-0-epic/references/shared-conventions.md +33 -22
  345. package/adapters/pi/skills/forge-0-epic/references/stage-exit-protocol.md +63 -19
  346. package/adapters/pi/skills/forge-1-prd/SKILL.md +3 -1
  347. package/adapters/pi/skills/forge-1-prd/references/shared-conventions.md +33 -22
  348. package/adapters/pi/skills/forge-1-prd/references/stage-exit-protocol.md +63 -19
  349. package/adapters/pi/skills/forge-2-tech/SKILL.md +5 -1
  350. package/adapters/pi/skills/forge-2-tech/references/shared-conventions.md +33 -22
  351. package/adapters/pi/skills/forge-2-tech/references/stage-exit-protocol.md +63 -19
  352. package/adapters/pi/skills/forge-3-specs/SKILL.md +5 -1
  353. package/adapters/pi/skills/forge-3-specs/references/shared-conventions.md +33 -22
  354. package/adapters/pi/skills/forge-3-specs/references/stage-exit-protocol.md +63 -19
  355. package/adapters/pi/skills/forge-4-backlog/SKILL.md +41 -3
  356. package/adapters/pi/skills/forge-4-backlog/references/shared-conventions.md +33 -22
  357. package/adapters/pi/skills/forge-4-backlog/references/stage-exit-protocol.md +63 -19
  358. package/adapters/pi/skills/forge-5-loop/SKILL.md +36 -36
  359. package/adapters/pi/skills/forge-5-loop/references/agent-selection.md +16 -0
  360. package/adapters/pi/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  361. package/adapters/pi/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  362. package/adapters/pi/skills/forge-5-loop/references/result-reporting.md +40 -11
  363. package/adapters/pi/skills/forge-5-loop/references/runner-contract.md +25 -7
  364. package/adapters/pi/skills/forge-5-loop/references/shared-conventions.md +33 -22
  365. package/adapters/pi/skills/forge-5-loop/references/stage-exit-protocol.md +63 -19
  366. package/adapters/pi/skills/forge-6-docs/SKILL.md +29 -6
  367. package/adapters/pi/skills/forge-6-docs/references/shared-conventions.md +33 -22
  368. package/adapters/pi/skills/forge-6-docs/references/stage-exit-protocol.md +63 -19
  369. package/adapters/pi/skills/forge-fix/SKILL.md +34 -0
  370. package/adapters/pi/skills/forge-fix/references/shared-conventions.md +33 -22
  371. package/adapters/pi/skills/forge-fix/references/stage-exit-protocol.md +63 -19
  372. package/adapters/pi/skills/forge-guide/references/forge-config-schema.json +20 -2
  373. package/adapters/pi/skills/forge-guide/references/process-overview.md +2 -2
  374. package/adapters/pi/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  375. package/adapters/pi/skills/forge-guide/references/shared-conventions.md +33 -22
  376. package/adapters/pi/skills/forge-verify/SKILL.md +10 -11
  377. package/adapters/pi/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  378. package/adapters/pi/skills/forge-verify/references/findings-template.md +31 -1
  379. package/adapters/pi/skills/forge-verify/references/shared-conventions.md +33 -22
  380. package/adapters/pi/skills/forge-verify/references/stage-exit-protocol.md +63 -19
  381. package/adapters/pi/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  382. package/adapters/pi/skills/forge-verify/references/verification-checklists/epic.md +1 -1
  383. package/adapters/pi/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  384. package/adapters/pi/skills/forge-verify/references/verification-checklists/specs.md +43 -1
  385. package/dist/manifest.d.ts +1 -1
  386. package/dist/rauf.d.ts +3 -3
  387. package/dist/rauf.js +2 -2
  388. package/dist/types.d.ts +1 -1
  389. package/package.json +1 -1
@@ -34,7 +34,7 @@ python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specs
34
34
  ```
35
35
  and show one rollup line: `{epic} — {complete}/{total} complete, next: {nextCommand}`.
36
36
  2. **Standalone features below.** Scan the remaining `{specsDir}/*/` that directly contain a `.pipeline-state.json` **without** an `epic` back-pointer. A nested member's `.pipeline-state.json` is **attributed to its epic (Tier 1), never listed as a standalone feature**.
37
- - **Rank by recency.** Run the recency ranker so the most-recently-touched active feature is the default — the user rarely has to type a name (especially on mobile after a clear your session / start a fresh session):
37
+ - **Rank by recency.** Run the recency ranker so the most-recently-touched active feature is the default — the user rarely has to type a name (especially on mobile after a session clear):
38
38
  ```bash
39
39
  R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
40
40
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
@@ -96,7 +96,7 @@ After rendering a **per-feature** dashboard for an **active** pipeline (skip thi
96
96
  - **Epic member** (this feature's `rank-features` row has a non-null `epic`, i.e. its `.pipeline-state.json` carries an `epic` back-pointer): run `epic-manifest.py render-status "{epic}" --specs-dir "{specsDir}" --json` (standard prelude; you likely already have this from the Tier-1 epic rollup — reuse it rather than re-running). Then:
97
97
  - If `actionable` is non-empty, offer the next member via the host's question mechanism: *"Epic '{epic}' has {total−complete} feature(s) left — next up: **{actionable[0].name}** (`{actionable[0].nextCommand}`). Start it now?"* On accept, drive it exactly like a normal next stage (honor `autoInvokeNextStage` + `Skill`-tool availability per step 3's Continue-in-this-session rule; else print `{nextCommand}`). List any remaining `actionable` members as also-available.
98
98
  - If `actionable` is empty but the epic is **not** fully complete (members blocked on unmet `dependsOn`), say so and point at the blockers rather than offering a start.
99
- - If the epic is **fully complete** (`rollup.complete == rollup.total`, `total > 0`), congratulate on the whole epic and offer the epic-level architecture doc (`/feature-forge:forge-6-docs` already surfaces this — mention it) and/or that the epic can be marked complete (`/feature-forge:forge {epic}` renders the finished dashboard).
99
+ - If the epic is **fully complete** (`rollup.complete == rollup.total`, `total > 0`), congratulate on the whole epic. Offer the epic-level architecture doc **only when every member row's `docsStatus` is `complete` or `skipped`** (#173 — the orchestration rollup counts loop-completeness, so it reads full before any docs exist; a `skipped` docs stage satisfies by decision, #197). When some members' docs are still unwritten, point at the next docs run (`/feature-forge:forge-6-docs {member}`) instead of the epic doc. Either way, mention the epic can be marked complete (`/feature-forge:forge {epic}` renders the finished dashboard).
100
100
  - **Standalone** (row's `epic` is null): offer to start a fresh feature — *"Start a new feature: `/feature-forge:forge-1-prd <feature-name>` (or group several with `/feature-forge:forge-0-epic <epic-name>`)."* Then, from the `rank-features` `active` list, surface any **other** active pipelines (exclude this just-completed one) as a one-line list with their `nextCommand`s so the user can jump straight back into in-flight work. If the **detached-epic hint above fired** for this feature, lead with that recovery path (`docs/recovery-detached-epic-member.md`) — the split-brain reconcile is the more likely next action than starting something new.
101
101
 
102
102
  **2. Check the context window.** Run the context-usage helper so you can advise whether to continue here or start the next stage in a fresh session:
@@ -110,7 +110,7 @@ python3 "$R/scripts/forge-session.py" context-usage --json
110
110
 
111
111
  **2b. Auto-verify catch-up (when `verifyPending` is true).** Under this behavior the just-completed authoring stage runs auto-verify **in-stage** (`references/stage-exit-protocol.md`, in-stage verify block), which clears `verifyPending` — so on the normal path this branch does **nothing**. It fires only as a **catch-up**, for any of three reasons: the producing stage could not dispatch a clean-room subagent (non-Claude host); it ran before this behavior landed; or the stage exit **recorded durable `auto-verify-pending` debt** that was never discharged — the row's `verifyState` is `auto-pending`, meaning verification was scheduled on disk and never ran (a dropped or declined in-stage dispatch, a crash, or a cleared session). **This branch fires on an `auto-pending` row**: the debt is owed and recorded, so treat it exactly like any other outstanding verification and never as "never verified" or as already discharged. Lead with the obligation sentence from the legend before acting. When it does fire, decide whether verify runs automatically (identical logic to the in-stage run, so a stage that already verified is never double-verified):
112
112
 
113
- - **`autoVerify` is true for the just-completed `verifyStage`** → **skip the verify question entirely** and run verify now, *provided it can run clean-room*. Auto-verify is safe to run unattended only because verify executes in a fresh `forge-verifier` subagent that inherits none of this session's context (so no clear your session / start a fresh session is needed and only a compact digest returns). Guard the clean-room assumption: proceed unattended **only when the host's subagent mechanism + `forge-verifier` subagent are available**. Invoke `feature-forge:forge-verify` via the host's skill-invocation mechanism in **require-clean (`auto`) mode**, passing the literal `owner: nested` token in the invocation prompt — you are the dispatcher here, so **you** are the sole terminal owner and the branch skill prints no terminal block of its own (see "Branch ownership: the `owner:` token" in `references/stage-exit-protocol.md`). In require-clean mode forge-verify refuses to run inline and returns a sentinel if the subagent is not dispatchable (see `skills/forge-verify/SKILL.md`). Then:
113
+ - **`autoVerify` is true for the just-completed `verifyStage`** → **skip the verify question entirely** and run verify now, *provided it can run clean-room*. Auto-verify is safe to run unattended only because verify executes in a fresh `forge-verifier` subagent that inherits none of this session's context (so no session clear is needed and only a compact digest returns). Guard the clean-room assumption: proceed unattended **only when the host's subagent mechanism + `forge-verifier` subagent are available**. Invoke `feature-forge:forge-verify` via the host's skill-invocation mechanism in **require-clean (`auto`) mode**, passing the literal `owner: nested` token in the invocation prompt — you are the dispatcher here, so **you** are the sole terminal owner and the branch skill prints no terminal block of its own (see "Branch ownership: the `owner:` token" in `references/stage-exit-protocol.md`). This is a **delegate-and-resume** site (see "Caller-side resumption" in the same reference): on the sub-skill's return, control returns here — continue at the matching outcome branch below. In require-clean mode forge-verify refuses to run inline and returns a sentinel if the subagent is not dispatchable (see `skills/forge-verify/SKILL.md`). Then:
114
114
  - **Sentinel returned (clean-room unavailable)** → do **not** run verify inline. Degrade to the manual gate: fall through to step 3 with the **"Verify `{stage}` first (manual)"** option included, and if `overThreshold`, recommend "clear your session / start a fresh session, then verify in a clean session." Verify state stays outstanding; the stage is never advanced on false assurance.
115
115
  - **Verify passed / no findings** → proceed to the normal advance gate (step 3), no verify option.
116
116
  - **Verify found findings** →
@@ -127,9 +127,9 @@ python3 "$R/scripts/forge-session.py" context-usage --json
127
127
  - **Pick a different stage** — free-form escape to any stage or other action.
128
128
 
129
129
  **4. Act on the choice.**
130
- - **Clean session** (the default) → give the exact next command and the clear your session / start a fresh session-then-re-run instruction; do not invoke anything (you cannot clear your session / start a fresh session for the user).
131
- - **Continue in this session** → if `autoInvokeNextStage` is true (default) **and** the host's skill-invocation mechanism is available, invoke the chosen stage **via the host's skill-invocation mechanism** in this same session (e.g. `skill: "feature-forge:forge-3-specs"`, `args: "{feature}"`) — no retyping, no paste. If `autoInvokeNextStage` is false, or the host's skill-invocation mechanism is unavailable (a non-Claude host), fall back to printing `{nextCommand}` prominently for the user to run.
132
- - **Verify now / Verify now + enable auto-verify** → invoke `feature-forge:forge-verify` via the host's skill-invocation mechanism (require-clean mode) with the literal `owner: nested` token. **Every navigator dispatch of `forge-verify`/`forge-fix` — the step 2b catch-up chain, this gate, and the "Apply fixes now" choice of the findings digest — carries `owner: nested`**, so the branch skill returns its structured result and prints no terminal block, and the navigator stays the sole terminal owner. For the **enable-auto-verify** variant, additionally patch `autoVerify: true` into `forge.config.json` in place (preserve formatting and other keys) — never a silent write. On a non-Claude host or when degrading to the manual/inline gate, print `{verifyCommand}` instead.
130
+ - **Clean session** (the default) → give the exact next command and the session clear-then-re-run instruction; do not invoke anything (you cannot clear your session / start a fresh session for the user).
131
+ - **Continue in this session** → if `autoInvokeNextStage` is true (default) **and** the host's skill-invocation mechanism is available, invoke the chosen stage **via the host's skill-invocation mechanism** in this same session (e.g. `skill: "feature-forge:forge-3-specs"`, `args: "{feature}"`) — no retyping, no paste. This advance is a **terminal handoff** (see "Caller-side resumption" in `references/stage-exit-protocol.md`): the invoked stage owns the terminal from here — the navigator's job ends at the invocation, deliberately, not by omission. If `autoInvokeNextStage` is false, or the host's skill-invocation mechanism is unavailable (a non-Claude host), fall back to printing `{nextCommand}` prominently for the user to run.
132
+ - **Verify now / Verify now + enable auto-verify** → invoke `feature-forge:forge-verify` via the host's skill-invocation mechanism (require-clean mode) with the literal `owner: nested` token. **Every navigator dispatch of `forge-verify`/`forge-fix` — the step 2b catch-up chain, this gate, and the "Apply fixes now" choice of the findings digest — carries `owner: nested`**, so the branch skill returns its structured result and prints no terminal block, and the navigator stays the sole terminal owner. Each is a **delegate-and-resume** site: on return, control returns to this gate's flow — act on the result (digest, gate, or advance) yourself; the branch skill's own close never ends the dashboard turn. For the **enable-auto-verify** variant, additionally patch `autoVerify: true` into `forge.config.json` in place (preserve formatting and other keys) — never a silent write. On a non-Claude host or when degrading to the manual/inline gate, print `{verifyCommand}` instead.
133
133
  - **Different stage** → honor the free-form request.
134
134
 
135
135
  **Host fallback.** On a non-Claude host or when the host's skill-invocation and subagent mechanisms are unavailable, auto-verify never runs unattended — fall back to printing `{verifyCommand}` exactly as today, mirroring `autoInvokeNextStage`.
@@ -213,8 +213,8 @@ Support these sub-commands for pipeline lifecycle management:
213
213
  - `/feature-forge:forge abandon {feature}` — Set `pipelineStatus` to `"abandoned"`. Use the host's question mechanism to confirm first, and state what's reversible: abandoning does not delete artifacts and can be undone with `/feature-forge:forge resume {feature}`, so the cost is low — but if the user really means "stop and discard," point out that `pause` is the better choice when they're only setting it aside. Offer **Abandon** · **Pause instead** · **Cancel**.
214
214
  - `/feature-forge:forge run [{feature}]` — **Opt-in auto-advance.** Drive the feature through consecutive stages in one session instead of confirming each boundary. This is a convenience wrapper over **3b. Drive to the Next Stage** — same stage order, same context gate — just looped:
215
215
  1. Resolve the feature (if omitted, use the recency default from `rank-features`; if multiple are equally plausible, ask once via the host's question mechanism).
216
- 2. **Before each stage,** run `forge-session.py context-usage`. If `overThreshold` is true, **stop** and recommend a clean session (give the exact `{nextCommand}` and the clear your session / start a fresh session-then-re-run instruction) — never auto-clear your session / start a fresh session.
217
- 3. Otherwise invoke the next stage's skill via the host's skill-invocation mechanism, let it run to its natural stopping point, then re-read state and continue from step 2.
216
+ 2. **Before each stage,** run `forge-session.py context-usage`. If `overThreshold` is true, **stop** and recommend a clean session (give the exact `{nextCommand}` and the session clear-then-re-run instruction) — never auto-clear your session / start a fresh session.
217
+ 3. Otherwise invoke the next stage's skill via the host's skill-invocation mechanism as a **delegate-and-resume** invocation, declaring the resume point at the invocation (see "Caller-side resumption: the declared resume point" in `references/stage-exit-protocol.md`): when the stage skill returns, control returns to **this loop, at step 2**, in the same turn — re-read state and continue. The invoked stage's own closing posture never ends the `run` loop.
218
218
  4. **Stop conditions:** the next stage is an interview/decision point that calls the host's question mechanism (PRD and tech inherently pause for input — let them); `nextStage` is `null` (pipeline complete); context over threshold; or a stage signals it needs human input / is blocked. Always report where the loop stopped and why.
219
219
  Per-stage confirmation (3b) remains the default — `run` is only used when the user explicitly asks to "run" / "drive" / "auto-advance" the pipeline. On a non-Claude host where the host's skill-invocation mechanism is unavailable, fall back to printing the ordered list of commands to run.
220
220
 
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "notes": {
39
39
  "type": "string",
40
- "description": "Free-form notes persisted between sessions (user can add context before stepping away)"
40
+ "description": "Free-form notes persisted between sessions (user can add context before stepping away). A single string with latest-note-wins semantics: `state-note` (its only sanctioned writer) OVERWRITES the previous value — an author folds any still-relevant earlier note into the one combined string. Read by the navigator dashboard AND by each downstream stage's Step 1 carried-over note check (forge-2-tech through forge-5-loop), which surfaces it as stage input; it never overrides artifacts or config."
41
41
  },
42
42
  "epicChangeRequests": {
43
43
  "type": "array",
@@ -127,7 +127,7 @@
127
127
  "forge-4-backlog": { "$ref": "#/definitions/stageEntry" },
128
128
  "forge-verify-backlog": { "$ref": "#/definitions/verifyEntry" },
129
129
  "forge-5-loop": { "$ref": "#/definitions/stageEntry" },
130
- "forge-6-docs": { "$ref": "#/definitions/stageEntry" },
130
+ "forge-6-docs": { "$ref": "#/definitions/docsStageEntry" },
131
131
  "forge-verify-impl": { "$ref": "#/definitions/verifyEntry" },
132
132
  "forge-verify-prd": { "$ref": "#/definitions/verifyEntry" },
133
133
  "forge-verify-tech": { "$ref": "#/definitions/verifyEntry" }
@@ -165,6 +165,38 @@
165
165
  }
166
166
  }
167
167
  },
168
+ "docsStageEntry": {
169
+ "type": "object",
170
+ "required": ["status"],
171
+ "description": "The forge-6-docs stage entry: identical to stageEntry except that `skipped` is a legal status and `skippedAt` records when the deliberate skip was written (by the `state-skip` verb, never by hand). `skipped` is a terminal, done-for-selection status — the pipeline ends without the stage claiming artifacts it never produced (#197). Deliberately scoped to the docs stage: a skipped PRD or specs stage is not a representable state, so the shared stageEntry enum does NOT carry `skipped`.",
172
+ "properties": {
173
+ "status": {
174
+ "type": "string",
175
+ "enum": ["pending", "in-progress", "complete", "stale", "skipped"]
176
+ },
177
+ "version": {
178
+ "type": "integer",
179
+ "description": "Incremented each time this stage's artifacts are revised"
180
+ },
181
+ "artifacts": {
182
+ "type": "array",
183
+ "items": { "type": "string" },
184
+ "description": "Relative paths to artifacts produced by this stage"
185
+ },
186
+ "startedAt": { "type": ["string", "null"], "format": "date-time" },
187
+ "completedAt": { "type": ["string", "null"], "format": "date-time" },
188
+ "skippedAt": { "type": ["string", "null"], "format": "date-time", "description": "UTC ISO-8601 timestamp of the deliberate skip (status: skipped). Written by `state-skip`; absent on every other status." },
189
+ "commitHash": {
190
+ "type": ["string", "null"],
191
+ "description": "Git commit SHA of this stage's artifact commit (Commit 1 of the two-commit Git Commit Protocol in shared-conventions.md). Written by a small follow-up commit so it points at the artifact commit itself, never at an orphaned amend or the hash-recording commit. null until recorded (or when there was no new artifact commit)."
192
+ },
193
+ "basedOnVersions": {
194
+ "type": "object",
195
+ "description": "Upstream stage versions this artifact was built against",
196
+ "additionalProperties": { "type": "integer" }
197
+ }
198
+ }
199
+ },
168
200
  "verifyEntry": {
169
201
  "type": "object",
170
202
  "required": ["status"],
@@ -37,7 +37,7 @@ The pipeline compiles a fuzzy feature idea into a machine-executable `backlog.js
37
37
  **Method:** Clean-context analysis producing actionable findings with an ordered fix plan.
38
38
 
39
39
  **Manual or automatic.** By default the navigator offers verification after each stage. Because
40
- it runs in a fresh, read-only subagent (clean-room by construction, never needs a `/clear`), it is
40
+ it runs in a fresh, read-only subagent (clean-room by construction, never needs a session clear), it is
41
41
  safe to automate: set `autoVerify: true` (or per-stage via `autoVerifyStages`) in
42
42
  `forge.config.json` and the navigator runs `forge-verify` automatically once a stage completes,
43
43
  returning only a compact digest to the session. The freshness ledger (verify entries record the
@@ -118,7 +118,7 @@ they track the current model tier automatically.
118
118
 
119
119
  ### forge-verifier
120
120
  - **Purpose:** Read-only verification of pipeline artifacts
121
- - **Used by:** `forge-verify` skill (delegation via Agent tool)
121
+ - **Used by:** `forge-verify` skill (delegation via host's subagent mechanism)
122
122
  - **Tools:** Read, Glob, Grep, Bash (read-only operations only)
123
123
  - **Model:** Opus (judgement-heavy gap/inconsistency analysis)
124
124
  - **Memory:** Project-scoped persistent memory — accumulates knowledge about recurring issues and project-specific patterns across sessions
@@ -15,11 +15,11 @@ If no feature name is provided:
15
15
 
16
16
  ## User Input Protocol
17
17
 
18
- ### CRITICAL GUARDRAIL: Use AskUserQuestion for All Questions
18
+ ### CRITICAL GUARDRAIL: Use the host's question mechanism for All Questions
19
19
 
20
- You MUST use the `AskUserQuestion` tool whenever you need the user's input before proceeding. This includes yes/no confirmations, choices between options, interview questions, and feedback on artifacts. NEVER output questions as inline prose text — the user may not be prompted and the session will stall.
20
+ You MUST use the host's question mechanism whenever you need the user's input before proceeding. This includes yes/no confirmations, choices between options, interview questions, and feedback on artifacts. NEVER output questions as inline prose text — the user may not be prompted and the session will stall.
21
21
 
22
- **Required turn structure:** Output your analysis, findings, or context as regular text. Then call `AskUserQuestion` with your questions. Do NOT mix questions into your text output.
22
+ **Required turn structure:** Output your analysis, findings, or context as regular text. Then call the host's question mechanism with your questions. Do NOT mix questions into your text output.
23
23
 
24
24
  **WRONG — questions as inline prose (causes stalling):**
25
25
  ```
@@ -31,14 +31,14 @@ I found that the codebase uses React and TanStack Router. Here are my questions:
31
31
  **RIGHT — context as text, questions via tool:**
32
32
  ```
33
33
  I found that the codebase uses React and TanStack Router.
34
- [then call AskUserQuestion with: "1. Where should this component live? 2. Should we use server-side rendering?"]
34
+ [then call the host's question mechanism with: "1. Where should this component live? 2. Should we use server-side rendering?"]
35
35
  ```
36
36
 
37
37
  ### Decision Support: Help the User Choose
38
38
 
39
- When an `AskUserQuestion` carries substantive options (a real choice — not a trivial yes/no confirmation), do not just list them. The interview stages have already done codebase research and integration analysis; surfacing that synthesis at the decision moment is the whole point. For every such question:
39
+ When a question posed through the host's question mechanism carries substantive options (a real choice — not a trivial yes/no confirmation), do not just list them. The interview stages have already done codebase research and integration analysis; surfacing that synthesis at the decision moment is the whole point. For every such question:
40
40
 
41
- - **Lead with a recommended option.** Place it first and label it `(recommended)` (matching the `AskUserQuestion` "(Recommended)" convention).
41
+ - **Lead with a recommended option.** Place it first and label it `(recommended)` (matching the host's question mechanism "(Recommended)" convention).
42
42
  - **Put the trade-off in each option's `description`.** Say why you'd pick it and what you give up versus the alternatives — the cost, not just the benefit.
43
43
  - **State a one-line rationale** in the text before the question for *why* the recommendation wins.
44
44
 
@@ -49,10 +49,21 @@ Two modes, and make clear which one you're in:
49
49
 
50
50
  **The only thing to avoid is false confidence** — recommending as if evidence-backed when it's really preference. Never respond to the absence of a clear winner by going silent: a defaulted recommendation with honest trade-offs always beats a neutral option dump.
51
51
 
52
- For genuinely comparable artifacts (competing module structures, two code snippets, layout variants), use the `AskUserQuestion` `preview` field to show them side-by-side.
52
+ For genuinely comparable artifacts (competing module structures, two code snippets, layout variants), use the host's question mechanism `preview` field to show them side-by-side.
53
53
 
54
54
  The **Branch Setup** block below is the reference pattern: a strong recommendation as the first option, rationale inline, the alternative still available, never a hard-stop.
55
55
 
56
+ ## Stage Review Gate
57
+
58
+ Every authoring stage ends its "Review with User" step in exactly one of two shapes. Which shape a stage uses is declared **here, once** — each stage's review step points at this block by title, and the shape is never re-derived from the surrounding prose or inferred from how sibling stages behave (three stages block and one does not; majority-shape inference is precisely the failure this block exists to prevent):
59
+
60
+ - **Blocking review (gate).** The stage presents the artifact and collects feedback through the host's question mechanism; it does **not** proceed until the user answers, iterating until they confirm. Stages: **forge-1-prd** (Step 5), **forge-2-tech** (Step 6), **forge-3-specs** (Step 6).
61
+ - **Non-blocking review (invitation).** The stage states the artifact is ready and invites adjustments **as a statement, not a question** — and then **proceeds to the next step in the same turn unless the user asks for changes**. The invitation obliges the agent to *continue*: emitting the invitation sentence and stopping treats the non-gate as a gate and strands the stage `in-progress` with its completion step unrun — a defect, not caution. Stage: **forge-4-backlog** (Step 6).
62
+
63
+ **Why the shapes differ.** A blocking review guards an artifact whose content was just authored from open-ended interview or synthesis — the user is the only authority on "complete", so the stage must wait. forge-4's backlog is *derived* from specs the user already approved, was planned interactively in its Step 3, and is machine-validated in its Step 5; a second hard gate would re-ask a settled question, and the loop never launches without forge-5-loop's own Step 2d confirmation anyway. The invitation is a courtesy checkpoint, not an approval gate (removed deliberately in #78's consistency sweep).
64
+
65
+ A stage that changes shape changes it **in this block first**; the per-stage pointer stays a pointer.
66
+
56
67
  ## Configuration Reading
57
68
 
58
69
  Read `forge.config.json` from the project root. If it doesn't exist, use defaults.
@@ -68,10 +79,10 @@ Extract these config values (use defaults if not present):
68
79
  - `branchPerFeature` (default: true)
69
80
  - `branchPrefix` (default: `forge/`)
70
81
  - `loopIterationMultiplier` (default: `1.5`)
71
- - `autoInvokeNextStage` (default: `true` — the `/feature-forge:forge` navigator auto-invokes the next stage via the `Skill` tool after the user confirms; `false` keeps copy-paste behavior. Navigator-only.)
82
+ - `autoInvokeNextStage` (default: `true` — the `/feature-forge:forge` navigator auto-invokes the next stage via the host's skill-invocation mechanism after the user confirms; `false` keeps copy-paste behavior. Navigator-only.)
72
83
  - `contextWindowTokens` (default: `null` — context window used by the navigator's context-usage check; `null` infers from the session model and falls back to 200000. Set to the model's window, e.g. `1000000` on a 1M model. Navigator-only.)
73
84
  - `contextWarnThreshold` (default: `0.7` — fraction of the window past which the navigator recommends a clean session. Navigator-only.)
74
- - `autoVerify` (default: `false` — when `true`, `forge-verify` runs automatically after a stage completes, no prompt. **In-stage-primary:** the just-completed authoring stage runs it itself, in-session, before the exit block (honoring the verify-before-clear principle). The navigator runs it only as a **catch-up** when verify is still pending (a host that could not dispatch a clean-room subagent, or a stage run before this behavior landed). Either way it runs in a fresh clean-room subagent, so it never needs a `/clear` and costs only a compact digest.)
85
+ - `autoVerify` (default: `false` — when `true`, `forge-verify` runs automatically after a stage completes, no prompt. **In-stage-primary:** the just-completed authoring stage runs it itself, in-session, before the exit block (honoring the verify-before-clear principle). The navigator runs it only as a **catch-up** when verify is still pending (a host that could not dispatch a clean-room subagent, or a stage run before this behavior landed). Either way it runs in a fresh clean-room subagent, so it never needs a session clear and costs only a compact digest.)
75
86
  - `autoVerifyStages` (default: `{}` — per-stage overrides for `autoVerify`, e.g. `{"forge-1-prd": false}`. Effective value = `autoVerifyStages[stage]` if present, else `autoVerify`. Keys are constrained to the five verify-capable stages; a typo is a config error surfaced as `invalidAutoVerifyKeys`. Both the in-stage run and the navigator catch-up read this same effective value.)
76
87
  - `autoFix` (default: `false` — when `true`, `forge-fix` is chained after an auto-verify that finds issues — by the in-stage run (primary) or the navigator catch-up — but only when auto-verify is on for that stage AND preconditions hold (zero unresolved decisions, clean tree, passing re-verify); otherwise a digest is surfaced and the gate is presented.)
77
88
  - `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`.)
@@ -81,7 +92,7 @@ Extract these config values (use defaults if not present):
81
92
  Before any file I/O against a feature's artifacts, resolve its directory through the deterministic helper rather than hardcoding `{specsDir}/{feature}/`. This makes flat (`{specsDir}/{feature}/`) and nested (`{specsDir}/{epic}/{feature}/`) layouts both resolve from a bare feature name (REQ-DIR-03), with standalone features behaving exactly as today.
82
93
 
83
94
  ```bash
84
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
95
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
85
96
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
86
97
  resolvedFeatureDir=$(python3 "$R/scripts/epic-manifest.py" \
87
98
  resolve "<feature>" --specs-dir "<specsDir>")
@@ -96,12 +107,12 @@ In both failure cases, do not fall back to a guessed path.
96
107
  **On `not-found`, check other branches before stopping.** With `branchPerFeature`, the feature's directory (and its `.pipeline-state.json`) may exist only on its topic branch — invisible from the default branch of a fresh clone. Before concluding the pipeline does not exist, run the read-only cross-branch discovery:
97
108
 
98
109
  ```bash
99
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
110
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
100
111
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
101
112
  python3 "$R/scripts/forge-session.py" discover-feature "<feature>" --specs-dir "<specsDir>" --json
102
113
  ```
103
114
 
104
- - **Candidates found** (`candidates` and/or `remoteCandidates` non-empty): summarize them as text (branch, recorded stage, whether the state's own `branch` field matches), then use `AskUserQuestion`: **Switch to `{branch}` (recommended)** — run the candidate's `switchCommand` · **Fetch + switch** — for a `needsFetch` remote candidate, run its `fetchCommand` then `switchCommand` (note its contents were matched by name only, not inspected) · **Treat `{feature}` as new on this branch** · **Stop**. A checkout is a mutation inside an otherwise read-only flow: perform it ONLY on the user's explicit accept AND with a clean working tree (`git status --porcelain` prints nothing) — never auto-switch, never with uncommitted changes. After a successful switch, re-run this Feature Directory Resolution block from the top.
115
+ - **Candidates found** (`candidates` and/or `remoteCandidates` non-empty): summarize them as text (branch, recorded stage, whether the state's own `branch` field matches), then use the host's question mechanism: **Switch to `{branch}` (recommended)** — run the candidate's `switchCommand` · **Fetch + switch** — for a `needsFetch` remote candidate, run its `fetchCommand` then `switchCommand` (note its contents were matched by name only, not inspected) · **Treat `{feature}` as new on this branch** · **Stop**. A checkout is a mutation inside an otherwise read-only flow: perform it ONLY on the user's explicit accept AND with a clean working tree (`git status --porcelain` prints nothing) — never auto-switch, never with uncommitted changes. After a successful switch, re-run this Feature Directory Resolution block from the top.
105
116
  - **Nothing found** (both lists empty): the pipeline genuinely does not exist anywhere discoverable — STOP and surface the original `not-found` stderr line verbatim (or, where the caller offers to start a new pipeline, offer that).
106
117
 
107
118
  **Anti-fabrication guard.** Never describe pipeline state that resolution or discovery did not return: if both come back empty, the pipeline does not exist — say exactly that, and never reconstruct stages, backlogs, or history from conversational memory.
@@ -124,16 +135,16 @@ Whenever a stage creates the specs tree for the first time (the first PRD or epi
124
135
  Run this after creating the feature/epic directory, before the stage's git commit:
125
136
 
126
137
  ```bash
127
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
138
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
128
139
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
129
140
  mkdir -p "<specsDir>"
130
141
  [ -f "<specsDir>/AGENTS.md" ] || cp "$R/references/templates/specs-hygiene/AGENTS.md" "<specsDir>/AGENTS.md"
131
142
  ```
132
143
 
133
- If the host is Claude (the `AskUserQuestion` tool is available), also ensure the Claude-framed variant:
144
+ If the host is Claude (the Claude-native question tool is available), also ensure the Claude-framed variant:
134
145
 
135
146
  ```bash
136
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
147
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
137
148
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
138
149
  [ -f "<specsDir>/CLAUDE.md" ] || cp "$R/references/templates/specs-hygiene/CLAUDE.md" "<specsDir>/CLAUDE.md"
139
150
  ```
@@ -153,7 +164,7 @@ After resolving the feature directory, check the feature's `.pipeline-state.json
153
164
  To obtain the manifest contracts and the live completion status of each dependency in one deterministic call, run `render-status` and read the per-feature `status` and the `consumes`/`exposes` arrays rather than re-deriving them:
154
165
 
155
166
  ```bash
156
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
167
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
157
168
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
158
169
  python3 "$R/scripts/epic-manifest.py" \
159
170
  render-status "<epic>" --specs-dir "<specsDir>" --json
@@ -168,7 +179,7 @@ If `render-status` fails, proceed with **only** EPIC.md + charter (a corrupt man
168
179
  Defense-in-depth for the split-brain-epic failure (Issue #125). Invoke this block in the authoring stages (`forge-1-prd`..`forge-4-backlog`) once the feature has resolved — right after **Epic Context Injection** for the stages that run it (`forge-1-prd`..`forge-3-specs`), and right after **Feature Directory Resolution** for `forge-4-backlog`. It confirms that a **resolved nested epic member** actually sits on a branch that contains the epic's manifest. Without this, a member reached from a branch cut *before* the epic-manifest commit (or that otherwise lacks it) would author specs against an epic decomposition that is not present — the exact drift that produces a disjoint, split-brain member. **Skip if not a git repo or `branchPerFeature` is false.**
169
180
 
170
181
  ```bash
171
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
182
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
172
183
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
173
184
  python3 "$R/scripts/forge-session.py" check-epic-base --feature "{feature}" --specs-dir "{specsDir}" --json
174
185
  ```
@@ -191,7 +202,7 @@ Pipeline state is written by the `state-*` verbs of `scripts/forge-session.py`
191
202
 
192
203
  If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbatim, do **not** proceed to the next step of the surrounding protocol, and do **not** hand-author the JSON as a workaround. The stage remains resumable because the entry stamp is already on disk — re-run the verb once the cause is fixed.
193
204
 
194
- **The eight `state-*` verbs.** `state-enter` (Stage-Entry Guard), `state-artifact` (incremental artifact tracking), `state-complete` (Git Commit Protocol), `state-branch` (Branch Setup and Branch Reconciliation), `state-note` (the Immediate Downstream Note below, and the optional completion note at stage closure), `state-decision` (deferred decisions), `state-ecr` (epic change requests), and `state-verify` (one `forge-verify-*` verification transition — below). The `--epic` member requirement and the exit-2 failure protocol above apply to **every** one of them, `state-verify` included; no verify entry is ever hand-authored.
205
+ **The nine `state-*` verbs.** `state-enter` (Stage-Entry Guard), `state-artifact` (incremental artifact tracking), `state-complete` (Git Commit Protocol), `state-skip` (the deliberate forge-6-docs documentation skip — scoped to that one stage; writes `status: "skipped"` + `skippedAt`, refuses to erase a record of docs that exist, and is the only sanctioned writer of a skipped docs stage), `state-branch` (Branch Setup and Branch Reconciliation), `state-note` (the Immediate Downstream Note below, and the optional completion note at stage closure), `state-decision` (deferred decisions), `state-ecr` (epic change requests), and `state-verify` (one `forge-verify-*` verification transition — below). The `--epic` member requirement and the exit-2 failure protocol above apply to **every** one of them, `state-verify` included; no verify entry is ever hand-authored.
195
206
 
196
207
  ### `state-verify` — verification results and provenance
197
208
 
@@ -200,7 +211,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
200
211
  **`auto-verify-pending` is not a skill-facing status.** It is written by `stage-exit`'s scheduling boundary, which records the debt automatically when auto-verify is effective for a stage. The value is accepted on this CLI so the entry stays inspectable and repairable, not so a skill can hand-schedule verification: no skill body and no reference passes it, and none should. Every other status in the list is the recorded *result* of a verification that ran (or was explicitly skipped); this one records that one was *owed*.
201
212
 
202
213
  ```bash
203
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
214
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
204
215
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
205
216
  python3 "$R/scripts/forge-session.py" state-verify \
206
217
  --feature "{feature}" --stage "{served-production-stage}" --status "<status>" \
@@ -210,7 +221,7 @@ python3 "$R/scripts/forge-session.py" state-verify \
210
221
  Provenance follows the same two-commit sequence as `state-complete`: the result transition above writes `commitHash: null`, Commit 1 records the findings document and the state, and a second `state-verify` call records the full 40-hex hash of Commit 1 and touches nothing else (never `--amend`; an abbreviated hash is refused rather than expanded). Add `--epic "{epic}"` for an epic member — required, per the member rule above:
211
222
 
212
223
  ```bash
213
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
224
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
214
225
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
215
226
  python3 "$R/scripts/forge-session.py" state-verify \
216
227
  --feature "{feature}" --stage "{served-production-stage}" \
@@ -220,7 +231,7 @@ python3 "$R/scripts/forge-session.py" state-verify \
220
231
  Epic-scoped verification is the single exception to the member rule: with `--stage forge-0-epic`, `--feature` names the **epic** and `--epic` must be absent or exactly equal to it. That call writes `{specsDir}/{epic}/.epic-state.json` and never a member's `.pipeline-state.json`, and its freshness version is the epic manifest's `revision`, never a member's stage version:
221
232
 
222
233
  ```bash
223
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
234
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
224
235
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
225
236
  python3 "$R/scripts/forge-session.py" state-verify \
226
237
  --feature "{epic}" --stage forge-0-epic --status "<status>" \
@@ -242,7 +253,7 @@ Frame the choice with its cost: re-running re-derives this stage from the curren
242
253
  When an interview raises a concern that belongs to a *later stage of this same feature*, acknowledge it and persist it **immediately, at the moment it is raised** — not at stage closure — by running `state-note` with a concise one-line statement of the concern. Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol above; omitting it for a member is an error and must never be allowed to fall back to a same-named flat feature.
243
254
 
244
255
  ```bash
245
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
256
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
246
257
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
247
258
  python3 "$R/scripts/forge-session.py" state-note \
248
259
  --feature "{feature}" --note "<concise downstream concern>" \
@@ -275,7 +286,7 @@ Invoke this block at the **very start** of a pipeline entry point — `forge-1-p
275
286
  1. Read the current branch: `git rev-parse --abbrev-ref HEAD`.
276
287
  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.
277
288
  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.
278
- 4. **If the current branch IS the default branch** → use `AskUserQuestion` with a **strong recommendation** (still optional):
289
+ 4. **If the current branch IS the default branch** → use the host's question mechanism with a **strong recommendation** (still optional):
279
290
 
280
291
  > "You're on `{defaultBranch}`. Strongly recommended: create `{branchPrefix}{label}` so this {scope}'s work stays isolated and reviewable as one branch. Create it?"
281
292
  > Options: **Create `{branchPrefix}{label}` (recommended)** · **Stay on `{defaultBranch}`**
@@ -286,7 +297,7 @@ Invoke this block at the **very start** of a pipeline entry point — `forge-1-p
286
297
  **Record the branch.** After this block resolves, record the resulting branch name in the feature's top-level `branch` field by running `state-branch` (create/update it when the state file is first written for this stage). Emit the call **once the feature directory exists** — i.e. after Feature Directory Resolution and the Entry Stamp, **not** at this block: Branch Setup runs at the very start of the entry point, before any directory resolution, and a brand-new standalone feature may have no directory yet. Add `--epic "{epic}"` to the call when this feature is an epic member — required, per the Pipeline State Protocol.
287
298
 
288
299
  ```bash
289
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
300
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
290
301
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
291
302
  python3 "$R/scripts/forge-session.py" state-branch \
292
303
  --feature "{feature}" --branch "<name>" --specs-dir "{specsDir}"
@@ -299,20 +310,20 @@ Downstream stages and `forge-5-loop` read it to detect drift back onto the defau
299
310
  The recorded `branch` is a **self-healing hint, not gospel.** A hosted environment (Claude.ai remote, cloud agents) can impose an arbitrary session branch (e.g. `claude/<slug>`) that Branch Setup silently records; the user may then move the work to the intended topic branch, leaving the recorded field stale. Every branch-aware mechanism (the `forge-5-loop` guard, `discover-feature`) keys off that field, so a stale value actively misleads — the loop would offer to switch you *back* to the imposed branch. Invoke this block from `forge-5-loop`'s pre-flight (and any stage that acts on the recorded branch) to reconcile deterministically. Skip if not a git repo or `branchPerFeature` is false.
300
311
 
301
312
  ```bash
302
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
313
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
303
314
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
304
315
  python3 "$R/scripts/forge-session.py" reconcile-branch --feature "{feature}" --specs-dir "{specsDir}" --json
305
316
  ```
306
317
 
307
318
  Act on the emitted `action` (source of truth is where the state actually resolves, not the recorded field):
308
319
  - **`adopt-current`** — you are on a non-default topic branch where the state resolves, and the recorded `branch` differs (a stale/imposed value). Run `state-branch` (below) to write `newBranch` into the state `branch` field, with a **visible one-line note** ("recorded branch was `{stateBranch}`; work is on `{currentBranch}` — updating to match") — never silently, and **never push the user back** to the recorded branch (offer that only as a plain alternative).
309
- - **`warn-drift`** — you are on the **default** branch and the state records a topic branch. Via `AskUserQuestion`, strongly recommend creating/switching to `{branchPrefix}{feature}` (then record it), still allowing **proceed on the default branch**. Never hard-stop.
320
+ - **`warn-drift`** — you are on the **default** branch and the state records a topic branch. Via the host's question mechanism, strongly recommend creating/switching to `{branchPrefix}{feature}` (then record it), still allowing **proceed on the default branch**. Never hard-stop.
310
321
  - **`none`** / **`not-resolved`** — nothing to do; proceed.
311
322
 
312
323
  The `adopt-current` write, with the portable plugin-root prelude. Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol:
313
324
 
314
325
  ```bash
315
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
326
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
316
327
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
317
328
  python3 "$R/scripts/forge-session.py" state-branch \
318
329
  --feature "{feature}" --branch "{newBranch}" --specs-dir "{specsDir}"
@@ -338,7 +349,7 @@ When `gitCommitAfterStage` is true, follow this exact order to avoid state incon
338
349
  The two `state-complete` calls, with the portable plugin-root prelude. Add `--epic "{epic}"` to each when this feature is an epic member — required, per the Pipeline State Protocol:
339
350
 
340
351
  ```bash
341
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
352
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
342
353
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
343
354
  # Commit 1 — before `git commit`
344
355
  python3 "$R/scripts/forge-session.py" state-complete \
@@ -360,15 +371,15 @@ Invoke this block at the **start of an authoring stage** (`forge-1-prd`..`forge-
360
371
 
361
372
  2. **Interrupted** (`status: "in-progress"`) — a previous run of THIS stage was interrupted before it committed (the exit commit is what flips it to `complete`, so `in-progress` on entry always means a crash/abandon). Do **not** silently re-author. Instead:
362
373
  - **Inventory on-disk artifacts:** list the files this stage produces that already exist in `{resolvedFeatureDir}/` (e.g. `PRD.md`; `tech-spec.md`; the `##-*.md` suite + `TRACEABILITY.md`; `backlog.json`), and cross-check against the `stages.{stage}.artifacts` array (written incrementally during the previous run).
363
- - **Gate via `AskUserQuestion`** (Decision Support protocol): present the inventory as text, then ask "This {stage} run was interrupted — {N} artifact(s) from the previous run are on disk: {list}. Resume the in-progress draft, or start a new version from scratch?" Options: **Resume (recommended)** — continue from the first artifact not yet written/complete, reusing the existing files; do **not** re-stamp or bump the version. · **Start a new version** — treat it as a fresh authoring pass (proceed to the Entry Stamp; the version increments at exit).
374
+ - **Gate via the host's question mechanism** (Decision Support protocol): present the inventory as text, then ask "This {stage} run was interrupted — {N} artifact(s) from the previous run are on disk: {list}. Resume the in-progress draft, or start a new version from scratch?" Options: **Resume (recommended)** — continue from the first artifact not yet written/complete, reusing the existing files; do **not** re-stamp or bump the version. · **Start a new version** — treat it as a fresh authoring pass (proceed to the Entry Stamp; the version increments at exit).
364
375
  - Skip artifact regeneration for files that already exist and are complete (non-empty, properly structured); continue from the next unwritten artifact.
365
376
 
366
- 3. **Re-authoring** (`status: "complete"` or `"stale"`) — a finished draft exists. Warn via `AskUserQuestion` before overwriting: "A completed {stage} artifact already exists for '{feature}' (v{n}{, marked stale}). Continuing will create a new version. Proceed?" On confirm, proceed to the Entry Stamp and author a new version (the version increments at exit, per that stage's Update-Pipeline-State step).
377
+ 3. **Re-authoring** (`status: "complete"` or `"stale"`) — a finished draft exists. Warn via the host's question mechanism before overwriting: "A completed {stage} artifact already exists for '{feature}' (v{n}{, marked stale}). Continuing will create a new version. Proceed?" On confirm, proceed to the Entry Stamp and author a new version (the version increments at exit, per that stage's Update-Pipeline-State step).
367
378
 
368
379
  **Entry Stamp** (fresh, restart, and re-author paths — NOT the resume path). Before authoring, record the entry stamp by running `state-enter` — one atomic write that sets `stages.{stage}.status` → `"in-progress"`, `stages.{stage}.startedAt` → current ISO-8601 UTC timestamp, top-level `currentStage` → `"{stage}"` (where the pipeline IS, per O1), and refreshes `updatedAt`. Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol:
369
380
 
370
381
  ```bash
371
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
382
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
372
383
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
373
384
  python3 "$R/scripts/forge-session.py" state-enter \
374
385
  --feature "{feature}" --stage "{stage}" --specs-dir "{specsDir}"
@@ -381,7 +392,7 @@ This write is **left uncommitted**: it is staged and committed as part of this s
381
392
  **Incremental artifact tracking:** When a stage writes multiple files (e.g. forge-3-specs writing a suite of spec documents), run `state-artifact --feature {feature} --stage {stage} --path <file>` after writing each file — not just at stage completion. This is what makes the Interrupted inventory above precise about which files were successfully written. Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol.
382
393
 
383
394
  ```bash
384
- R="$(bash -c 'for d in "${CLAUDE_PLUGIN_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
395
+ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
385
396
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
386
397
  python3 "$R/scripts/forge-session.py" state-artifact \
387
398
  --feature "{feature}" --stage "{stage}" --path "<file>" --specs-dir "{specsDir}"
@@ -395,7 +406,7 @@ Invoke this block **at the head of any post-entry step that writes a stage artif
395
406
 
396
407
  1. **Proceed** when `stages.{stage}.status` is `"in-progress"` (this session's Entry Stamp — you are finishing the run you started) or absent/`pending`. Run the write / exit normally.
397
408
 
398
- 2. **Detect-and-refuse** when ALL of these hold: `stages.{stage}.status ∈ {"complete", "stale"}` **AND** the stage's artifacts (incl. `TRACEABILITY.md` for forge-3-specs) exist on disk **AND** a `commitHash` is recorded for the stage **AND** you did **not** author this stage earlier in the current session. This is a stale/replayed continuation of an already-finished, committed stage. Do **not** overwrite the artifact or re-run the exit. Route instead to the **Stage-Entry Guard**'s *Re-authoring* path: surface the same `AskUserQuestion` warning ("A completed {stage} artifact already exists for '{feature}' (v{n}{, marked stale}). Continuing will create a new version. Proceed?"). Only on explicit confirmation re-enter from the Entry Stamp (the version bumps at exit); otherwise **stop** and report that the stage is already complete — cite the recorded `commitHash` and offer `/feature-forge:forge {feature}` to see true state.
409
+ 2. **Detect-and-refuse** when ALL of these hold: `stages.{stage}.status ∈ {"complete", "stale"}` **AND** the stage's artifacts (incl. `TRACEABILITY.md` for forge-3-specs) exist on disk **AND** a `commitHash` is recorded for the stage **AND** you did **not** author this stage earlier in the current session. This is a stale/replayed continuation of an already-finished, committed stage. Do **not** overwrite the artifact or re-run the exit. Route instead to the **Stage-Entry Guard**'s *Re-authoring* path: surface the same warning via the host's question mechanism ("A completed {stage} artifact already exists for '{feature}' (v{n}{, marked stale}). Continuing will create a new version. Proceed?"). Only on explicit confirmation re-enter from the Entry Stamp (the version bumps at exit); otherwise **stop** and report that the stage is already complete — cite the recorded `commitHash` and offer `/feature-forge:forge {feature}` to see true state.
399
410
 
400
411
  When you cannot confirm you authored the current run, treat it as a replay and refuse: a false refuse costs one confirmation click; a false proceed overwrites a committed artifact and re-churns a stage version. `--force` follows Force Mode (skip the gate, treat as a deliberate re-author).
401
412