@garygentry/feature-forge 0.3.1 → 0.3.4

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 (421) hide show
  1. package/adapters/claude/.feature-forge-bundle.json +1 -1
  2. package/adapters/claude/agents/forge-verifier.md +3 -1
  3. package/adapters/claude/references/decisions/single-writer-threat-model.md +53 -0
  4. package/adapters/claude/references/epic-manifest-schema.json +6 -1
  5. package/adapters/claude/references/epic-state-schema.json +50 -0
  6. package/adapters/claude/references/forge-config-schema.json +19 -1
  7. package/adapters/claude/references/forge-decisions-schema.json +33 -0
  8. package/adapters/claude/references/pipeline-state-schema.json +38 -4
  9. package/adapters/claude/references/ralph-loop-contract.md +6 -3
  10. package/adapters/claude/references/shared-conventions.md +77 -3
  11. package/adapters/claude/references/stage-exit-protocol.md +391 -143
  12. package/adapters/claude/scripts/epic-manifest.py +495 -91
  13. package/adapters/claude/scripts/fix-sweep.py +1180 -0
  14. package/adapters/claude/scripts/forge-bootstrap.py +57 -5
  15. package/adapters/claude/scripts/forge-session.py +4241 -146
  16. package/adapters/claude/scripts/validate-traceability.py +86 -5
  17. package/adapters/claude/skills/forge/SKILL.md +10 -9
  18. package/adapters/claude/skills/forge/references/pipeline-state-schema.json +38 -4
  19. package/adapters/claude/skills/forge/references/shared-conventions.md +77 -3
  20. package/adapters/claude/skills/forge/references/stage-exit-protocol.md +391 -143
  21. package/adapters/claude/skills/forge-0-epic/SKILL.md +7 -2
  22. package/adapters/claude/skills/forge-0-epic/references/edit-mode.md +29 -25
  23. package/adapters/claude/skills/forge-0-epic/references/epic-manifest-subcommands.md +5 -0
  24. package/adapters/claude/skills/forge-0-epic/references/pipeline-state-schema.json +38 -4
  25. package/adapters/claude/skills/forge-0-epic/references/shared-conventions.md +77 -3
  26. package/adapters/claude/skills/forge-0-epic/references/stage-exit-protocol.md +391 -143
  27. package/adapters/claude/skills/forge-1-prd/SKILL.md +17 -4
  28. package/adapters/claude/skills/forge-1-prd/references/shared-conventions.md +77 -3
  29. package/adapters/claude/skills/forge-1-prd/references/stage-exit-protocol.md +391 -143
  30. package/adapters/claude/skills/forge-2-tech/SKILL.md +18 -4
  31. package/adapters/claude/skills/forge-2-tech/references/shared-conventions.md +77 -3
  32. package/adapters/claude/skills/forge-2-tech/references/stage-exit-protocol.md +391 -143
  33. package/adapters/claude/skills/forge-3-specs/SKILL.md +9 -3
  34. package/adapters/claude/skills/forge-3-specs/references/shared-conventions.md +77 -3
  35. package/adapters/claude/skills/forge-3-specs/references/spec-archetypes.md +9 -0
  36. package/adapters/claude/skills/forge-3-specs/references/stage-exit-protocol.md +391 -143
  37. package/adapters/claude/skills/forge-4-backlog/SKILL.md +56 -5
  38. package/adapters/claude/skills/forge-4-backlog/references/shared-conventions.md +77 -3
  39. package/adapters/claude/skills/forge-4-backlog/references/stage-exit-protocol.md +391 -143
  40. package/adapters/claude/skills/forge-5-loop/SKILL.md +67 -69
  41. package/adapters/claude/skills/forge-5-loop/references/agent-selection.md +16 -0
  42. package/adapters/claude/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  43. package/adapters/claude/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  44. package/adapters/claude/skills/forge-5-loop/references/result-reporting.md +101 -33
  45. package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +26 -6
  46. package/adapters/claude/skills/forge-5-loop/references/shared-conventions.md +77 -3
  47. package/adapters/claude/skills/forge-5-loop/references/stage-exit-protocol.md +391 -143
  48. package/adapters/claude/skills/forge-6-docs/SKILL.md +75 -8
  49. package/adapters/claude/skills/forge-6-docs/references/shared-conventions.md +77 -3
  50. package/adapters/claude/skills/forge-6-docs/references/stage-exit-protocol.md +516 -0
  51. package/adapters/claude/skills/forge-fix/SKILL.md +119 -33
  52. package/adapters/claude/skills/forge-fix/references/shared-conventions.md +77 -3
  53. package/adapters/claude/skills/forge-fix/references/stage-exit-protocol.md +391 -143
  54. package/adapters/claude/skills/forge-guide/references/forge-config-schema.json +19 -1
  55. package/adapters/claude/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  56. package/adapters/claude/skills/forge-guide/references/shared-conventions.md +77 -3
  57. package/adapters/claude/skills/forge-verify/SKILL.md +82 -51
  58. package/adapters/claude/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  59. package/adapters/claude/skills/forge-verify/references/findings-template.md +69 -49
  60. package/adapters/claude/skills/forge-verify/references/shared-conventions.md +77 -3
  61. package/adapters/claude/skills/forge-verify/references/stage-exit-protocol.md +516 -0
  62. package/adapters/claude/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  63. package/adapters/claude/skills/forge-verify/references/verification-checklists/epic.md +4 -3
  64. package/adapters/claude/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  65. package/adapters/claude/skills/forge-verify/references/verification-checklists/specs.md +45 -1
  66. package/adapters/codex/.feature-forge-bundle.json +1 -1
  67. package/adapters/codex/agents/forge-verifier.toml +3 -1
  68. package/adapters/codex/references/decisions/single-writer-threat-model.md +53 -0
  69. package/adapters/codex/references/epic-manifest-schema.json +6 -1
  70. package/adapters/codex/references/epic-state-schema.json +50 -0
  71. package/adapters/codex/references/forge-config-schema.json +19 -1
  72. package/adapters/codex/references/forge-decisions-schema.json +33 -0
  73. package/adapters/codex/references/pipeline-state-schema.json +38 -4
  74. package/adapters/codex/references/process-overview.md +2 -2
  75. package/adapters/codex/references/ralph-loop-contract.md +6 -3
  76. package/adapters/codex/references/shared-conventions.md +102 -28
  77. package/adapters/codex/references/stage-exit-protocol.md +395 -147
  78. package/adapters/codex/scripts/epic-manifest.py +495 -91
  79. package/adapters/codex/scripts/fix-sweep.py +1180 -0
  80. package/adapters/codex/scripts/forge-bootstrap.py +57 -5
  81. package/adapters/codex/scripts/forge-session.py +4241 -146
  82. package/adapters/codex/scripts/validate-traceability.py +86 -5
  83. package/adapters/codex/skills/forge/SKILL.md +13 -12
  84. package/adapters/codex/skills/forge/references/pipeline-state-schema.json +38 -4
  85. package/adapters/codex/skills/forge/references/process-overview.md +2 -2
  86. package/adapters/codex/skills/forge/references/shared-conventions.md +102 -28
  87. package/adapters/codex/skills/forge/references/stage-exit-protocol.md +395 -147
  88. package/adapters/codex/skills/forge-0-epic/SKILL.md +7 -2
  89. package/adapters/codex/skills/forge-0-epic/references/edit-mode.md +37 -33
  90. package/adapters/codex/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
  91. package/adapters/codex/skills/forge-0-epic/references/pipeline-state-schema.json +38 -4
  92. package/adapters/codex/skills/forge-0-epic/references/shared-conventions.md +102 -28
  93. package/adapters/codex/skills/forge-0-epic/references/stage-exit-protocol.md +395 -147
  94. package/adapters/codex/skills/forge-1-prd/SKILL.md +17 -4
  95. package/adapters/codex/skills/forge-1-prd/references/shared-conventions.md +102 -28
  96. package/adapters/codex/skills/forge-1-prd/references/stage-exit-protocol.md +395 -147
  97. package/adapters/codex/skills/forge-2-tech/SKILL.md +18 -4
  98. package/adapters/codex/skills/forge-2-tech/references/shared-conventions.md +102 -28
  99. package/adapters/codex/skills/forge-2-tech/references/stage-exit-protocol.md +395 -147
  100. package/adapters/codex/skills/forge-3-specs/SKILL.md +9 -3
  101. package/adapters/codex/skills/forge-3-specs/references/shared-conventions.md +102 -28
  102. package/adapters/codex/skills/forge-3-specs/references/spec-archetypes.md +9 -0
  103. package/adapters/codex/skills/forge-3-specs/references/stage-exit-protocol.md +395 -147
  104. package/adapters/codex/skills/forge-4-backlog/SKILL.md +56 -5
  105. package/adapters/codex/skills/forge-4-backlog/references/shared-conventions.md +102 -28
  106. package/adapters/codex/skills/forge-4-backlog/references/stage-exit-protocol.md +395 -147
  107. package/adapters/codex/skills/forge-5-loop/SKILL.md +67 -69
  108. package/adapters/codex/skills/forge-5-loop/references/agent-selection.md +17 -1
  109. package/adapters/codex/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  110. package/adapters/codex/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  111. package/adapters/codex/skills/forge-5-loop/references/result-reporting.md +101 -33
  112. package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +30 -10
  113. package/adapters/codex/skills/forge-5-loop/references/shared-conventions.md +102 -28
  114. package/adapters/codex/skills/forge-5-loop/references/stage-exit-protocol.md +395 -147
  115. package/adapters/codex/skills/forge-6-docs/SKILL.md +75 -8
  116. package/adapters/codex/skills/forge-6-docs/references/shared-conventions.md +102 -28
  117. package/adapters/codex/skills/forge-6-docs/references/stage-exit-protocol.md +516 -0
  118. package/adapters/codex/skills/forge-fix/SKILL.md +118 -32
  119. package/adapters/codex/skills/forge-fix/references/shared-conventions.md +102 -28
  120. package/adapters/codex/skills/forge-fix/references/stage-exit-protocol.md +395 -147
  121. package/adapters/codex/skills/forge-guide/SKILL.md +1 -1
  122. package/adapters/codex/skills/forge-guide/references/forge-config-schema.json +19 -1
  123. package/adapters/codex/skills/forge-guide/references/process-overview.md +2 -2
  124. package/adapters/codex/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  125. package/adapters/codex/skills/forge-guide/references/shared-conventions.md +102 -28
  126. package/adapters/codex/skills/forge-init/SKILL.md +1 -1
  127. package/adapters/codex/skills/forge-verify/SKILL.md +82 -51
  128. package/adapters/codex/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  129. package/adapters/codex/skills/forge-verify/references/findings-template.md +70 -50
  130. package/adapters/codex/skills/forge-verify/references/shared-conventions.md +102 -28
  131. package/adapters/codex/skills/forge-verify/references/stage-exit-protocol.md +516 -0
  132. package/adapters/codex/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  133. package/adapters/codex/skills/forge-verify/references/verification-checklists/epic.md +5 -4
  134. package/adapters/codex/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  135. package/adapters/codex/skills/forge-verify/references/verification-checklists/specs.md +45 -1
  136. package/adapters/copilot/.feature-forge-bundle.json +1 -1
  137. package/adapters/copilot/agents/forge-verifier.md +3 -1
  138. package/adapters/copilot/references/decisions/single-writer-threat-model.md +53 -0
  139. package/adapters/copilot/references/epic-manifest-schema.json +6 -1
  140. package/adapters/copilot/references/epic-state-schema.json +50 -0
  141. package/adapters/copilot/references/forge-config-schema.json +19 -1
  142. package/adapters/copilot/references/forge-decisions-schema.json +33 -0
  143. package/adapters/copilot/references/pipeline-state-schema.json +38 -4
  144. package/adapters/copilot/references/process-overview.md +2 -2
  145. package/adapters/copilot/references/ralph-loop-contract.md +6 -3
  146. package/adapters/copilot/references/shared-conventions.md +102 -28
  147. package/adapters/copilot/references/stage-exit-protocol.md +395 -147
  148. package/adapters/copilot/scripts/epic-manifest.py +495 -91
  149. package/adapters/copilot/scripts/fix-sweep.py +1180 -0
  150. package/adapters/copilot/scripts/forge-bootstrap.py +57 -5
  151. package/adapters/copilot/scripts/forge-session.py +4241 -146
  152. package/adapters/copilot/scripts/validate-traceability.py +86 -5
  153. package/adapters/copilot/skills/forge/forge.md +13 -12
  154. package/adapters/copilot/skills/forge/references/pipeline-state-schema.json +38 -4
  155. package/adapters/copilot/skills/forge/references/process-overview.md +2 -2
  156. package/adapters/copilot/skills/forge/references/shared-conventions.md +102 -28
  157. package/adapters/copilot/skills/forge/references/stage-exit-protocol.md +395 -147
  158. package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +7 -2
  159. package/adapters/copilot/skills/forge-0-epic/references/edit-mode.md +37 -33
  160. package/adapters/copilot/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
  161. package/adapters/copilot/skills/forge-0-epic/references/pipeline-state-schema.json +38 -4
  162. package/adapters/copilot/skills/forge-0-epic/references/shared-conventions.md +102 -28
  163. package/adapters/copilot/skills/forge-0-epic/references/stage-exit-protocol.md +395 -147
  164. package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +17 -4
  165. package/adapters/copilot/skills/forge-1-prd/references/shared-conventions.md +102 -28
  166. package/adapters/copilot/skills/forge-1-prd/references/stage-exit-protocol.md +395 -147
  167. package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +18 -4
  168. package/adapters/copilot/skills/forge-2-tech/references/shared-conventions.md +102 -28
  169. package/adapters/copilot/skills/forge-2-tech/references/stage-exit-protocol.md +395 -147
  170. package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +9 -3
  171. package/adapters/copilot/skills/forge-3-specs/references/shared-conventions.md +102 -28
  172. package/adapters/copilot/skills/forge-3-specs/references/spec-archetypes.md +9 -0
  173. package/adapters/copilot/skills/forge-3-specs/references/stage-exit-protocol.md +395 -147
  174. package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +56 -5
  175. package/adapters/copilot/skills/forge-4-backlog/references/shared-conventions.md +102 -28
  176. package/adapters/copilot/skills/forge-4-backlog/references/stage-exit-protocol.md +395 -147
  177. package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +67 -69
  178. package/adapters/copilot/skills/forge-5-loop/references/agent-selection.md +17 -1
  179. package/adapters/copilot/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  180. package/adapters/copilot/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  181. package/adapters/copilot/skills/forge-5-loop/references/result-reporting.md +101 -33
  182. package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +30 -10
  183. package/adapters/copilot/skills/forge-5-loop/references/shared-conventions.md +102 -28
  184. package/adapters/copilot/skills/forge-5-loop/references/stage-exit-protocol.md +395 -147
  185. package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +75 -8
  186. package/adapters/copilot/skills/forge-6-docs/references/shared-conventions.md +102 -28
  187. package/adapters/copilot/skills/forge-6-docs/references/stage-exit-protocol.md +516 -0
  188. package/adapters/copilot/skills/forge-fix/forge-fix.md +118 -32
  189. package/adapters/copilot/skills/forge-fix/references/shared-conventions.md +102 -28
  190. package/adapters/copilot/skills/forge-fix/references/stage-exit-protocol.md +395 -147
  191. package/adapters/copilot/skills/forge-guide/forge-guide.md +1 -1
  192. package/adapters/copilot/skills/forge-guide/references/forge-config-schema.json +19 -1
  193. package/adapters/copilot/skills/forge-guide/references/process-overview.md +2 -2
  194. package/adapters/copilot/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  195. package/adapters/copilot/skills/forge-guide/references/shared-conventions.md +102 -28
  196. package/adapters/copilot/skills/forge-init/forge-init.md +1 -1
  197. package/adapters/copilot/skills/forge-verify/forge-verify.md +82 -51
  198. package/adapters/copilot/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  199. package/adapters/copilot/skills/forge-verify/references/findings-template.md +70 -50
  200. package/adapters/copilot/skills/forge-verify/references/shared-conventions.md +102 -28
  201. package/adapters/copilot/skills/forge-verify/references/stage-exit-protocol.md +516 -0
  202. package/adapters/copilot/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  203. package/adapters/copilot/skills/forge-verify/references/verification-checklists/epic.md +5 -4
  204. package/adapters/copilot/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  205. package/adapters/copilot/skills/forge-verify/references/verification-checklists/specs.md +45 -1
  206. package/adapters/cursor/.feature-forge-bundle.json +1 -1
  207. package/adapters/cursor/agents/forge-verifier.mdc +3 -1
  208. package/adapters/cursor/references/decisions/single-writer-threat-model.md +53 -0
  209. package/adapters/cursor/references/epic-manifest-schema.json +6 -1
  210. package/adapters/cursor/references/epic-state-schema.json +50 -0
  211. package/adapters/cursor/references/forge-config-schema.json +19 -1
  212. package/adapters/cursor/references/forge-decisions-schema.json +33 -0
  213. package/adapters/cursor/references/pipeline-state-schema.json +38 -4
  214. package/adapters/cursor/references/process-overview.md +2 -2
  215. package/adapters/cursor/references/ralph-loop-contract.md +6 -3
  216. package/adapters/cursor/references/shared-conventions.md +102 -28
  217. package/adapters/cursor/references/stage-exit-protocol.md +395 -147
  218. package/adapters/cursor/scripts/epic-manifest.py +495 -91
  219. package/adapters/cursor/scripts/fix-sweep.py +1180 -0
  220. package/adapters/cursor/scripts/forge-bootstrap.py +57 -5
  221. package/adapters/cursor/scripts/forge-session.py +4241 -146
  222. package/adapters/cursor/scripts/validate-traceability.py +86 -5
  223. package/adapters/cursor/skills/forge/forge.mdc +13 -12
  224. package/adapters/cursor/skills/forge/references/pipeline-state-schema.json +38 -4
  225. package/adapters/cursor/skills/forge/references/process-overview.md +2 -2
  226. package/adapters/cursor/skills/forge/references/shared-conventions.md +102 -28
  227. package/adapters/cursor/skills/forge/references/stage-exit-protocol.md +395 -147
  228. package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +7 -2
  229. package/adapters/cursor/skills/forge-0-epic/references/edit-mode.md +37 -33
  230. package/adapters/cursor/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
  231. package/adapters/cursor/skills/forge-0-epic/references/pipeline-state-schema.json +38 -4
  232. package/adapters/cursor/skills/forge-0-epic/references/shared-conventions.md +102 -28
  233. package/adapters/cursor/skills/forge-0-epic/references/stage-exit-protocol.md +395 -147
  234. package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +17 -4
  235. package/adapters/cursor/skills/forge-1-prd/references/shared-conventions.md +102 -28
  236. package/adapters/cursor/skills/forge-1-prd/references/stage-exit-protocol.md +395 -147
  237. package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +18 -4
  238. package/adapters/cursor/skills/forge-2-tech/references/shared-conventions.md +102 -28
  239. package/adapters/cursor/skills/forge-2-tech/references/stage-exit-protocol.md +395 -147
  240. package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +9 -3
  241. package/adapters/cursor/skills/forge-3-specs/references/shared-conventions.md +102 -28
  242. package/adapters/cursor/skills/forge-3-specs/references/spec-archetypes.md +9 -0
  243. package/adapters/cursor/skills/forge-3-specs/references/stage-exit-protocol.md +395 -147
  244. package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +56 -5
  245. package/adapters/cursor/skills/forge-4-backlog/references/shared-conventions.md +102 -28
  246. package/adapters/cursor/skills/forge-4-backlog/references/stage-exit-protocol.md +395 -147
  247. package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +67 -69
  248. package/adapters/cursor/skills/forge-5-loop/references/agent-selection.md +17 -1
  249. package/adapters/cursor/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  250. package/adapters/cursor/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  251. package/adapters/cursor/skills/forge-5-loop/references/result-reporting.md +101 -33
  252. package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +30 -10
  253. package/adapters/cursor/skills/forge-5-loop/references/shared-conventions.md +102 -28
  254. package/adapters/cursor/skills/forge-5-loop/references/stage-exit-protocol.md +395 -147
  255. package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +75 -8
  256. package/adapters/cursor/skills/forge-6-docs/references/shared-conventions.md +102 -28
  257. package/adapters/cursor/skills/forge-6-docs/references/stage-exit-protocol.md +516 -0
  258. package/adapters/cursor/skills/forge-fix/forge-fix.mdc +118 -32
  259. package/adapters/cursor/skills/forge-fix/references/shared-conventions.md +102 -28
  260. package/adapters/cursor/skills/forge-fix/references/stage-exit-protocol.md +395 -147
  261. package/adapters/cursor/skills/forge-guide/forge-guide.mdc +1 -1
  262. package/adapters/cursor/skills/forge-guide/references/forge-config-schema.json +19 -1
  263. package/adapters/cursor/skills/forge-guide/references/process-overview.md +2 -2
  264. package/adapters/cursor/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  265. package/adapters/cursor/skills/forge-guide/references/shared-conventions.md +102 -28
  266. package/adapters/cursor/skills/forge-init/forge-init.mdc +1 -1
  267. package/adapters/cursor/skills/forge-verify/forge-verify.mdc +82 -51
  268. package/adapters/cursor/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  269. package/adapters/cursor/skills/forge-verify/references/findings-template.md +70 -50
  270. package/adapters/cursor/skills/forge-verify/references/shared-conventions.md +102 -28
  271. package/adapters/cursor/skills/forge-verify/references/stage-exit-protocol.md +516 -0
  272. package/adapters/cursor/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  273. package/adapters/cursor/skills/forge-verify/references/verification-checklists/epic.md +5 -4
  274. package/adapters/cursor/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  275. package/adapters/cursor/skills/forge-verify/references/verification-checklists/specs.md +45 -1
  276. package/adapters/gemini/.feature-forge-bundle.json +1 -1
  277. package/adapters/gemini/agents/forge-verifier.md +3 -1
  278. package/adapters/gemini/gemini-extension.json +1 -1
  279. package/adapters/gemini/references/decisions/single-writer-threat-model.md +53 -0
  280. package/adapters/gemini/references/epic-manifest-schema.json +6 -1
  281. package/adapters/gemini/references/epic-state-schema.json +50 -0
  282. package/adapters/gemini/references/forge-config-schema.json +19 -1
  283. package/adapters/gemini/references/forge-decisions-schema.json +33 -0
  284. package/adapters/gemini/references/pipeline-state-schema.json +38 -4
  285. package/adapters/gemini/references/process-overview.md +2 -2
  286. package/adapters/gemini/references/ralph-loop-contract.md +6 -3
  287. package/adapters/gemini/references/shared-conventions.md +102 -28
  288. package/adapters/gemini/references/stage-exit-protocol.md +395 -147
  289. package/adapters/gemini/scripts/epic-manifest.py +495 -91
  290. package/adapters/gemini/scripts/fix-sweep.py +1180 -0
  291. package/adapters/gemini/scripts/forge-bootstrap.py +57 -5
  292. package/adapters/gemini/scripts/forge-session.py +4241 -146
  293. package/adapters/gemini/scripts/validate-traceability.py +86 -5
  294. package/adapters/gemini/skills/forge/forge.md +13 -12
  295. package/adapters/gemini/skills/forge/references/pipeline-state-schema.json +38 -4
  296. package/adapters/gemini/skills/forge/references/process-overview.md +2 -2
  297. package/adapters/gemini/skills/forge/references/shared-conventions.md +102 -28
  298. package/adapters/gemini/skills/forge/references/stage-exit-protocol.md +395 -147
  299. package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +7 -2
  300. package/adapters/gemini/skills/forge-0-epic/references/edit-mode.md +37 -33
  301. package/adapters/gemini/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
  302. package/adapters/gemini/skills/forge-0-epic/references/pipeline-state-schema.json +38 -4
  303. package/adapters/gemini/skills/forge-0-epic/references/shared-conventions.md +102 -28
  304. package/adapters/gemini/skills/forge-0-epic/references/stage-exit-protocol.md +395 -147
  305. package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +17 -4
  306. package/adapters/gemini/skills/forge-1-prd/references/shared-conventions.md +102 -28
  307. package/adapters/gemini/skills/forge-1-prd/references/stage-exit-protocol.md +395 -147
  308. package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +18 -4
  309. package/adapters/gemini/skills/forge-2-tech/references/shared-conventions.md +102 -28
  310. package/adapters/gemini/skills/forge-2-tech/references/stage-exit-protocol.md +395 -147
  311. package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +9 -3
  312. package/adapters/gemini/skills/forge-3-specs/references/shared-conventions.md +102 -28
  313. package/adapters/gemini/skills/forge-3-specs/references/spec-archetypes.md +9 -0
  314. package/adapters/gemini/skills/forge-3-specs/references/stage-exit-protocol.md +395 -147
  315. package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +56 -5
  316. package/adapters/gemini/skills/forge-4-backlog/references/shared-conventions.md +102 -28
  317. package/adapters/gemini/skills/forge-4-backlog/references/stage-exit-protocol.md +395 -147
  318. package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +67 -69
  319. package/adapters/gemini/skills/forge-5-loop/references/agent-selection.md +17 -1
  320. package/adapters/gemini/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  321. package/adapters/gemini/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  322. package/adapters/gemini/skills/forge-5-loop/references/result-reporting.md +101 -33
  323. package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +30 -10
  324. package/adapters/gemini/skills/forge-5-loop/references/shared-conventions.md +102 -28
  325. package/adapters/gemini/skills/forge-5-loop/references/stage-exit-protocol.md +395 -147
  326. package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +75 -8
  327. package/adapters/gemini/skills/forge-6-docs/references/shared-conventions.md +102 -28
  328. package/adapters/gemini/skills/forge-6-docs/references/stage-exit-protocol.md +516 -0
  329. package/adapters/gemini/skills/forge-fix/forge-fix.md +118 -32
  330. package/adapters/gemini/skills/forge-fix/references/shared-conventions.md +102 -28
  331. package/adapters/gemini/skills/forge-fix/references/stage-exit-protocol.md +395 -147
  332. package/adapters/gemini/skills/forge-guide/forge-guide.md +1 -1
  333. package/adapters/gemini/skills/forge-guide/references/forge-config-schema.json +19 -1
  334. package/adapters/gemini/skills/forge-guide/references/process-overview.md +2 -2
  335. package/adapters/gemini/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  336. package/adapters/gemini/skills/forge-guide/references/shared-conventions.md +102 -28
  337. package/adapters/gemini/skills/forge-init/forge-init.md +1 -1
  338. package/adapters/gemini/skills/forge-verify/forge-verify.md +82 -51
  339. package/adapters/gemini/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  340. package/adapters/gemini/skills/forge-verify/references/findings-template.md +70 -50
  341. package/adapters/gemini/skills/forge-verify/references/shared-conventions.md +102 -28
  342. package/adapters/gemini/skills/forge-verify/references/stage-exit-protocol.md +516 -0
  343. package/adapters/gemini/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  344. package/adapters/gemini/skills/forge-verify/references/verification-checklists/epic.md +5 -4
  345. package/adapters/gemini/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  346. package/adapters/gemini/skills/forge-verify/references/verification-checklists/specs.md +45 -1
  347. package/adapters/pi/.feature-forge-bundle.json +1 -1
  348. package/adapters/pi/agents/forge-verifier.md +3 -1
  349. package/adapters/pi/references/decisions/single-writer-threat-model.md +53 -0
  350. package/adapters/pi/references/epic-manifest-schema.json +6 -1
  351. package/adapters/pi/references/epic-state-schema.json +50 -0
  352. package/adapters/pi/references/forge-config-schema.json +19 -1
  353. package/adapters/pi/references/forge-decisions-schema.json +33 -0
  354. package/adapters/pi/references/pipeline-state-schema.json +38 -4
  355. package/adapters/pi/references/process-overview.md +2 -2
  356. package/adapters/pi/references/ralph-loop-contract.md +6 -3
  357. package/adapters/pi/references/shared-conventions.md +91 -17
  358. package/adapters/pi/references/stage-exit-protocol.md +395 -147
  359. package/adapters/pi/scripts/epic-manifest.py +495 -91
  360. package/adapters/pi/scripts/fix-sweep.py +1180 -0
  361. package/adapters/pi/scripts/forge-bootstrap.py +57 -5
  362. package/adapters/pi/scripts/forge-session.py +4241 -146
  363. package/adapters/pi/scripts/validate-traceability.py +86 -5
  364. package/adapters/pi/skills/forge/SKILL.md +10 -9
  365. package/adapters/pi/skills/forge/references/pipeline-state-schema.json +38 -4
  366. package/adapters/pi/skills/forge/references/process-overview.md +2 -2
  367. package/adapters/pi/skills/forge/references/shared-conventions.md +91 -17
  368. package/adapters/pi/skills/forge/references/stage-exit-protocol.md +395 -147
  369. package/adapters/pi/skills/forge-0-epic/SKILL.md +7 -2
  370. package/adapters/pi/skills/forge-0-epic/references/edit-mode.md +31 -27
  371. package/adapters/pi/skills/forge-0-epic/references/epic-manifest-subcommands.md +6 -1
  372. package/adapters/pi/skills/forge-0-epic/references/pipeline-state-schema.json +38 -4
  373. package/adapters/pi/skills/forge-0-epic/references/shared-conventions.md +91 -17
  374. package/adapters/pi/skills/forge-0-epic/references/stage-exit-protocol.md +395 -147
  375. package/adapters/pi/skills/forge-1-prd/SKILL.md +17 -4
  376. package/adapters/pi/skills/forge-1-prd/references/shared-conventions.md +91 -17
  377. package/adapters/pi/skills/forge-1-prd/references/stage-exit-protocol.md +395 -147
  378. package/adapters/pi/skills/forge-2-tech/SKILL.md +18 -4
  379. package/adapters/pi/skills/forge-2-tech/references/shared-conventions.md +91 -17
  380. package/adapters/pi/skills/forge-2-tech/references/stage-exit-protocol.md +395 -147
  381. package/adapters/pi/skills/forge-3-specs/SKILL.md +9 -3
  382. package/adapters/pi/skills/forge-3-specs/references/shared-conventions.md +91 -17
  383. package/adapters/pi/skills/forge-3-specs/references/spec-archetypes.md +9 -0
  384. package/adapters/pi/skills/forge-3-specs/references/stage-exit-protocol.md +395 -147
  385. package/adapters/pi/skills/forge-4-backlog/SKILL.md +56 -5
  386. package/adapters/pi/skills/forge-4-backlog/references/shared-conventions.md +91 -17
  387. package/adapters/pi/skills/forge-4-backlog/references/stage-exit-protocol.md +395 -147
  388. package/adapters/pi/skills/forge-5-loop/SKILL.md +67 -69
  389. package/adapters/pi/skills/forge-5-loop/references/agent-selection.md +16 -0
  390. package/adapters/pi/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
  391. package/adapters/pi/skills/forge-5-loop/references/recovery-procedure.md +349 -0
  392. package/adapters/pi/skills/forge-5-loop/references/result-reporting.md +101 -33
  393. package/adapters/pi/skills/forge-5-loop/references/runner-contract.md +29 -9
  394. package/adapters/pi/skills/forge-5-loop/references/shared-conventions.md +91 -17
  395. package/adapters/pi/skills/forge-5-loop/references/stage-exit-protocol.md +395 -147
  396. package/adapters/pi/skills/forge-6-docs/SKILL.md +75 -8
  397. package/adapters/pi/skills/forge-6-docs/references/shared-conventions.md +91 -17
  398. package/adapters/pi/skills/forge-6-docs/references/stage-exit-protocol.md +516 -0
  399. package/adapters/pi/skills/forge-fix/SKILL.md +118 -32
  400. package/adapters/pi/skills/forge-fix/references/shared-conventions.md +91 -17
  401. package/adapters/pi/skills/forge-fix/references/stage-exit-protocol.md +395 -147
  402. package/adapters/pi/skills/forge-guide/references/forge-config-schema.json +19 -1
  403. package/adapters/pi/skills/forge-guide/references/process-overview.md +2 -2
  404. package/adapters/pi/skills/forge-guide/references/ralph-loop-contract.md +6 -3
  405. package/adapters/pi/skills/forge-guide/references/shared-conventions.md +91 -17
  406. package/adapters/pi/skills/forge-verify/SKILL.md +81 -50
  407. package/adapters/pi/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
  408. package/adapters/pi/skills/forge-verify/references/findings-template.md +69 -49
  409. package/adapters/pi/skills/forge-verify/references/shared-conventions.md +91 -17
  410. package/adapters/pi/skills/forge-verify/references/stage-exit-protocol.md +516 -0
  411. package/adapters/pi/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
  412. package/adapters/pi/skills/forge-verify/references/verification-checklists/epic.md +5 -4
  413. package/adapters/pi/skills/forge-verify/references/verification-checklists/impl.md +85 -0
  414. package/adapters/pi/skills/forge-verify/references/verification-checklists/specs.md +45 -1
  415. package/package.json +1 -1
  416. package/adapters/claude/skills/forge-verify/references/pipeline-state-schema.json +0 -191
  417. package/adapters/codex/skills/forge-verify/references/pipeline-state-schema.json +0 -191
  418. package/adapters/copilot/skills/forge-verify/references/pipeline-state-schema.json +0 -191
  419. package/adapters/cursor/skills/forge-verify/references/pipeline-state-schema.json +0 -191
  420. package/adapters/gemini/skills/forge-verify/references/pipeline-state-schema.json +0 -191
  421. package/adapters/pi/skills/forge-verify/references/pipeline-state-schema.json +0 -191
