@garygentry/feature-forge 0.2.12 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/adapters/GENERATION-REPORT.md +1 -0
  2. package/adapters/claude/.feature-forge-bundle.json +1 -1
  3. package/adapters/claude/references/forge-config-schema.json +5 -0
  4. package/adapters/claude/scripts/epic-manifest.py +209 -0
  5. package/adapters/claude/scripts/forge-bootstrap.py +1 -0
  6. package/adapters/claude/scripts/forge-init.sh +2 -0
  7. package/adapters/claude/skills/forge/SKILL.md +9 -1
  8. package/adapters/claude/skills/forge/references/pipeline-state-schema.json +191 -0
  9. package/adapters/claude/skills/forge/references/process-overview.md +143 -0
  10. package/adapters/claude/skills/forge/references/shared-conventions.md +283 -0
  11. package/adapters/claude/skills/forge/references/stage-exit-protocol.md +258 -0
  12. package/adapters/claude/skills/forge-0-epic/references/epic-manifest-subcommands.md +11 -0
  13. package/adapters/claude/skills/forge-0-epic/references/pipeline-state-schema.json +191 -0
  14. package/adapters/claude/skills/forge-0-epic/references/portable-root.md +71 -0
  15. package/adapters/claude/skills/forge-0-epic/references/shared-conventions.md +283 -0
  16. package/adapters/claude/skills/forge-0-epic/references/stage-exit-protocol.md +258 -0
  17. package/adapters/claude/skills/forge-1-prd/references/pipeline-state-schema.json +191 -0
  18. package/adapters/claude/skills/forge-1-prd/references/shared-conventions.md +283 -0
  19. package/adapters/claude/skills/forge-1-prd/references/stage-exit-protocol.md +258 -0
  20. package/adapters/claude/skills/forge-2-tech/SKILL.md +1 -1
  21. package/adapters/claude/skills/forge-2-tech/references/pipeline-state-schema.json +191 -0
  22. package/adapters/claude/skills/forge-2-tech/references/shared-conventions.md +283 -0
  23. package/adapters/claude/skills/forge-2-tech/references/stack-resolution.md +54 -0
  24. package/adapters/claude/skills/forge-2-tech/references/stacks/_generic.md +90 -0
  25. package/adapters/claude/skills/forge-2-tech/references/stacks/go.md +138 -0
  26. package/adapters/claude/skills/forge-2-tech/references/stacks/python.md +163 -0
  27. package/adapters/claude/skills/forge-2-tech/references/stacks/rust.md +151 -0
  28. package/adapters/claude/skills/forge-2-tech/references/stacks/typescript.md +111 -0
  29. package/adapters/claude/skills/forge-2-tech/references/stage-exit-protocol.md +258 -0
  30. package/adapters/claude/skills/forge-3-specs/references/pipeline-state-schema.json +191 -0
  31. package/adapters/claude/skills/forge-3-specs/references/shared-conventions.md +283 -0
  32. package/adapters/claude/skills/forge-3-specs/references/stacks/_generic.md +90 -0
  33. package/adapters/claude/skills/forge-3-specs/references/stacks/go.md +138 -0
  34. package/adapters/claude/skills/forge-3-specs/references/stacks/python.md +163 -0
  35. package/adapters/claude/skills/forge-3-specs/references/stacks/rust.md +151 -0
  36. package/adapters/claude/skills/forge-3-specs/references/stacks/typescript.md +111 -0
  37. package/adapters/claude/skills/forge-3-specs/references/stage-exit-protocol.md +258 -0
  38. package/adapters/claude/skills/forge-4-backlog/references/forge-config-schema.json +236 -0
  39. package/adapters/claude/skills/forge-4-backlog/references/pipeline-state-schema.json +191 -0
  40. package/adapters/claude/skills/forge-4-backlog/references/shared-conventions.md +283 -0
  41. package/adapters/claude/skills/forge-4-backlog/references/stage-exit-protocol.md +258 -0
  42. package/adapters/claude/skills/forge-5-loop/references/forge-config-schema.json +236 -0
  43. package/adapters/claude/skills/forge-5-loop/references/ralph-loop-contract.md +221 -0
  44. package/adapters/claude/skills/forge-5-loop/references/shared-conventions.md +283 -0
  45. package/adapters/claude/skills/forge-5-loop/references/stage-exit-protocol.md +258 -0
  46. package/adapters/claude/skills/forge-6-docs/SKILL.md +4 -1
  47. package/adapters/claude/skills/forge-6-docs/references/pipeline-state-schema.json +191 -0
  48. package/adapters/claude/skills/forge-6-docs/references/shared-conventions.md +283 -0
  49. package/adapters/claude/skills/forge-fix/references/shared-conventions.md +283 -0
  50. package/adapters/claude/skills/forge-fix/references/stage-exit-protocol.md +258 -0
  51. package/adapters/claude/skills/forge-guide/references/forge-config-schema.json +236 -0
  52. package/adapters/claude/skills/forge-guide/references/process-overview.md +143 -0
  53. package/adapters/claude/skills/forge-guide/references/ralph-loop-contract.md +221 -0
  54. package/adapters/claude/skills/forge-guide/references/shared-conventions.md +283 -0
  55. package/adapters/claude/skills/forge-guide/references/stack-resolution.md +54 -0
  56. package/adapters/claude/skills/forge-guide/references/stacks/_generic.md +90 -0
  57. package/adapters/claude/skills/forge-guide/references/stacks/go.md +138 -0
  58. package/adapters/claude/skills/forge-guide/references/stacks/python.md +163 -0
  59. package/adapters/claude/skills/forge-guide/references/stacks/rust.md +151 -0
  60. package/adapters/claude/skills/forge-guide/references/stacks/typescript.md +111 -0
  61. package/adapters/claude/skills/forge-init/SKILL.md +1 -0
  62. package/adapters/claude/skills/forge-verify/SKILL.md +4 -3
  63. package/adapters/claude/skills/forge-verify/references/pipeline-state-schema.json +191 -0
  64. package/adapters/claude/skills/forge-verify/references/shared-conventions.md +283 -0
  65. package/adapters/claude/skills/forge-verify/references/verification-checklists.md +7 -0
  66. package/adapters/codex/.feature-forge-bundle.json +1 -1
  67. package/adapters/codex/references/forge-config-schema.json +5 -0
  68. package/adapters/codex/scripts/epic-manifest.py +209 -0
  69. package/adapters/codex/scripts/forge-bootstrap.py +1 -0
  70. package/adapters/codex/scripts/forge-init.sh +2 -0
  71. package/adapters/codex/skills/forge/SKILL.md +9 -1
  72. package/adapters/codex/skills/forge/references/pipeline-state-schema.json +191 -0
  73. package/adapters/codex/skills/forge/references/process-overview.md +143 -0
  74. package/adapters/codex/skills/forge/references/shared-conventions.md +283 -0
  75. package/adapters/codex/skills/forge/references/stage-exit-protocol.md +258 -0
  76. package/adapters/codex/skills/forge-0-epic/references/epic-manifest-subcommands.md +11 -0
  77. package/adapters/codex/skills/forge-0-epic/references/pipeline-state-schema.json +191 -0
  78. package/adapters/codex/skills/forge-0-epic/references/portable-root.md +71 -0
  79. package/adapters/codex/skills/forge-0-epic/references/shared-conventions.md +283 -0
  80. package/adapters/codex/skills/forge-0-epic/references/stage-exit-protocol.md +258 -0
  81. package/adapters/codex/skills/forge-1-prd/references/pipeline-state-schema.json +191 -0
  82. package/adapters/codex/skills/forge-1-prd/references/shared-conventions.md +283 -0
  83. package/adapters/codex/skills/forge-1-prd/references/stage-exit-protocol.md +258 -0
  84. package/adapters/codex/skills/forge-2-tech/SKILL.md +1 -1
  85. package/adapters/codex/skills/forge-2-tech/references/pipeline-state-schema.json +191 -0
  86. package/adapters/codex/skills/forge-2-tech/references/shared-conventions.md +283 -0
  87. package/adapters/codex/skills/forge-2-tech/references/stack-resolution.md +54 -0
  88. package/adapters/codex/skills/forge-2-tech/references/stacks/_generic.md +90 -0
  89. package/adapters/codex/skills/forge-2-tech/references/stacks/go.md +138 -0
  90. package/adapters/codex/skills/forge-2-tech/references/stacks/python.md +163 -0
  91. package/adapters/codex/skills/forge-2-tech/references/stacks/rust.md +151 -0
  92. package/adapters/codex/skills/forge-2-tech/references/stacks/typescript.md +111 -0
  93. package/adapters/codex/skills/forge-2-tech/references/stage-exit-protocol.md +258 -0
  94. package/adapters/codex/skills/forge-3-specs/references/pipeline-state-schema.json +191 -0
  95. package/adapters/codex/skills/forge-3-specs/references/shared-conventions.md +283 -0
  96. package/adapters/codex/skills/forge-3-specs/references/stacks/_generic.md +90 -0
  97. package/adapters/codex/skills/forge-3-specs/references/stacks/go.md +138 -0
  98. package/adapters/codex/skills/forge-3-specs/references/stacks/python.md +163 -0
  99. package/adapters/codex/skills/forge-3-specs/references/stacks/rust.md +151 -0
  100. package/adapters/codex/skills/forge-3-specs/references/stacks/typescript.md +111 -0
  101. package/adapters/codex/skills/forge-3-specs/references/stage-exit-protocol.md +258 -0
  102. package/adapters/codex/skills/forge-4-backlog/references/forge-config-schema.json +236 -0
  103. package/adapters/codex/skills/forge-4-backlog/references/pipeline-state-schema.json +191 -0
  104. package/adapters/codex/skills/forge-4-backlog/references/shared-conventions.md +283 -0
  105. package/adapters/codex/skills/forge-4-backlog/references/stage-exit-protocol.md +258 -0
  106. package/adapters/codex/skills/forge-5-loop/references/forge-config-schema.json +236 -0
  107. package/adapters/codex/skills/forge-5-loop/references/ralph-loop-contract.md +221 -0
  108. package/adapters/codex/skills/forge-5-loop/references/shared-conventions.md +283 -0
  109. package/adapters/codex/skills/forge-5-loop/references/stage-exit-protocol.md +258 -0
  110. package/adapters/codex/skills/forge-6-docs/SKILL.md +4 -1
  111. package/adapters/codex/skills/forge-6-docs/references/pipeline-state-schema.json +191 -0
  112. package/adapters/codex/skills/forge-6-docs/references/shared-conventions.md +283 -0
  113. package/adapters/codex/skills/forge-fix/references/shared-conventions.md +283 -0
  114. package/adapters/codex/skills/forge-fix/references/stage-exit-protocol.md +258 -0
  115. package/adapters/codex/skills/forge-guide/references/forge-config-schema.json +236 -0
  116. package/adapters/codex/skills/forge-guide/references/process-overview.md +143 -0
  117. package/adapters/codex/skills/forge-guide/references/ralph-loop-contract.md +221 -0
  118. package/adapters/codex/skills/forge-guide/references/shared-conventions.md +283 -0
  119. package/adapters/codex/skills/forge-guide/references/stack-resolution.md +54 -0
  120. package/adapters/codex/skills/forge-guide/references/stacks/_generic.md +90 -0
  121. package/adapters/codex/skills/forge-guide/references/stacks/go.md +138 -0
  122. package/adapters/codex/skills/forge-guide/references/stacks/python.md +163 -0
  123. package/adapters/codex/skills/forge-guide/references/stacks/rust.md +151 -0
  124. package/adapters/codex/skills/forge-guide/references/stacks/typescript.md +111 -0
  125. package/adapters/codex/skills/forge-init/SKILL.md +1 -0
  126. package/adapters/codex/skills/forge-verify/SKILL.md +4 -3
  127. package/adapters/codex/skills/forge-verify/references/pipeline-state-schema.json +191 -0
  128. package/adapters/codex/skills/forge-verify/references/shared-conventions.md +283 -0
  129. package/adapters/codex/skills/forge-verify/references/verification-checklists.md +7 -0
  130. package/adapters/copilot/.feature-forge-bundle.json +1 -1
  131. package/adapters/copilot/references/forge-config-schema.json +5 -0
  132. package/adapters/copilot/scripts/epic-manifest.py +209 -0
  133. package/adapters/copilot/scripts/forge-bootstrap.py +1 -0
  134. package/adapters/copilot/scripts/forge-init.sh +2 -0
  135. package/adapters/copilot/skills/forge/forge.md +9 -1
  136. package/adapters/copilot/skills/forge/references/pipeline-state-schema.json +191 -0
  137. package/adapters/copilot/skills/forge/references/process-overview.md +143 -0
  138. package/adapters/copilot/skills/forge/references/shared-conventions.md +283 -0
  139. package/adapters/copilot/skills/forge/references/stage-exit-protocol.md +258 -0
  140. package/adapters/copilot/skills/forge-0-epic/references/epic-manifest-subcommands.md +11 -0
  141. package/adapters/copilot/skills/forge-0-epic/references/pipeline-state-schema.json +191 -0
  142. package/adapters/copilot/skills/forge-0-epic/references/portable-root.md +71 -0
  143. package/adapters/copilot/skills/forge-0-epic/references/shared-conventions.md +283 -0
  144. package/adapters/copilot/skills/forge-0-epic/references/stage-exit-protocol.md +258 -0
  145. package/adapters/copilot/skills/forge-1-prd/references/pipeline-state-schema.json +191 -0
  146. package/adapters/copilot/skills/forge-1-prd/references/shared-conventions.md +283 -0
  147. package/adapters/copilot/skills/forge-1-prd/references/stage-exit-protocol.md +258 -0
  148. package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +1 -1
  149. package/adapters/copilot/skills/forge-2-tech/references/pipeline-state-schema.json +191 -0
  150. package/adapters/copilot/skills/forge-2-tech/references/shared-conventions.md +283 -0
  151. package/adapters/copilot/skills/forge-2-tech/references/stack-resolution.md +54 -0
  152. package/adapters/copilot/skills/forge-2-tech/references/stacks/_generic.md +90 -0
  153. package/adapters/copilot/skills/forge-2-tech/references/stacks/go.md +138 -0
  154. package/adapters/copilot/skills/forge-2-tech/references/stacks/python.md +163 -0
  155. package/adapters/copilot/skills/forge-2-tech/references/stacks/rust.md +151 -0
  156. package/adapters/copilot/skills/forge-2-tech/references/stacks/typescript.md +111 -0
  157. package/adapters/copilot/skills/forge-2-tech/references/stage-exit-protocol.md +258 -0
  158. package/adapters/copilot/skills/forge-3-specs/references/pipeline-state-schema.json +191 -0
  159. package/adapters/copilot/skills/forge-3-specs/references/shared-conventions.md +283 -0
  160. package/adapters/copilot/skills/forge-3-specs/references/stacks/_generic.md +90 -0
  161. package/adapters/copilot/skills/forge-3-specs/references/stacks/go.md +138 -0
  162. package/adapters/copilot/skills/forge-3-specs/references/stacks/python.md +163 -0
  163. package/adapters/copilot/skills/forge-3-specs/references/stacks/rust.md +151 -0
  164. package/adapters/copilot/skills/forge-3-specs/references/stacks/typescript.md +111 -0
  165. package/adapters/copilot/skills/forge-3-specs/references/stage-exit-protocol.md +258 -0
  166. package/adapters/copilot/skills/forge-4-backlog/references/forge-config-schema.json +236 -0
  167. package/adapters/copilot/skills/forge-4-backlog/references/pipeline-state-schema.json +191 -0
  168. package/adapters/copilot/skills/forge-4-backlog/references/shared-conventions.md +283 -0
  169. package/adapters/copilot/skills/forge-4-backlog/references/stage-exit-protocol.md +258 -0
  170. package/adapters/copilot/skills/forge-5-loop/references/forge-config-schema.json +236 -0
  171. package/adapters/copilot/skills/forge-5-loop/references/ralph-loop-contract.md +221 -0
  172. package/adapters/copilot/skills/forge-5-loop/references/shared-conventions.md +283 -0
  173. package/adapters/copilot/skills/forge-5-loop/references/stage-exit-protocol.md +258 -0
  174. package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +4 -1
  175. package/adapters/copilot/skills/forge-6-docs/references/pipeline-state-schema.json +191 -0
  176. package/adapters/copilot/skills/forge-6-docs/references/shared-conventions.md +283 -0
  177. package/adapters/copilot/skills/forge-fix/references/shared-conventions.md +283 -0
  178. package/adapters/copilot/skills/forge-fix/references/stage-exit-protocol.md +258 -0
  179. package/adapters/copilot/skills/forge-guide/references/forge-config-schema.json +236 -0
  180. package/adapters/copilot/skills/forge-guide/references/process-overview.md +143 -0
  181. package/adapters/copilot/skills/forge-guide/references/ralph-loop-contract.md +221 -0
  182. package/adapters/copilot/skills/forge-guide/references/shared-conventions.md +283 -0
  183. package/adapters/copilot/skills/forge-guide/references/stack-resolution.md +54 -0
  184. package/adapters/copilot/skills/forge-guide/references/stacks/_generic.md +90 -0
  185. package/adapters/copilot/skills/forge-guide/references/stacks/go.md +138 -0
  186. package/adapters/copilot/skills/forge-guide/references/stacks/python.md +163 -0
  187. package/adapters/copilot/skills/forge-guide/references/stacks/rust.md +151 -0
  188. package/adapters/copilot/skills/forge-guide/references/stacks/typescript.md +111 -0
  189. package/adapters/copilot/skills/forge-init/forge-init.md +1 -0
  190. package/adapters/copilot/skills/forge-verify/forge-verify.md +4 -3
  191. package/adapters/copilot/skills/forge-verify/references/pipeline-state-schema.json +191 -0
  192. package/adapters/copilot/skills/forge-verify/references/shared-conventions.md +283 -0
  193. package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +7 -0
  194. package/adapters/cursor/.feature-forge-bundle.json +1 -1
  195. package/adapters/cursor/references/forge-config-schema.json +5 -0
  196. package/adapters/cursor/scripts/epic-manifest.py +209 -0
  197. package/adapters/cursor/scripts/forge-bootstrap.py +1 -0
  198. package/adapters/cursor/scripts/forge-init.sh +2 -0
  199. package/adapters/cursor/skills/forge/forge.mdc +9 -1
  200. package/adapters/cursor/skills/forge/references/pipeline-state-schema.json +191 -0
  201. package/adapters/cursor/skills/forge/references/process-overview.md +143 -0
  202. package/adapters/cursor/skills/forge/references/shared-conventions.md +283 -0
  203. package/adapters/cursor/skills/forge/references/stage-exit-protocol.md +258 -0
  204. package/adapters/cursor/skills/forge-0-epic/references/epic-manifest-subcommands.md +11 -0
  205. package/adapters/cursor/skills/forge-0-epic/references/pipeline-state-schema.json +191 -0
  206. package/adapters/cursor/skills/forge-0-epic/references/portable-root.md +71 -0
  207. package/adapters/cursor/skills/forge-0-epic/references/shared-conventions.md +283 -0
  208. package/adapters/cursor/skills/forge-0-epic/references/stage-exit-protocol.md +258 -0
  209. package/adapters/cursor/skills/forge-1-prd/references/pipeline-state-schema.json +191 -0
  210. package/adapters/cursor/skills/forge-1-prd/references/shared-conventions.md +283 -0
  211. package/adapters/cursor/skills/forge-1-prd/references/stage-exit-protocol.md +258 -0
  212. package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +1 -1
  213. package/adapters/cursor/skills/forge-2-tech/references/pipeline-state-schema.json +191 -0
  214. package/adapters/cursor/skills/forge-2-tech/references/shared-conventions.md +283 -0
  215. package/adapters/cursor/skills/forge-2-tech/references/stack-resolution.md +54 -0
  216. package/adapters/cursor/skills/forge-2-tech/references/stacks/_generic.md +90 -0
  217. package/adapters/cursor/skills/forge-2-tech/references/stacks/go.md +138 -0
  218. package/adapters/cursor/skills/forge-2-tech/references/stacks/python.md +163 -0
  219. package/adapters/cursor/skills/forge-2-tech/references/stacks/rust.md +151 -0
  220. package/adapters/cursor/skills/forge-2-tech/references/stacks/typescript.md +111 -0
  221. package/adapters/cursor/skills/forge-2-tech/references/stage-exit-protocol.md +258 -0
  222. package/adapters/cursor/skills/forge-3-specs/references/pipeline-state-schema.json +191 -0
  223. package/adapters/cursor/skills/forge-3-specs/references/shared-conventions.md +283 -0
  224. package/adapters/cursor/skills/forge-3-specs/references/stacks/_generic.md +90 -0
  225. package/adapters/cursor/skills/forge-3-specs/references/stacks/go.md +138 -0
  226. package/adapters/cursor/skills/forge-3-specs/references/stacks/python.md +163 -0
  227. package/adapters/cursor/skills/forge-3-specs/references/stacks/rust.md +151 -0
  228. package/adapters/cursor/skills/forge-3-specs/references/stacks/typescript.md +111 -0
  229. package/adapters/cursor/skills/forge-3-specs/references/stage-exit-protocol.md +258 -0
  230. package/adapters/cursor/skills/forge-4-backlog/references/forge-config-schema.json +236 -0
  231. package/adapters/cursor/skills/forge-4-backlog/references/pipeline-state-schema.json +191 -0
  232. package/adapters/cursor/skills/forge-4-backlog/references/shared-conventions.md +283 -0
  233. package/adapters/cursor/skills/forge-4-backlog/references/stage-exit-protocol.md +258 -0
  234. package/adapters/cursor/skills/forge-5-loop/references/forge-config-schema.json +236 -0
  235. package/adapters/cursor/skills/forge-5-loop/references/ralph-loop-contract.md +221 -0
  236. package/adapters/cursor/skills/forge-5-loop/references/shared-conventions.md +283 -0
  237. package/adapters/cursor/skills/forge-5-loop/references/stage-exit-protocol.md +258 -0
  238. package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +4 -1
  239. package/adapters/cursor/skills/forge-6-docs/references/pipeline-state-schema.json +191 -0
  240. package/adapters/cursor/skills/forge-6-docs/references/shared-conventions.md +283 -0
  241. package/adapters/cursor/skills/forge-fix/references/shared-conventions.md +283 -0
  242. package/adapters/cursor/skills/forge-fix/references/stage-exit-protocol.md +258 -0
  243. package/adapters/cursor/skills/forge-guide/references/forge-config-schema.json +236 -0
  244. package/adapters/cursor/skills/forge-guide/references/process-overview.md +143 -0
  245. package/adapters/cursor/skills/forge-guide/references/ralph-loop-contract.md +221 -0
  246. package/adapters/cursor/skills/forge-guide/references/shared-conventions.md +283 -0
  247. package/adapters/cursor/skills/forge-guide/references/stack-resolution.md +54 -0
  248. package/adapters/cursor/skills/forge-guide/references/stacks/_generic.md +90 -0
  249. package/adapters/cursor/skills/forge-guide/references/stacks/go.md +138 -0
  250. package/adapters/cursor/skills/forge-guide/references/stacks/python.md +163 -0
  251. package/adapters/cursor/skills/forge-guide/references/stacks/rust.md +151 -0
  252. package/adapters/cursor/skills/forge-guide/references/stacks/typescript.md +111 -0
  253. package/adapters/cursor/skills/forge-init/forge-init.mdc +1 -0
  254. package/adapters/cursor/skills/forge-verify/forge-verify.mdc +4 -3
  255. package/adapters/cursor/skills/forge-verify/references/pipeline-state-schema.json +191 -0
  256. package/adapters/cursor/skills/forge-verify/references/shared-conventions.md +283 -0
  257. package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +7 -0
  258. package/adapters/gemini/.feature-forge-bundle.json +1 -1
  259. package/adapters/gemini/gemini-extension.json +1 -1
  260. package/adapters/gemini/references/forge-config-schema.json +5 -0
  261. package/adapters/gemini/scripts/epic-manifest.py +209 -0
  262. package/adapters/gemini/scripts/forge-bootstrap.py +1 -0
  263. package/adapters/gemini/scripts/forge-init.sh +2 -0
  264. package/adapters/gemini/skills/forge/forge.md +9 -1
  265. package/adapters/gemini/skills/forge/references/pipeline-state-schema.json +191 -0
  266. package/adapters/gemini/skills/forge/references/process-overview.md +143 -0
  267. package/adapters/gemini/skills/forge/references/shared-conventions.md +283 -0
  268. package/adapters/gemini/skills/forge/references/stage-exit-protocol.md +258 -0
  269. package/adapters/gemini/skills/forge-0-epic/references/epic-manifest-subcommands.md +11 -0
  270. package/adapters/gemini/skills/forge-0-epic/references/pipeline-state-schema.json +191 -0
  271. package/adapters/gemini/skills/forge-0-epic/references/portable-root.md +71 -0
  272. package/adapters/gemini/skills/forge-0-epic/references/shared-conventions.md +283 -0
  273. package/adapters/gemini/skills/forge-0-epic/references/stage-exit-protocol.md +258 -0
  274. package/adapters/gemini/skills/forge-1-prd/references/pipeline-state-schema.json +191 -0
  275. package/adapters/gemini/skills/forge-1-prd/references/shared-conventions.md +283 -0
  276. package/adapters/gemini/skills/forge-1-prd/references/stage-exit-protocol.md +258 -0
  277. package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +1 -1
  278. package/adapters/gemini/skills/forge-2-tech/references/pipeline-state-schema.json +191 -0
  279. package/adapters/gemini/skills/forge-2-tech/references/shared-conventions.md +283 -0
  280. package/adapters/gemini/skills/forge-2-tech/references/stack-resolution.md +54 -0
  281. package/adapters/gemini/skills/forge-2-tech/references/stacks/_generic.md +90 -0
  282. package/adapters/gemini/skills/forge-2-tech/references/stacks/go.md +138 -0
  283. package/adapters/gemini/skills/forge-2-tech/references/stacks/python.md +163 -0
  284. package/adapters/gemini/skills/forge-2-tech/references/stacks/rust.md +151 -0
  285. package/adapters/gemini/skills/forge-2-tech/references/stacks/typescript.md +111 -0
  286. package/adapters/gemini/skills/forge-2-tech/references/stage-exit-protocol.md +258 -0
  287. package/adapters/gemini/skills/forge-3-specs/references/pipeline-state-schema.json +191 -0
  288. package/adapters/gemini/skills/forge-3-specs/references/shared-conventions.md +283 -0
  289. package/adapters/gemini/skills/forge-3-specs/references/stacks/_generic.md +90 -0
  290. package/adapters/gemini/skills/forge-3-specs/references/stacks/go.md +138 -0
  291. package/adapters/gemini/skills/forge-3-specs/references/stacks/python.md +163 -0
  292. package/adapters/gemini/skills/forge-3-specs/references/stacks/rust.md +151 -0
  293. package/adapters/gemini/skills/forge-3-specs/references/stacks/typescript.md +111 -0
  294. package/adapters/gemini/skills/forge-3-specs/references/stage-exit-protocol.md +258 -0
  295. package/adapters/gemini/skills/forge-4-backlog/references/forge-config-schema.json +236 -0
  296. package/adapters/gemini/skills/forge-4-backlog/references/pipeline-state-schema.json +191 -0
  297. package/adapters/gemini/skills/forge-4-backlog/references/shared-conventions.md +283 -0
  298. package/adapters/gemini/skills/forge-4-backlog/references/stage-exit-protocol.md +258 -0
  299. package/adapters/gemini/skills/forge-5-loop/references/forge-config-schema.json +236 -0
  300. package/adapters/gemini/skills/forge-5-loop/references/ralph-loop-contract.md +221 -0
  301. package/adapters/gemini/skills/forge-5-loop/references/shared-conventions.md +283 -0
  302. package/adapters/gemini/skills/forge-5-loop/references/stage-exit-protocol.md +258 -0
  303. package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +4 -1
  304. package/adapters/gemini/skills/forge-6-docs/references/pipeline-state-schema.json +191 -0
  305. package/adapters/gemini/skills/forge-6-docs/references/shared-conventions.md +283 -0
  306. package/adapters/gemini/skills/forge-fix/references/shared-conventions.md +283 -0
  307. package/adapters/gemini/skills/forge-fix/references/stage-exit-protocol.md +258 -0
  308. package/adapters/gemini/skills/forge-guide/references/forge-config-schema.json +236 -0
  309. package/adapters/gemini/skills/forge-guide/references/process-overview.md +143 -0
  310. package/adapters/gemini/skills/forge-guide/references/ralph-loop-contract.md +221 -0
  311. package/adapters/gemini/skills/forge-guide/references/shared-conventions.md +283 -0
  312. package/adapters/gemini/skills/forge-guide/references/stack-resolution.md +54 -0
  313. package/adapters/gemini/skills/forge-guide/references/stacks/_generic.md +90 -0
  314. package/adapters/gemini/skills/forge-guide/references/stacks/go.md +138 -0
  315. package/adapters/gemini/skills/forge-guide/references/stacks/python.md +163 -0
  316. package/adapters/gemini/skills/forge-guide/references/stacks/rust.md +151 -0
  317. package/adapters/gemini/skills/forge-guide/references/stacks/typescript.md +111 -0
  318. package/adapters/gemini/skills/forge-init/forge-init.md +1 -0
  319. package/adapters/gemini/skills/forge-verify/forge-verify.md +4 -3
  320. package/adapters/gemini/skills/forge-verify/references/pipeline-state-schema.json +191 -0
  321. package/adapters/gemini/skills/forge-verify/references/shared-conventions.md +283 -0
  322. package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +7 -0
  323. package/package.json +1 -1