@@ -20,6 +20,28 @@ Resolve the feature directory via the **Feature Directory Resolution** block in
20
20
 
21
21
  Read `{resolvedFeatureDir}/.pipeline-state.json` to understand what exists.
22
22
 
23
+ ### Documentation Decision Gate
24
+
25
+ Documentation is valuable but not mandatory: a feature may close with docs deliberately skipped, recorded honestly as `skipped` (never as a false `complete`). This gate is configured by `docsStage` in `forge.config.json` (`"prompt"` | `"skip"`, default `"prompt"`; an unrecognized or absent value behaves as `"prompt"`):
26
+
27
+ - **`"prompt"`** — before gathering sources, use the host's question mechanism to ask: **Generate docs (recommended)** — proceed with this skill as written · **Skip documentation for this feature** — close the stage with no docs, recorded as `skipped`; docs can still be generated later by re-running this stage.
28
+ - **`"skip"`** — take the skip path below directly, with no question: say one line — "docsStage is configured to skip: recording forge-6-docs as deliberately skipped for {feature}." — and proceed to the `state-skip` write. The user opted out of the per-run prompt by setting the config; re-asking would defeat it.
29
+
30
+ On **Skip documentation**, persist the skip through the `state-skip` verb — never by hand, and never via `state-complete` (which would claim a completion that did not happen). Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol in `references/shared-conventions.md`:
31
+
32
+ ```bash
33
+ 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')"
34
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
35
+ python3 "$R/scripts/forge-session.py" state-skip \
36
+ --feature "{feature}" --stage forge-6-docs --specs-dir "{specsDir}"
37
+ ```
38
+
39
+ If the verb exits 2, surface its plain `Error:` line verbatim — a refusal means the skip would erase a record of docs that already exist; do not force it. Ask the user how to proceed (typically: generate/refresh the docs normally).
40
+
41
+ After a successful skip write: if `gitCommitAfterStage` is true, commit the state change (`git add {resolvedFeatureDir}/`, message `"{commitPrefix}({feature}): skip architecture docs"`) — a plain single commit; there is no artifact commit, so the two-commit hash follow-up does not apply. Then go **directly to Step 6** with `{DocsOutcome}` = `skipped`. Steps 1 (rest), 2, 3, 4, and 5 are all skipped — including the Impl-Verify Backstop: skipping docs generates nothing over unverified code, and any outstanding verification stays visible in state and keeps being surfaced by the navigator.
42
+
43
+ On **Generate docs**, continue below.
44
+
23
45
  ### Gather Sources
24
46
 
25
47
  Load into context:
@@ -36,7 +58,28 @@ Also check `.pipeline-state.json` for `stages.forge-5-loop`. If it exists and ha
36
58
 
37
59
  ### Impl-Verify Backstop
38
60
 
39
- Check `.pipeline-state.json` for `stages.forge-verify-impl`. If it is **absent** or has status `"skipped"`, use the host's question mechanism to warn with the cost of skipping: "Implementation hasn't been verified yet. Recommended: run `/feature-forge:forge-verify {feature} impl` first to audit the loop's output — docs generated over unverified code can document bugs or gaps as if they were intended behavior, and readers will trust them. Generate docs anyway?" Offer **Verify first (recommended)** · **Generate docs anyway**. This mirrors `forge-4-backlog`'s pre-stage verification check and backstops a skipped impl-verify regardless of how the loop ended. If `stages.forge-verify-impl` shows it already ran (`findings-applied`, `findings-reported`, or `passed`), proceed with no warning.
61
+ Read `stages.forge-verify-impl` from `.pipeline-state.json` and branch on its status — **five** cases, in this order (the pending case must be tested *before* the absent/`skipped` one, or owed-and-dropped debt gets reported as never-scheduled):
62
+
63
+ 1. **`passed`** — verification ran and resolved clean (or advisory-only, report attached); proceed with no warning.
64
+ 2. **`findings-reported`** — blocking findings are live and **unresolved**: docs generated over them can document known defects as intended behavior. Use the host's question mechanism to offer: **Apply the findings first (recommended)** (`/feature-forge:forge-fix {feature} --served-stage forge-5-loop`) · **Generate docs anyway**. Proceeding is an explicit deferral, persisted per the skip rule below — the findings documents stay on disk and the deferral is a recorded decision.
65
+ 3. **`findings-applied`** — fixes landed but nothing re-verified them: this status deliberately clears freshness, so the implementation's verification is still outstanding, not silently satisfied. Use the host's question mechanism to offer: **Re-verify first (recommended)** (`/feature-forge:forge-verify {feature} impl`) · **Generate docs anyway**. On proceed, **write nothing to the verify entry** — the skip rule below does NOT apply to this case. `findings-applied` counts as complete-for-orchestration, so replacing it with `skipped` would demote the member out of its epic rollup and re-block dependents (`state-verify` refuses exactly that write — issue #203's 5/6 → 1/6 collapse). The recorded status already says re-verification is outstanding; proceeding is the deferral, and later gates keep surfacing it.
66
+ 4. **`auto-verify-pending`** — automatic verification *was* scheduled for the implementation stage and the debt *was* durably recorded; it simply has not run. Say exactly that, naming the served stage and the retry command: *"{feature}: automatic verification is still pending for forge-5-loop; run `/feature-forge:forge-verify {feature} impl` to resolve it."* Then use the host's question mechanism to offer the same two choices as case 5. Never report this as "hasn't been verified yet" — an **absent** entry means verification was never scheduled, `auto-verify-pending` means it was scheduled and never ran, and the operator acts on those two facts differently.
67
+ 5. **Absent, or `skipped`** — use the host's question mechanism to warn with the cost of skipping: "Implementation hasn't been verified yet. Recommended: run `/feature-forge:forge-verify {feature} impl` first to audit the loop's output — docs generated over unverified code can document bugs or gaps as if they were intended behavior, and readers will trust them. Generate docs anyway?"
68
+
69
+ Cases 2–5 all pair a recommended first action with **Generate docs anyway**. On **Verify first** / **Re-verify first**, invoke `feature-forge:forge-verify {feature} impl` with the literal `owner: nested` token in the dispatching prompt — this dispatch happens inside the docs stage, so **you** remain the sole terminal owner and the branch skill returns its structured result and prints no terminal block of its own (see "Branch ownership: the `owner:` token" in `references/stage-exit-protocol.md`); on **Apply the findings first**, dispatch `feature-forge:forge-fix` the same way (same token, same ownership). This mirrors `forge-4-backlog`'s pre-stage verification check and backstops a skipped or unresolved impl-verify regardless of how the loop ended.
70
+
71
+ **"Generate docs anyway" persists the skip before docs can complete — in cases 2, 4, and 5 only.** An explicit choice to proceed without verification is recorded as `skipped` through `state-verify` — never by hand — **before** Step 2, so an unresolved result cannot be bypassed by this stage's terminal wording. Case 3 (`findings-applied`) is the exception spelled out above: its deferral writes nothing, because the verb refuses to demote a complete-for-orchestration status (#203). Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol in `references/shared-conventions.md`:
72
+
73
+ ```bash
74
+ 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')"
75
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
76
+ python3 "$R/scripts/forge-session.py" state-verify \
77
+ --feature "{feature}" --stage forge-5-loop --status skipped --specs-dir "{specsDir}"
78
+ ```
79
+
80
+ If that verb exits 2, surface its plain `Error:` line verbatim and stop — the skip is not persisted, so docs may not complete.
81
+
82
+ **Verification that is operationally unavailable is not an implicit skip.** If the user chose **Verify first** and the clean-room verifier could not be dispatched, returned `CLEAN_ROOM_UNAVAILABLE`, or returned a non-answer, then verification did **not** run: write nothing, follow the *Clean-room unavailable, or a non-answer* path in `references/stage-exit-protocol.md` (leave the debt unresolved and print the verify command for the user to run), and never read the failed attempt as consent to proceed. Docs may complete only after verification passes or after the user makes the explicit "Generate docs anyway" choice above, which persists `skipped` — an unavailable tool is neither.
40
83
 
41
84
  ### Epic-Level Documentation (epic members only)
42
85
 
@@ -50,13 +93,13 @@ python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specs
50
93
 
51
94
  If `render-status` fails, skip the epic-level offer and proceed with the per-feature docs only; surface the error per the exit-1/exit-2 split in the **Feature Directory Resolution** block of `references/shared-conventions.md` (exit 1 → parse `{findings[]}` from stdout; exit 2 → surface the plain `Error:` stderr line verbatim).
52
95
 
53
- **Only if `rollup.total > 0 AND rollup.complete == rollup.total`** (every member is complete-for-orchestration; the `total > 0` guard excludes an empty epic), offer the extra doc as a statement the user can take or leave — not a forced question:
96
+ **Gate the offer on per-member DOCS state, not the orchestration rollup (#173).** `rollup.complete` counts loop-completeness, so in an epic implemented before any docs were written it reads full on the *first* member's docs run — offering an epic doc that would be sourced from a fraction of its inputs. Instead, read each member row's `docsStatus` from the same `render-status` payload and offer **only if**: `rollup.total > 0`, AND every member **other than {feature}** has `docsStatus` of `complete` or `skipped` (#197's deliberate skip satisfies — those members will contribute no per-feature docs by decision, not by omission). The current member counts as satisfied by this in-flight run. This fires exactly once per epic, on its final docs run:
54
97
 
55
- "All {total} features in the '{epic}' epic are complete. I can also generate an **epic-level architecture document** spanning the features, alongside {feature}'s per-feature docs — say the word and I'll add it."
98
+ "All {total} features in the '{epic}' epic now have their documentation settled. I can also generate an **epic-level architecture document** spanning the features, alongside {feature}'s per-feature docs — say the word and I'll add it."
56
99
 
57
- If the user asks for it, synthesize a doc at **`{docsDir}/{epic}/`** sourced from: the `EPIC.md` narrative, each member's per-feature docs, and the manifest contracts (each feature's `exposes`/`consumes`). When the epic-level doc is written, the Step 5 commit also stages `{docsDir}/{epic}/`.
100
+ If the user asks for it, synthesize a doc at **`{docsDir}/{epic}/`** sourced from: the `EPIC.md` narrative, each member's per-feature docs (members whose docs were deliberately skipped contribute their manifest charter/contracts only), and the manifest contracts (each feature's `exposes`/`consumes`). When the epic-level doc is written, the Step 5 commit also stages `{docsDir}/{epic}/`.
58
101
 