@@ -131,6 +131,7 @@ These files are transported byte-for-byte from canon into every `adapters/<agent
131
131
  - `scripts/forge-root.sh` → `adapters/<agent>/scripts/forge-root.sh` (mode 0755, byte-identical — REQ-GEN-05).
132
132
  - the whole repo-root `references/` tree (all root files plus the `stacks/` and `templates/specs-hygiene/` subtrees) → `adapters/<agent>/references/` (verbatim — REQ-GEN-04 / D5).
133
133
  - each skill's own `references/` subdir → `adapters/<agent>/skills/<name>/references/` (verbatim, where present).
134
+ - each bundle-root SHARED reference a skill cites (e.g. `references/shared-conventions.md`, `references/stacks/`) → that skill's `adapters/<agent>/skills/<name>/references/` (verbatim), so a bare `references/X` prose read resolves skill-local on every install layout — including the non-plugin Claude tree with no `${CLAUDE_PLUGIN_ROOT}` (#132).
134
135
 
135
136
  Regenerate all adapter output with `python3 scripts/build-adapters.py`.
136
137
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feature-forge",
3
- "version": "0.12.7",
3
+ "version": "0.12.8",
4
4
  "agent": "claude",
5
5
  "generatedBy": "python3 scripts/build-adapters.py"
6
6
  }
@@ -51,6 +51,11 @@
51
51
  "type": ["string", "null"],
52
52
  "description": "Command to run tests. Null until set. Examples: 'bun test', 'pytest', 'go test ./...'. Used in acceptance criteria and verification."
53
53
  },
54
+ "smokeCommand": {
55
+ "type": ["string", "null"],
56
+ "default": null,
57
+ "description": "Optional end-to-end smoke command that boots the wired application entrypoint and drives one happy-path request, exiting 0 on success. DISTINCT from testCommand (unit tests, which may self-bootstrap) and loopRunner.runCommand (the loop launcher). Consumed by impl-verify's runnability check (CHECK-I21): when set it is executed (pass iff exit 0); when null the check degrades to an advisory not-applicable finding, never a hard fail (mirrors how a null typeCheckCommand is treated). Examples: 'npm run smoke', './scripts/smoke.sh', 'curl -fsS localhost:3000/health'."
58
+ },
54
59
  "loopIterationMultiplier": {
55
60
  "type": "number",
56
61
  "default": 1.5,
@@ -27,6 +27,7 @@ import argparse
27
27
  import json
28
28
  import os
29
29
  import re
30
+ import shutil
30
31
  import sys
31
32
  import tempfile
32
33
  from datetime import datetime, timezone
@@ -1195,6 +1196,180 @@ def set_status(epic_dir: Path, specs_dir: Path, status: str) -> list[Finding]:
1195
1196
  return _bump_and_write(epic_dir, specs_dir, manifest)
1196
1197
 
1197
1198
 
1199
+ def _load_state_strict(state_path: Path) -> dict:
1200
+ """Read a .pipeline-state.json, raising UsageError on a missing/corrupt file.
1201
+
1202
+ Unlike ``_read_state_safely`` (which downgrades a torn read to ``{}`` for the
1203
+ read-only dashboard), an adopt mutation must NOT silently discard the
1204
+ standalone's stage history — a corrupt source is a hard stop (exit 2) so the
1205
+ human fixes it before the irreversible move.
1206
+ """
1207
+ try:
1208
+ parsed = json.loads(state_path.read_text(encoding="utf-8"))
1209
+ except OSError as exc:
1210
+ raise UsageError(f"cannot read {state_path}: {exc}")
1211
+ except json.JSONDecodeError as exc:
1212
+ raise UsageError(f"{state_path} is not valid JSON: {exc}")
1213
+ if not isinstance(parsed, dict):
1214
+ raise UsageError(f"{state_path} is not a JSON object")
1215
+ return parsed
1216
+
1217
+
1218
+ def _merge_member_state(stub: dict, standalone: dict, epic_name: str) -> dict:
1219
+ """Merge a detached standalone's state onto an epic member stub (Issue #126).
1220
+
1221
+ The **stub** is the base — it carries the correct ``epic`` and ``branch``
1222
+ back-pointers that the epic minted. The **standalone** holds the real work, so
1223
+ its stage history / artifacts / currentStage overlay the stub. The ``epic``
1224
+ back-pointer is forced to the target epic; the stub's ``branch`` is preserved
1225
+ (only falling back to the standalone's when the stub has none).
1226
+ """
1227
+ merged = dict(stub)
1228
+ for key in ("currentStage", "artifacts", "notes",
1229
+ "deferredDecisions", "epicChangeRequests"):
1230
+ if key in standalone:
1231
+ merged[key] = standalone[key]
1232
+ stages = dict(stub.get("stages") or {})
1233
+ stages.update(standalone.get("stages") or {})
1234
+ merged["stages"] = stages
1235
+ merged["epic"] = epic_name
1236
+ if not (isinstance(stub.get("branch"), str) and stub["branch"]) and \
1237
+ isinstance(standalone.get("branch"), str) and standalone["branch"]:
1238
+ merged["branch"] = standalone["branch"]
1239
+ return merged
1240
+
1241
+
1242
+ def adopt_feature(
1243
+ epic_dir: Path,
1244
+ specs_dir: Path,
1245
+ feature: str,
1246
+ charter: str | None,
1247
+ deps: list[str],
1248
+ ) -> dict:
1249
+ """Reconcile a detached standalone feature into an epic member (Issue #126).
1250
+
1251
+ The scripted recovery for a **split-brain epic** (#125): a feature that should
1252
+ be an epic member was forged as a flat standalone at ``{specsDir}/{feature}/``.
1253
+ This relocates it into the member slot ``{epicDir}/{feature}/``, merging state
1254
+ so the stub's ``epic``/``branch`` back-pointers survive, removes the flat dir
1255
+ (no residual), and adds the feature to the manifest if absent.
1256
+
1257
+ Operates on the CURRENT tree/branch — both the flat standalone and the epic
1258
+ manifest must already be present (the human brings a cross-branch standalone
1259
+ onto the epic's home branch first, per ``docs/recovery-detached-epic-member.md``;
1260
+ EPIC.md prose is regenerated separately via forge-0-epic). Deliberately ordered
1261
+ **relocate-then-manifest**: after the flat dir is gone the feature name maps to
1262
+ exactly one dir, so ``add_feature``'s global-uniqueness re-validation stays
1263
+ clean. Re-entrant — a half-finished run (files moved, manifest not yet updated)
1264
+ completes on re-run.
1265
+
1266
+ Args:
1267
+ epic_dir: The target epic subtree directory (must hold epic-manifest.json).
1268
+ specs_dir: The configured specs directory.
1269
+ feature: The detached standalone feature name to adopt.
1270
+ charter: Charter for the manifest entry when the feature is not yet a
1271
+ member; a default is used when omitted.
1272
+ deps: dependsOn for the new manifest entry (ignored if already a member).
1273
+
1274
+ Returns:
1275
+ A summary dict (``adopted``/``relocated``/``manifestUpdated``/…) on success.
1276
+
1277
+ Raises:
1278
+ UsageError: Unsafe name, missing manifest, nothing to adopt, or an I/O
1279
+ failure (exit 2).
1280
+ FindingsError: A blocking manifest finding from ``add_feature`` (e.g. an
1281
+ unknown dependency) after relocation — exit 1; re-run after fixing.
1282
+ """
1283
+ assert_safe_name(feature)
1284
+ for dep in deps:
1285
+ assert_safe_name(dep)
1286
+
1287
+ # The epic manifest must exist on this tree (exit 2 if not — nothing to adopt into).
1288
+ load_manifest(epic_dir)
1289
+
1290
+ flat_dir = contained_path(specs_dir, feature)
1291
+ member_dir = contained_path(epic_dir, feature)
1292
+ if flat_dir == member_dir:
1293
+ raise UsageError(f"feature {feature!r} resolves to the epic dir itself")
1294
+
1295
+ flat_state = flat_dir / PIPELINE_STATE_FILENAME
1296
+ member_state = member_dir / PIPELINE_STATE_FILENAME
1297
+ flat_exists = flat_state.is_file()
1298
+ member_exists = member_state.is_file()
1299
+
1300
+ if not flat_exists and not member_exists:
1301
+ raise UsageError(
1302
+ f"nothing to adopt: neither a standalone {flat_dir} nor a member "
1303
+ f"{member_dir} has a {PIPELINE_STATE_FILENAME}"
1304
+ )
1305
+
1306
+ relocated = False
1307
+ if flat_exists:
1308
+ standalone = _load_state_strict(flat_state)
1309
+ if member_exists:
1310
+ merged = _merge_member_state(
1311
+ _read_state_safely(member_state), standalone, epic_dir.name
1312
+ )
1313
+ else:
1314
+ merged = dict(standalone)
1315
+ merged["epic"] = epic_dir.name
1316
+ # Move every artifact except the state file (merged separately) into the
1317
+ # member slot; the standalone (real work) wins on any name collision.
1318
+ member_dir.mkdir(parents=True, exist_ok=True)
1319
+ for child in sorted(flat_dir.iterdir()):
1320
+ if child.name == PIPELINE_STATE_FILENAME:
1321
+ continue
1322
+ dest = member_dir / child.name
1323
+ if dest.is_dir():
1324
+ shutil.rmtree(dest)
1325
+ elif dest.exists():
1326
+ dest.unlink()
1327
+ shutil.move(str(child), str(dest))
1328
+ atomic_write(member_state, merged)
1329
+ shutil.rmtree(flat_dir)
1330
+ relocated = True
1331
+ else:
1332
+ # Already nested (a prior run moved the files) — only ensure the back-pointer.
1333
+ stub = _read_state_safely(member_state)
1334
+ if stub.get("epic") != epic_dir.name:
1335
+ stub["epic"] = epic_dir.name
1336
+ atomic_write(member_state, stub)
1337
+
1338
+ # Ensure the feature is a manifest member (idempotent — the flat dir is gone now,
1339
+ # so add_feature's tree-uniqueness re-check sees exactly one dir for the name).
1340
+ manifest = load_manifest(epic_dir)
1341
+ already_member = any(
1342
+ isinstance(f, dict) and f.get("name") == feature
1343
+ for f in manifest.get("features", [])
1344
+ )
1345
+ manifest_updated = False
1346
+ if not already_member:
1347
+ findings = add_feature(
1348
+ epic_dir, specs_dir, feature,
1349
+ charter or f"Adopted into the {epic_dir.name} epic from a detached standalone.",
1350
+ deps,
1351
+ )
1352
+ if findings:
1353
+ raise FindingsError(findings)
1354
+ manifest_updated = True
1355
+
1356
+ return {
1357
+ "adopted": True,
1358
+ "epic": epic_dir.name,
1359
+ "feature": feature,
1360
+ "memberDir": str(member_dir),
1361
+ "relocated": relocated,
1362
+ "manifestUpdated": manifest_updated,
1363
+ "wasAlreadyMember": already_member,
1364
+ "nextSteps": [
1365
+ f"Regenerate EPIC.md prose via /feature-forge:forge-0-epic {epic_dir.name}",
1366
+ f"Confirm the dashboard via /feature-forge:forge {epic_dir.name}",
1367
+ f"Verify the member via /feature-forge:forge-verify {feature}",
1368
+ "Commit the surgery (stage the epic subtree and the removed flat dir).",
1369
+ ],
1370
+ }
1371
+
1372
+
1198
1373
  # --------------------------------------------------------------------------- #
1199
1374
  # CLI Dispatch (02 §9)
1200
1375
  # --------------------------------------------------------------------------- #
@@ -1285,6 +1460,25 @@ def _dispatch(args: argparse.Namespace, specs_dir: Path) -> int:
1285
1460
  _print_status_table(status)
1286
1461
  return 0
1287
1462
 
1463
+ if cmd == "adopt-feature":
1464
+ epic_dir = contained_path(specs_dir, args.epic)
1465
+ summary = adopt_feature(
1466
+ epic_dir, specs_dir, args.name, args.charter,
1467
+ _split_list(args.depends_on),
1468
+ )
1469
+ if args.json_output:
1470
+ print(json.dumps(summary, indent=2, ensure_ascii=False))
1471
+ else:
1472
+ print(f"Adopted {summary['feature']!r} into epic {summary['epic']!r}.")
1473
+ print(f" member dir: {summary['memberDir']}")
1474
+ print(f" relocated files: {summary['relocated']}")
1475
+ print(f" manifest added: {summary['manifestUpdated']}"
1476
+ f"{' (already a member)' if summary['wasAlreadyMember'] else ''}")
1477
+ print("Next steps:")
1478
+ for step in summary["nextSteps"]:
1479
+ print(f" - {step}")
1480
+ return 0
1481
+
1288
1482
  # Mutators ---------------------------------------------------------------
1289
1483
  if cmd in {"add-feature", "remove-feature", "reorder", "set-dep", "set-status"}:
1290
1484
  epic_dir = contained_path(specs_dir, args.epic)
@@ -1358,6 +1552,21 @@ def _build_parser() -> argparse.ArgumentParser:
1358
1552
  add_specs_dir(p_add)
1359
1553
  add_json(p_add)
1360
1554
 
1555
+ # adopt-feature --------------------------------------------------------- #
1556
+ p_adopt = sub.add_parser(
1557
+ "adopt-feature",
1558
+ help="Reconcile a detached standalone feature into an epic member (#126)",
1559
+ )
1560
+ p_adopt.add_argument("epic")
1561
+ p_adopt.add_argument("name")
1562
+ p_adopt.add_argument(
1563
+ "--charter", default=None,
1564
+ help="Charter for the manifest entry when the feature is not yet a member",
1565
+ )
1566
+ p_adopt.add_argument("--depends-on", dest="depends_on", default="", help="Comma list")
1567
+ add_specs_dir(p_adopt)
1568
+ add_json(p_adopt)
1569
+
1361
1570
  # remove-feature -------------------------------------------------------- #
1362
1571
  p_remove = sub.add_parser("remove-feature", help="Remove a member feature")
1363
1572
  p_remove.add_argument("epic")
@@ -568,6 +568,7 @@ def write_config(answers: Answers, target: Path, sentinel: Sentinel) -> None:
568
568
  "stack": None,
569
569
  "typeCheckCommand": None,
570
570
  "testCommand": None,
571
+ "smokeCommand": None,
571
572
  "loopIterationMultiplier": 1.5,
572
573
  # Navigator keys — kept in lockstep with forge-init.sh's emitted field set
573
574
  # (00 §7, REQ-CFG-02) so a bootstrapped config == forge-init's + loopRunner.
@@ -21,6 +21,7 @@ cat > "$CONFIG_FILE" << 'EOF'
21
21
  "stack": null,
22
22
  "typeCheckCommand": null,
23
23
  "testCommand": null,
24
+ "smokeCommand": null,
24
25
  "loopIterationMultiplier": 1.5,
25
26
  "autoInvokeNextStage": true,
26
27
  "contextWindowTokens": null,
@@ -42,6 +43,7 @@ echo " commitPrefix: forge"
42
43
  echo " stack: null (auto-detected during forge-2-tech)"
43
44
  echo " typeCheckCommand: null (auto-detected during forge-2-tech)"
44
45
  echo " testCommand: null (auto-detected during forge-2-tech)"
46
+ echo " smokeCommand: null (optional end-to-end smoke; enables impl-verify runnability check)"
45
47
  echo " loopIterationMultiplier: 1.5 (multiplier for loop iterations)"
46
48
  echo " autoInvokeNextStage: true (navigator auto-starts the next stage after you confirm)"
47
49
  echo " contextWindowTokens: null (infer; set to 1000000 on a 1M-context model)"
@@ -89,10 +89,18 @@ Use these status indicators:
89
89
 
90
90
  After rendering a **per-feature** dashboard for an **active** pipeline (skip this for paused/abandoned pipelines and for the Epic Dashboard), don't stop at a text suggestion — actively offer to start the next stage. This removes the copy-paste-after-`/clear` chore that makes long, multi-stage runs painful (especially on mobile).
91
91
 
92
- **1. Read the next step.** From the `rank-features --json` output (above), find this feature's row and read its `nextStage`, `nextCommand`, `verifyPending`, `verifyCommand`, `verifyStage`, `verifyState`, `autoVerify`, `autoFix`, and `verifyGate` (the resolved gate: `none` → no verify action; `auto` → the §2b catch-up; `standard` → the §3 gate). If the feature is not in the `active` list (paused/abandoned), or `nextStage` is `null` (every production stage complete), skip the drive prompt — instead congratulate the user and, if `forge-6-docs` has not run, offer it; otherwise note the pipeline is complete. If the payload has a non-empty `invalidAutoVerifyKeys`, print a one-line warning first (e.g. "⚠️ forge.config.json `autoVerifyStages` has unknown keys: … — they are ignored; fix the typo").
92
+ **1. Read the next step.** From the `rank-features --json` output (above), find this feature's row and read its `nextStage`, `nextCommand`, `verifyPending`, `verifyCommand`, `verifyStage`, `verifyState`, `autoVerify`, `autoFix`, and `verifyGate` (the resolved gate: `none` → no verify action; `auto` → the §2b catch-up; `standard` → the §3 gate). If the feature is not in the `active` list (paused/abandoned), or `nextStage` is `null` (every production stage complete), skip the drive prompt — instead congratulate the user and, if `forge-6-docs` has not run, offer it; otherwise the whole pipeline is done, so **route into the Completion hand-off block below instead of dead-ending** (steps 2/2b/3 do not apply — there is no next stage to drive). If the payload has a non-empty `invalidAutoVerifyKeys`, print a one-line warning first (e.g. "⚠️ forge.config.json `autoVerifyStages` has unknown keys: … — they are ignored; fix the typo").
93
93
 
94
94
  **Detached-epic hint (completion of a *standalone* feature, Issue #125).** When `nextStage` is `null` for a feature whose row has no `epic` (a standalone completion), run `discover-feature "{feature}" --json` (via the standard prelude) *before* congratulating. If any candidate has `isEpicMember: true` on another branch, add an **additive, non-blocking** hint — it does not change the completion, only flags a likely split-brain: "⚠️ Heads-up: `{feature}` matches a member of epic `{epic}` on branch `{stateBranch}`. This standalone pipeline may have been forged detached from that epic. To reconcile, see `docs/recovery-detached-epic-member.md` (or continue — this is only a heads-up)." Skip the hint for epic-member rows (their `epic` is non-null) and when discovery surfaces no epic-member candidate.
95
95
 
96
+ **Completion hand-off (fires when `nextStage` is `null` AND `forge-6-docs` has run — the pipeline is fully complete, Issue #124).** Do not dead-end on "pipeline is complete" — after congratulating, point the user at the next unit of work. This is a **terminal branch**: the drive steps (2/2b/3) do not run.
97
+
98
+ - **Epic member** (this feature's `rank-features` row has a non-null `epic`, i.e. its `.pipeline-state.json` carries an `epic` back-pointer): run `epic-manifest.py render-status "{epic}" --specs-dir "{specsDir}" --json` (standard prelude; you likely already have this from the Tier-1 epic rollup — reuse it rather than re-running). Then:
99
+ - If `actionable` is non-empty, offer the next member via `AskUserQuestion`: *"Epic '{epic}' has {total−complete} feature(s) left — next up: **{actionable[0].name}** (`{actionable[0].nextCommand}`). Start it now?"* On accept, drive it exactly like a normal next stage (honor `autoInvokeNextStage` + `Skill`-tool availability per step 3's Continue-in-this-session rule; else print `{nextCommand}`). List any remaining `actionable` members as also-available.
100
+ - If `actionable` is empty but the epic is **not** fully complete (members blocked on unmet `dependsOn`), say so and point at the blockers rather than offering a start.
101
+ - If the epic is **fully complete** (`rollup.complete == rollup.total`, `total > 0`), congratulate on the whole epic and offer the epic-level architecture doc (`/feature-forge:forge-6-docs` already surfaces this — mention it) and/or that the epic can be marked complete (`/feature-forge:forge {epic}` renders the finished dashboard).
102
+ - **Standalone** (row's `epic` is null): offer to start a fresh feature — *"Start a new feature: `/feature-forge:forge-1-prd <feature-name>` (or group several with `/feature-forge:forge-0-epic <epic-name>`)."* Then, from the `rank-features` `active` list, surface any **other** active pipelines (exclude this just-completed one) as a one-line list with their `nextCommand`s so the user can jump straight back into in-flight work. If the **detached-epic hint above fired** for this feature, lead with that recovery path (`docs/recovery-detached-epic-member.md`) — the split-brain reconcile is the more likely next action than starting something new.
103
+
96
104
  **2. Check the context window.** Run the context-usage helper so you can advise whether to continue here or start the next stage in a fresh session:
97
105
  ```bash