59
- If not all members are complete (or the feature has no `epic` back-pointer), **do not offer** — the per-feature doc flow proceeds unchanged.
102
+ If any other member's `docsStatus` is neither `complete` nor `skipped` (or the feature has no `epic` back-pointer), **do not offer** — the per-feature doc flow proceeds unchanged.
60
103
 
61
104
  Read `references/doc-conventions.md` for documentation standards.
62
105
 
@@ -182,10 +225,34 @@ python3 "$R/scripts/forge-session.py" state-complete \
182
225
 
183
226
  1. Record completion by running the `state-complete` call above with `--version`, one `--artifact` per doc file this stage produced, and one `--based-on STAGE=<version>` per completed upstream stage. Always include forge-1-prd, forge-2-tech, forge-3-specs. Include forge-4-backlog and forge-5-loop ONLY if they have status `complete`. The verb sets `status: "complete"`, `completedAt`, the version, `basedOnVersions` and `artifacts`, and refreshes `updatedAt`.
184
227
  2. If `gitCommitAfterStage` is true, follow the Git Commit Protocol in `references/shared-conventions.md`: stage files (`git add {docsDir}/{feature}/ {resolvedFeatureDir}/` — and **also** `{docsDir}/{epic}/` when an epic-level doc was written in Step 1), attempt commit with message `"{commitPrefix}({feature}): complete architecture docs"` (marking `stages.forge-6-docs.status` `complete` with `commitHash: null` in that commit), then record the artifact-commit hash via the protocol's two-commit follow-up (never `--amend`) only on success. If commit fails, leave status as `in-progress`.