98
106
  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')"
@@ -0,0 +1,191 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Feature Forge Pipeline State",
4
+ "description": "Tracks pipeline progress for a single feature across sessions. Lives at {specsDir}/{feature}/.pipeline-state.json",
5
+ "type": "object",
6
+ "required": ["feature", "createdAt", "updatedAt", "currentStage", "stages", "pipelineStatus"],
7
+ "properties": {
8
+ "pipelineStatus": {
9
+ "type": "string",
10
+ "enum": ["active", "paused", "abandoned"],
11
+ "default": "active"
12
+ },
13
+ "feature": {
14
+ "type": "string",
15
+ "description": "Feature name (matches directory name under specsDir)"
16
+ },
17
+ "epic": {
18
+ "type": "string",
19
+ "description": "Back-pointer to the owning epic's name. Absent for standalone features. The epic-manifest.json is canonical on conflict (REQ-STATE-01)."
20
+ },
21
+ "branch": {
22
+ "type": "string",
23
+ "description": "Git branch this feature's pipeline work is intended to land on, recorded by the Branch Setup block (shared-conventions.md) at the entry stage. Absent when the project isn't a git repo or branchPerFeature is false. Downstream stages and forge-5-loop compare the current branch against this to detect drift back onto the default branch before committing."
24
+ },
25
+ "createdAt": {
26
+ "type": "string",
27
+ "format": "date-time"
28
+ },
29
+ "updatedAt": {
30
+ "type": "string",
31
+ "format": "date-time"
32
+ },
33
+ "currentStage": {
34
+ "type": "string",
35
+ "enum": ["forge-1-prd", "forge-2-tech", "forge-3-specs", "forge-4-backlog", "forge-5-loop", "forge-6-docs", "complete", "forge-verify-prd", "forge-verify-tech", "forge-verify-specs", "forge-verify-backlog", "forge-verify-impl", "forge-0-epic", "forge-verify-epic"],
36
+ "description": "Where the pipeline IS: the most recently started stage — its `stages[<currentStage>].status` is `in-progress` while that stage is being authored, then `complete` once its artifacts are committed. A stage skill sets this to its own id when it starts. This is deliberately NOT 'the next stage to run': the next stage is DERIVED, never stored — it is the first production stage whose `stages[].status` is not `complete` (see `next_stage()` in forge-session.py, surfaced as the navigator/doctor `nextStage`). Consumers that need 'what runs next' compute it from `stages[].status`, not from this field. `complete` here means the whole pipeline is done. (Legacy/absent value: tools fall back to the derived next stage for display only — `build_rows` in forge-session.py.)"
37
+ },
38
+ "notes": {
39
+ "type": "string",
40
+ "description": "Free-form notes persisted between sessions (user can add context before stepping away)"
41
+ },
42
+ "epicChangeRequests": {
43
+ "type": "array",
44
+ "description": "Epic-level change requests raised by a member stage (forge-1-prd/forge-2-tech) when the epic DECOMPOSITION itself must change — distinct from the same-feature `notes` parking lot. Read by forge-0-epic edit mode (which applies them) and by forge-session stage-exit (which routes the exit on `blocksCurrent`). Absent/empty for standalone features. Additive/optional: legacy states without it validate unchanged.",
45
+ "items": {
46
+ "type": "object",
47
+ "required": ["kind", "target", "rationale", "blocksCurrent", "raisedBy", "raisedAt", "status"],
48
+ "additionalProperties": false,
49
+ "properties": {
50
+ "kind": {
51
+ "type": "string",
52
+ "enum": ["add-feature", "redep", "move-boundary", "split"],
53
+ "description": "The decomposition change. add-feature/redep map 1:1 onto edit-mode mutators; move-boundary/split are composite (applied guided-manual in v1)."
54
+ },
55
+ "target": {
56
+ "type": "string",
57
+ "description": "The sibling feature to add, or the feature/boundary affected."
58
+ },
59
+ "rationale": {
60
+ "type": "string",
61
+ "description": "Why the epic must change; seeds the edit-mode charter/prompt when applied."
62
+ },
63
+ "blocksCurrent": {
64
+ "type": "boolean",
65
+ "description": "true → the current feature's next stage would build on a soon-to-change decomposition (pause-now: reconcile before proceeding). false → a peer/downstream change (finish-then-edit). Drives stage-exit routing."
66
+ },
67
+ "raisedBy": {
68
+ "type": "string",
69
+ "enum": ["forge-1-prd", "forge-2-tech"],
70
+ "description": "The stage that detected the epic-level concern."
71
+ },
72
+ "raisedAt": { "type": "string", "format": "date-time" },
73
+ "status": {
74
+ "type": "string",
75
+ "enum": ["open", "applied", "dismissed"],
76
+ "default": "open",
77
+ "description": "Lifecycle: open → applied|dismissed. Only forge-0-epic edit mode flips open→applied/dismissed; recording stages only create open entries; navigator/verify only read."
78
+ }
79
+ }
80
+ }
81
+ },
82
+ "deferredDecisions": {
83
+ "type": "array",
84
+ "description": "Same-feature decisions deliberately postponed to a LATER stage of THIS feature — a structured alternative to burying them in the free-text `notes` string. Distinct from `notes` (unstructured scratch) and from `epicChangeRequests[]` (the epic DECOMPOSITION must change). Use this when a stage would otherwise be tempted to solicit a decision that properly belongs to a downstream stage (e.g. forge-1-prd deferring the concrete cache backend to forge-2-tech): record it here instead of asking now (see the deferred-decisions rule in `references/stage-exit-protocol.md`), and the target stage addresses it. Additive/optional: legacy states without it validate unchanged.",
85
+ "items": {
86
+ "type": "object",
87
+ "required": ["question", "raisedBy", "raisedAt", "status"],
88
+ "additionalProperties": false,
89
+ "properties": {
90
+ "question": {
91
+ "type": "string",
92
+ "description": "The decision being deferred, phrased as a concrete question for the target stage to answer."
93
+ },
94
+ "rationale": {
95
+ "type": "string",
96
+ "description": "Why it is deferred rather than decided now (e.g. depends on information the target stage produces)."
97
+ },
98
+ "targetStage": {
99
+ "type": "string",
100
+ "enum": ["forge-1-prd", "forge-2-tech", "forge-3-specs", "forge-4-backlog", "forge-5-loop", "forge-6-docs"],
101
+ "description": "The stage that should resolve this decision. Omit when unknown/any-later-stage."
102
+ },
103
+ "raisedBy": {
104
+ "type": "string",
105
+ "enum": ["forge-1-prd", "forge-2-tech", "forge-3-specs", "forge-4-backlog"],
106
+ "description": "The stage that deferred the decision."
107
+ },
108
+ "raisedAt": { "type": "string", "format": "date-time" },
109
+ "status": {
110
+ "type": "string",
111
+ "enum": ["open", "addressed", "dismissed"],
112
+ "default": "open",
113
+ "description": "Lifecycle: open → addressed|dismissed. The target stage flips open→addressed when it resolves the decision (or dismissed if it no longer applies); recording stages only create open entries."
114
+ }
115
+ }
116
+ }
117
+ },
118
+ "stages": {
119
+ "type": "object",
120
+ "properties": {
121
+ "forge-0-epic": { "$ref": "#/definitions/stageEntry" },
122
+ "forge-verify-epic": { "$ref": "#/definitions/verifyEntry" },
123
+ "forge-1-prd": { "$ref": "#/definitions/stageEntry" },
124
+ "forge-2-tech": { "$ref": "#/definitions/stageEntry" },
125
+ "forge-3-specs": { "$ref": "#/definitions/stageEntry" },
126
+ "forge-verify-specs": { "$ref": "#/definitions/verifyEntry" },
127
+ "forge-4-backlog": { "$ref": "#/definitions/stageEntry" },
128
+ "forge-verify-backlog": { "$ref": "#/definitions/verifyEntry" },
129
+ "forge-5-loop": { "$ref": "#/definitions/stageEntry" },
130
+ "forge-6-docs": { "$ref": "#/definitions/stageEntry" },
131
+ "forge-verify-impl": { "$ref": "#/definitions/verifyEntry" },
132
+ "forge-verify-prd": { "$ref": "#/definitions/verifyEntry" },
133
+ "forge-verify-tech": { "$ref": "#/definitions/verifyEntry" }
134
+ }
135
+ }
136
+ },
137
+ "definitions": {
138
+ "stageEntry": {
139
+ "type": "object",
140
+ "required": ["status"],
141
+ "properties": {
142
+ "status": {
143
+ "type": "string",
144
+ "enum": ["pending", "in-progress", "complete", "stale"]
145
+ },
146
+ "version": {
147
+ "type": "integer",
148
+ "description": "Incremented each time this stage's artifacts are revised"
149
+ },
150
+ "artifacts": {
151
+ "type": "array",
152
+ "items": { "type": "string" },
153
+ "description": "Relative paths to artifacts produced by this stage"
154
+ },
155
+ "startedAt": { "type": ["string", "null"], "format": "date-time" },
156
+ "completedAt": { "type": ["string", "null"], "format": "date-time" },
157
+ "commitHash": {
158
+ "type": ["string", "null"],
159
+ "description": "Git commit SHA of this stage's artifact commit (Commit 1 of the two-commit Git Commit Protocol in shared-conventions.md). Written by a small follow-up commit so it points at the artifact commit itself, never at an orphaned amend or the hash-recording commit. null until recorded (or when there was no new artifact commit)."
160
+ },
161
+ "basedOnVersions": {
162
+ "type": "object",
163
+ "description": "Upstream stage versions this artifact was built against",
164
+ "additionalProperties": { "type": "integer" }
165
+ }
166
+ }
167
+ },
168
+ "verifyEntry": {
169
+ "type": "object",
170
+ "required": ["status"],
171
+ "properties": {
172
+ "status": {
173
+ "type": "string",
174
+ "enum": ["pending", "passed", "findings-reported", "findings-applied", "skipped"]
175
+ },
176
+ "findingsFile": {
177
+ "type": ["string", "null"],
178
+ "description": "Path to the verification findings document"
179
+ },
180
+ "findingsCount": {
181
+ "type": ["integer", "null"],
182
+ "description": "Number of findings reported"
183
+ },
184
+ "verifiedAt": { "type": ["string", "null"], "format": "date-time" },
185
+ "fixedAt": { "type": ["string", "null"], "format": "date-time" },
186
+ "commitHash": { "type": ["string", "null"], "description": "Git commit SHA of the verify/fix artifact commit. Recorded via the two-commit Git Commit Protocol (shared-conventions.md) so it points at the artifact commit, never an orphaned amend." },
187
+ "verifiedStageVersion": { "type": ["integer", "null"], "description": "The production stage's `version` at the moment this verify was resolved. The navigator's freshness ledger compares it to the stage's current `version`: equal means the verify is fresh; a mismatch (artifact revised since) or an absent field (legacy state) means stale, so auto-verify re-fires. Recorded by forge-verify/forge-fix when writing a passed/findings-applied status." }
188
+ }
189
+ }
190
+ }
191
+ }