185
- 4. Tell user: "Documentation complete. Feature pipeline for '{feature}' is finished!\n `/feature-forge:forge {feature}` to see the final pipeline status." Then **hand off to the next unit of work** — do not dead-end here (Issue #124):
228
+ 3. Say that the docs are written — "Documentation complete for '{feature}'." — and stop there. The hand-off is Step 6's, and it is the script's to decide.
229
+
230
+ ## Step 6: Close the Stage
231
+
232
+ Every docs run ends here, and ends here **exactly once** — standalone or epic member, complete or not.
233
+
234
+ Select `{DocsOutcome}` first, from what actually landed:
235
+
236
+ - **`complete`** — the docs were written and Step 5's state (and commit, when `gitCommitAfterStage` is true) succeeded.
237
+ - **`skipped`** — the user chose **Skip documentation** at the Documentation Decision Gate and the `state-skip` write succeeded. Routes exactly like `complete` (the pipeline still ends here), but the wording says the docs were deliberately skipped — never that they exist.
238
+ - **`blocked`** — docs work could not complete. Persist only valid partial state, then run the same call with `blocked`; it routes to navigator/recovery and never claims the pipeline is finished. If the failure happened **before** a safe state write, report the failure and its recovery and run **no** exit at all — there is nothing durable for an exit to close over.
239
+
240
+ **Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
241
+
242
+ ```bash
243
+ 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')"
244
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
245
+ python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-6-docs --outcome "{DocsOutcome}" --specs-dir "{specsDir}" --host generic --verify-capability "{verify-capability}"
246
+ ```
247
+
248
+ Obey the DIRECTIVES it prints, in the consumption order this protocol fixes: surface `invalidAutoVerifyKeys` and every `warnings` entry first; `runInStageVerify: true` → run the in-stage clean-room verify chain now (honoring `autoFixEligible`, and asking through the Standard Verify Gate first when you may not dispatch unsolicited); `verifyGate: "standard"` → present the Standard Verify Gate; `verifyGate: "manual-print"` → print the `verifyCommand` for the user and do **not** dispatch inline. Then, and only when `terminalOwnedBy` is `"self"`, **print the NEXT-STEPS block verbatim as your absolute last output — nothing after its sentinel line.** A `terminalOwnedBy: "outer"` payload carries `nextSteps: null`: return your structured result to the caller and print no terminal block at all.
249
+
250
+ Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol in `references/shared-conventions.md`. Determine `{verify-capability}` per the **Host and capability determination** section of `references/stage-exit-protocol.md`: `interactive` needs both a question mechanism and *permission* to dispatch the clean-room `forge-verifier`, and a session that merely needs consent first is still `interactive`.
251
+
252
+ The script owns the routing for both outcomes, so append nothing to its block — no hand-off paragraph, no "start a new feature" list, no second command:
186
253
 
187
- - **Epic member** (the resolved feature has an `epic` back-pointer in its `.pipeline-state.json`): reuse the `render-status "{epic}" --specs-dir "{specsDir}" --json` output from Step 1's Epic-Level Documentation block (re-run it if you skipped that block). If `actionable` is non-empty, point at the next member: "Epic '{epic}' has {total−complete} feature(s) left — next up: **{actionable[0].name}**. Start it with `{actionable[0].nextCommand}`." (Offer to start it now if the host can invoke it — honor `autoInvokeNextStage` + `Skill`-tool availability; else just print the command.) If `actionable` is empty but the epic is not fully complete, note the remaining members are blocked on dependencies. If the epic is fully complete (`rollup.complete == rollup.total`, `total > 0`), congratulate on the whole epic — the epic-level architecture doc was already offered in Step 1 — and point at `/feature-forge:forge {epic}` for the finished dashboard.
188
- - **Standalone** (no `epic` back-pointer): offer the next feature — "Start a new feature: `/feature-forge:forge-1-prd <feature-name>` (or group several with `/feature-forge:forge-0-epic <epic-name>`). Run `/feature-forge:forge` to see any other active pipelines." Defer the full recency-ranked list of other pipelines to the navigator (`/feature-forge:forge`) rather than duplicating it here.
254
+ - **Epic member** — the script reads live epic status **at exit time**, after this stage's own state write and commit. Do **not** reuse Step 1's `render-status` snapshot and do **not** pass a member you picked yourself: that snapshot predates the docs state it would be routing from. An actionable member gets its own live command fenced; nothing actionable routes to the epic dashboard; every member complete routes to the dashboard completion view.
255
+ - **Standalone** — `complete` fences `/feature-forge:forge {feature}` as the authoritative completion action, and leaves starting a new feature (or grouping several with `/feature-forge:forge-0-epic`) as secondary unfenced text.
189
256
 
190
257
  ## Gotchas
191
258
 
@@ -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,6 +202,44 @@ 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
 
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.
206
+
207
+ ### `state-verify` — verification results and provenance
208
+
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
210
+
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*.
212
+
213
+ ```bash
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')"
215
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
216
+ python3 "$R/scripts/forge-session.py" state-verify \
217
+ --feature "{feature}" --stage "{served-production-stage}" --status "<status>" \
218
+ --specs-dir "{specsDir}"
219
+ ```
220
+
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:
222
+
223
+ ```bash
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')"
225
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
226
+ python3 "$R/scripts/forge-session.py" state-verify \
227
+ --feature "{feature}" --stage "{served-production-stage}" \
228
+ --commit-hash "$(git rev-parse HEAD)" --specs-dir "{specsDir}"
229
+ ```
230
+
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:
232
+
233
+ ```bash
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')"
235
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
236
+ python3 "$R/scripts/forge-session.py" state-verify \
237
+ --feature "{epic}" --stage forge-0-epic --status "<status>" \
238
+ --specs-dir "{specsDir}"
239
+ ```
240
+
241
+ On exit 2 the verification result is **not** recorded: surface the `Error:` line verbatim, name the feature (and epic), and do not claim the verification was persisted or advance past it.
242
+
194
243
  ### Staleness Detection (Read-Time)
195
244
 
196
245
  When loading upstream artifacts as prerequisites, check `basedOnVersions` in the pipeline state for this stage. If any upstream stage's current version is newer than the version recorded in `basedOnVersions`, warn the user before proceeding:
@@ -199,6 +248,31 @@ When loading upstream artifacts as prerequisites, check `basedOnVersions` in the
199
248
 
200
249
  Frame the choice with its cost: re-running re-derives this stage from the current upstream (safest, but discards any hand-edits to this stage's artifacts); proceeding stale is faster but risks baking outdated assumptions into everything downstream. Recommend re-running unless the user knows the upstream change doesn't affect this stage.
201
250
 
251
+ ## Immediate Downstream Note (Parking Lot)
252
+
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.
254
+
255
+ ```bash
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')"
257
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
258
+ python3 "$R/scripts/forge-session.py" state-note \
259
+ --feature "{feature}" --note "<concise downstream concern>" \
260
+ --specs-dir "{specsDir}"
261
+ ```
262
+
263
+ `state-note` **overwrites** the single top-level `notes` string — it does not append. To preserve an earlier note, read the current `notes` value out of the feature's `.pipeline-state.json` first and pass one combined concise string in a single `--note`; never edit or round-trip the JSON by hand. This interview-time call is separate from the optional completion note offered at stage closure and must not be deferred until then — a session that ends before closure would otherwise lose the concern entirely.
264
+
265
+ On `UsageError`/exit 2, surface the `Error:` line verbatim together with the named feature (and epic) and the recovery instruction, and **stop claiming the concern was recorded** — it was not. Epic *decomposition* changes are not notes: they go through `state-ecr` into `epicChangeRequests`, never into `notes`.
266
+
267
+ ## Verify Capability
268
+
269
+ Skills that close a stage pass `--verify-capability interactive|manual` to `stage-exit`. The full determination rule, the Standard Verify Gate, and the recovery path live in `references/stage-exit-protocol.md`; the two facts that are most often gotten wrong:
270
+
271
+ - **Dispatch capability is *permitted* dispatch, not a listed tool.** The question is "**may I dispatch `forge-verifier` right now**", not "is a subagent-dispatch tool in my tool surface". A session can carry a standing host instruction against dispatching subagents unless the user asked; such instructions are injected by the harness, sit outside this project's control, and outrank skill prose. Classify on permission, up front.
272
+ - **A consent requirement is `interactive`, not `manual`.** When dispatch is barred only *unless the user asked* and a question mechanism is available, pass `interactive`: the gate's own affirmative choice supplies the missing user request. Pass `manual` only when there is **no** question mechanism **and** **no** permitted dispatch.
273
+
274
+ A bar on unsolicited dispatch is never grounds to skip verification, and never grounds to fence the production successor while verification is unresolved. On the `runInStageVerify: true` path the emitted `verifyGate` stays `none`: reuse the Standard Verify Gate block for consent with **choice 2 omitted** (auto-verify is already effective, so "enable auto-verify going forward" is a no-op), leaving exactly two choices: *Verify now* (recommended) and *Skip for now*. The clean-room `forge-verifier` is **dispatched on the affirmative choice**, never merely printed for the user to run later; *Skip for now* is persisted as an explicit `skipped` before any advancing block.
275
+
202
276
  ## Branch Setup
203
277
 
204
278
  Invoke this block at the **very start** of a pipeline entry point — `forge-1-prd` (standalone feature) and `forge-0-epic` (epic) — **before** any directory resolution or interview, so the rest of the run lands on the intended branch. `{label}` is the feature name (forge-1-prd) or epic name (forge-0-epic); `{scope}` is `feature` or `epic` correspondingly.
@@ -212,7 +286,7 @@ Invoke this block at the **very start** of a pipeline entry point — `forge-1-p
212
286
  1. Read the current branch: `git rev-parse --abbrev-ref HEAD`.
213
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.
214
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.
215
- 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):
216
290
 
217
291
  > "You're on `{defaultBranch}`. Strongly recommended: create `{branchPrefix}{label}` so this {scope}'s work stays isolated and reviewable as one branch. Create it?"
218
292
  > Options: **Create `{branchPrefix}{label}` (recommended)** · **Stay on `{defaultBranch}`**
@@ -223,7 +297,7 @@ Invoke this block at the **very start** of a pipeline entry point — `forge-1-p
223
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.
224
298
 
225
299
  ```bash
226
- 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')"
227
301
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
228
302
  python3 "$R/scripts/forge-session.py" state-branch \
229
303
  --feature "{feature}" --branch "<name>" --specs-dir "{specsDir}"
@@ -236,20 +310,20 @@ Downstream stages and `forge-5-loop` read it to detect drift back onto the defau
236
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.
237
311
 
238
312
  ```bash
239
- 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')"
240
314
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
241
315
  python3 "$R/scripts/forge-session.py" reconcile-branch --feature "{feature}" --specs-dir "{specsDir}" --json
242
316
  ```
243
317
 
244
318
  Act on the emitted `action` (source of truth is where the state actually resolves, not the recorded field):
245
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).
246
- - **`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.
247
321
  - **`none`** / **`not-resolved`** — nothing to do; proceed.
248
322
 
249
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:
250
324
 
251
325
  ```bash
252
- 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')"
253
327
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
254
328
  python3 "$R/scripts/forge-session.py" state-branch \
255
329
  --feature "{feature}" --branch "{newBranch}" --specs-dir "{specsDir}"
@@ -275,7 +349,7 @@ When `gitCommitAfterStage` is true, follow this exact order to avoid state incon
275
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:
276
350
 
277
351
  ```bash
278
- 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')"
279
353
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
280
354
  # Commit 1 — before `git commit`
281
355
  python3 "$R/scripts/forge-session.py" state-complete \
@@ -297,15 +371,15 @@ Invoke this block at the **start of an authoring stage** (`forge-1-prd`..`forge-
297
371
 
298
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:
299
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).
300
- - **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).
301
375
  - Skip artifact regeneration for files that already exist and are complete (non-empty, properly structured); continue from the next unwritten artifact.
302
376
 
303
- 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).
304
378
 
305
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:
306
380
 
307
381
  ```bash
308
- 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')"
309
383
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
310
384
  python3 "$R/scripts/forge-session.py" state-enter \
311
385
  --feature "{feature}" --stage "{stage}" --specs-dir "{specsDir}"
@@ -318,7 +392,7 @@ This write is **left uncommitted**: it is staged and committed as part of this s
318
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.
319
393
 
320
394
  ```bash
321
- 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')"
322
396
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
323
397
  python3 "$R/scripts/forge-session.py" state-artifact \
324
398
  --feature "{feature}" --stage "{stage}" --path "<file>" --specs-dir "{specsDir}"
@@ -332,7 +406,7 @@ Invoke this block **at the head of any post-entry step that writes a stage artif
332
406
 
333
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.
334
408
 
335
- 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.
336
410
 
337
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).
338
412