@garygentry/feature-forge 0.2.13 → 0.3.0

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 (437) hide show
  1. package/README.md +6 -3
  2. package/adapters/GENERATION-REPORT.md +20 -0
  3. package/adapters/claude/.feature-forge-bundle.json +1 -1
  4. package/adapters/claude/references/epic-manifest-schema.json +5 -0
  5. package/adapters/claude/references/forge-config-schema.json +2 -2
  6. package/adapters/claude/references/shared-conventions.md +12 -0
  7. package/adapters/claude/references/stacks/_generic.md +21 -0
  8. package/adapters/claude/references/stacks/go.md +19 -0
  9. package/adapters/claude/references/stacks/python.md +21 -0
  10. package/adapters/claude/references/stacks/rust.md +19 -0
  11. package/adapters/claude/references/stacks/typescript.md +23 -0
  12. package/adapters/claude/scripts/epic-manifest.py +75 -5
  13. package/adapters/claude/scripts/forge-root.sh +102 -14
  14. package/adapters/claude/scripts/forge-session.py +68 -9
  15. package/adapters/claude/skills/forge/references/shared-conventions.md +12 -0
  16. package/adapters/claude/skills/forge-0-epic/references/shared-conventions.md +12 -0
  17. package/adapters/claude/skills/forge-1-prd/SKILL.md +2 -0
  18. package/adapters/claude/skills/forge-1-prd/references/shared-conventions.md +12 -0
  19. package/adapters/claude/skills/forge-2-tech/SKILL.md +2 -0
  20. package/adapters/claude/skills/forge-2-tech/references/shared-conventions.md +12 -0
  21. package/adapters/claude/skills/forge-2-tech/references/stacks/_generic.md +21 -0
  22. package/adapters/claude/skills/forge-2-tech/references/stacks/go.md +19 -0
  23. package/adapters/claude/skills/forge-2-tech/references/stacks/python.md +21 -0
  24. package/adapters/claude/skills/forge-2-tech/references/stacks/rust.md +19 -0
  25. package/adapters/claude/skills/forge-2-tech/references/stacks/typescript.md +23 -0
  26. package/adapters/claude/skills/forge-3-specs/SKILL.md +2 -0
  27. package/adapters/claude/skills/forge-3-specs/references/shared-conventions.md +12 -0
  28. package/adapters/claude/skills/forge-3-specs/references/stacks/_generic.md +21 -0
  29. package/adapters/claude/skills/forge-3-specs/references/stacks/go.md +19 -0
  30. package/adapters/claude/skills/forge-3-specs/references/stacks/python.md +21 -0
  31. package/adapters/claude/skills/forge-3-specs/references/stacks/rust.md +19 -0
  32. package/adapters/claude/skills/forge-3-specs/references/stacks/typescript.md +23 -0
  33. package/adapters/claude/skills/forge-4-backlog/SKILL.md +5 -0
  34. package/adapters/claude/skills/forge-4-backlog/references/forge-config-schema.json +2 -2
  35. package/adapters/claude/skills/forge-4-backlog/references/shared-conventions.md +12 -0
  36. package/adapters/claude/skills/forge-5-loop/SKILL.md +7 -9
  37. package/adapters/claude/skills/forge-5-loop/references/forge-config-schema.json +2 -2
  38. package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +41 -0
  39. package/adapters/claude/skills/forge-5-loop/references/shared-conventions.md +12 -0
  40. package/adapters/claude/skills/forge-6-docs/references/shared-conventions.md +12 -0
  41. package/adapters/claude/skills/forge-fix/references/shared-conventions.md +12 -0
  42. package/adapters/claude/skills/forge-guide/references/forge-config-schema.json +2 -2
  43. package/adapters/claude/skills/forge-guide/references/shared-conventions.md +12 -0
  44. package/adapters/claude/skills/forge-guide/references/stacks/_generic.md +21 -0
  45. package/adapters/claude/skills/forge-guide/references/stacks/go.md +19 -0
  46. package/adapters/claude/skills/forge-guide/references/stacks/python.md +21 -0
  47. package/adapters/claude/skills/forge-guide/references/stacks/rust.md +19 -0
  48. package/adapters/claude/skills/forge-guide/references/stacks/typescript.md +23 -0
  49. package/adapters/claude/skills/forge-verify/SKILL.md +3 -3
  50. package/adapters/claude/skills/forge-verify/references/shared-conventions.md +12 -0
  51. package/adapters/claude/skills/forge-verify/references/verification-checklists.md +82 -3
  52. package/adapters/codex/.feature-forge-bundle.json +1 -1
  53. package/adapters/codex/references/epic-manifest-schema.json +5 -0
  54. package/adapters/codex/references/forge-config-schema.json +2 -2
  55. package/adapters/codex/references/shared-conventions.md +12 -0
  56. package/adapters/codex/references/stacks/_generic.md +21 -0
  57. package/adapters/codex/references/stacks/go.md +19 -0
  58. package/adapters/codex/references/stacks/python.md +21 -0
  59. package/adapters/codex/references/stacks/rust.md +19 -0
  60. package/adapters/codex/references/stacks/typescript.md +23 -0
  61. package/adapters/codex/scripts/epic-manifest.py +75 -5
  62. package/adapters/codex/scripts/forge-root.sh +102 -14
  63. package/adapters/codex/scripts/forge-session.py +68 -9
  64. package/adapters/codex/skills/forge/references/shared-conventions.md +12 -0
  65. package/adapters/codex/skills/forge-0-epic/references/shared-conventions.md +12 -0
  66. package/adapters/codex/skills/forge-1-prd/SKILL.md +2 -0
  67. package/adapters/codex/skills/forge-1-prd/references/shared-conventions.md +12 -0
  68. package/adapters/codex/skills/forge-2-tech/SKILL.md +2 -0
  69. package/adapters/codex/skills/forge-2-tech/references/shared-conventions.md +12 -0
  70. package/adapters/codex/skills/forge-2-tech/references/stacks/_generic.md +21 -0
  71. package/adapters/codex/skills/forge-2-tech/references/stacks/go.md +19 -0
  72. package/adapters/codex/skills/forge-2-tech/references/stacks/python.md +21 -0
  73. package/adapters/codex/skills/forge-2-tech/references/stacks/rust.md +19 -0
  74. package/adapters/codex/skills/forge-2-tech/references/stacks/typescript.md +23 -0
  75. package/adapters/codex/skills/forge-3-specs/SKILL.md +2 -0
  76. package/adapters/codex/skills/forge-3-specs/references/shared-conventions.md +12 -0
  77. package/adapters/codex/skills/forge-3-specs/references/stacks/_generic.md +21 -0
  78. package/adapters/codex/skills/forge-3-specs/references/stacks/go.md +19 -0
  79. package/adapters/codex/skills/forge-3-specs/references/stacks/python.md +21 -0
  80. package/adapters/codex/skills/forge-3-specs/references/stacks/rust.md +19 -0
  81. package/adapters/codex/skills/forge-3-specs/references/stacks/typescript.md +23 -0
  82. package/adapters/codex/skills/forge-4-backlog/SKILL.md +5 -0
  83. package/adapters/codex/skills/forge-4-backlog/references/forge-config-schema.json +2 -2
  84. package/adapters/codex/skills/forge-4-backlog/references/shared-conventions.md +12 -0
  85. package/adapters/codex/skills/forge-5-loop/SKILL.md +7 -9
  86. package/adapters/codex/skills/forge-5-loop/references/forge-config-schema.json +2 -2
  87. package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +41 -0
  88. package/adapters/codex/skills/forge-5-loop/references/shared-conventions.md +12 -0
  89. package/adapters/codex/skills/forge-6-docs/references/shared-conventions.md +12 -0
  90. package/adapters/codex/skills/forge-fix/references/shared-conventions.md +12 -0
  91. package/adapters/codex/skills/forge-guide/references/forge-config-schema.json +2 -2
  92. package/adapters/codex/skills/forge-guide/references/shared-conventions.md +12 -0
  93. package/adapters/codex/skills/forge-guide/references/stacks/_generic.md +21 -0
  94. package/adapters/codex/skills/forge-guide/references/stacks/go.md +19 -0
  95. package/adapters/codex/skills/forge-guide/references/stacks/python.md +21 -0
  96. package/adapters/codex/skills/forge-guide/references/stacks/rust.md +19 -0
  97. package/adapters/codex/skills/forge-guide/references/stacks/typescript.md +23 -0
  98. package/adapters/codex/skills/forge-verify/SKILL.md +3 -3
  99. package/adapters/codex/skills/forge-verify/references/shared-conventions.md +12 -0
  100. package/adapters/codex/skills/forge-verify/references/verification-checklists.md +82 -3
  101. package/adapters/copilot/.feature-forge-bundle.json +1 -1
  102. package/adapters/copilot/references/epic-manifest-schema.json +5 -0
  103. package/adapters/copilot/references/forge-config-schema.json +2 -2
  104. package/adapters/copilot/references/shared-conventions.md +12 -0
  105. package/adapters/copilot/references/stacks/_generic.md +21 -0
  106. package/adapters/copilot/references/stacks/go.md +19 -0
  107. package/adapters/copilot/references/stacks/python.md +21 -0
  108. package/adapters/copilot/references/stacks/rust.md +19 -0
  109. package/adapters/copilot/references/stacks/typescript.md +23 -0
  110. package/adapters/copilot/scripts/epic-manifest.py +75 -5
  111. package/adapters/copilot/scripts/forge-root.sh +102 -14
  112. package/adapters/copilot/scripts/forge-session.py +68 -9
  113. package/adapters/copilot/skills/forge/references/shared-conventions.md +12 -0
  114. package/adapters/copilot/skills/forge-0-epic/references/shared-conventions.md +12 -0
  115. package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +2 -0
  116. package/adapters/copilot/skills/forge-1-prd/references/shared-conventions.md +12 -0
  117. package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +2 -0
  118. package/adapters/copilot/skills/forge-2-tech/references/shared-conventions.md +12 -0
  119. package/adapters/copilot/skills/forge-2-tech/references/stacks/_generic.md +21 -0
  120. package/adapters/copilot/skills/forge-2-tech/references/stacks/go.md +19 -0
  121. package/adapters/copilot/skills/forge-2-tech/references/stacks/python.md +21 -0
  122. package/adapters/copilot/skills/forge-2-tech/references/stacks/rust.md +19 -0
  123. package/adapters/copilot/skills/forge-2-tech/references/stacks/typescript.md +23 -0
  124. package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +2 -0
  125. package/adapters/copilot/skills/forge-3-specs/references/shared-conventions.md +12 -0
  126. package/adapters/copilot/skills/forge-3-specs/references/stacks/_generic.md +21 -0
  127. package/adapters/copilot/skills/forge-3-specs/references/stacks/go.md +19 -0
  128. package/adapters/copilot/skills/forge-3-specs/references/stacks/python.md +21 -0
  129. package/adapters/copilot/skills/forge-3-specs/references/stacks/rust.md +19 -0
  130. package/adapters/copilot/skills/forge-3-specs/references/stacks/typescript.md +23 -0
  131. package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +5 -0
  132. package/adapters/copilot/skills/forge-4-backlog/references/forge-config-schema.json +2 -2
  133. package/adapters/copilot/skills/forge-4-backlog/references/shared-conventions.md +12 -0
  134. package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +7 -9
  135. package/adapters/copilot/skills/forge-5-loop/references/forge-config-schema.json +2 -2
  136. package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +41 -0
  137. package/adapters/copilot/skills/forge-5-loop/references/shared-conventions.md +12 -0
  138. package/adapters/copilot/skills/forge-6-docs/references/shared-conventions.md +12 -0
  139. package/adapters/copilot/skills/forge-fix/references/shared-conventions.md +12 -0
  140. package/adapters/copilot/skills/forge-guide/references/forge-config-schema.json +2 -2
  141. package/adapters/copilot/skills/forge-guide/references/shared-conventions.md +12 -0
  142. package/adapters/copilot/skills/forge-guide/references/stacks/_generic.md +21 -0
  143. package/adapters/copilot/skills/forge-guide/references/stacks/go.md +19 -0
  144. package/adapters/copilot/skills/forge-guide/references/stacks/python.md +21 -0
  145. package/adapters/copilot/skills/forge-guide/references/stacks/rust.md +19 -0
  146. package/adapters/copilot/skills/forge-guide/references/stacks/typescript.md +23 -0
  147. package/adapters/copilot/skills/forge-verify/forge-verify.md +3 -3
  148. package/adapters/copilot/skills/forge-verify/references/shared-conventions.md +12 -0
  149. package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +82 -3
  150. package/adapters/cursor/.feature-forge-bundle.json +1 -1
  151. package/adapters/cursor/references/epic-manifest-schema.json +5 -0
  152. package/adapters/cursor/references/forge-config-schema.json +2 -2
  153. package/adapters/cursor/references/shared-conventions.md +12 -0
  154. package/adapters/cursor/references/stacks/_generic.md +21 -0
  155. package/adapters/cursor/references/stacks/go.md +19 -0
  156. package/adapters/cursor/references/stacks/python.md +21 -0
  157. package/adapters/cursor/references/stacks/rust.md +19 -0
  158. package/adapters/cursor/references/stacks/typescript.md +23 -0
  159. package/adapters/cursor/scripts/epic-manifest.py +75 -5
  160. package/adapters/cursor/scripts/forge-root.sh +102 -14
  161. package/adapters/cursor/scripts/forge-session.py +68 -9
  162. package/adapters/cursor/skills/forge/references/shared-conventions.md +12 -0
  163. package/adapters/cursor/skills/forge-0-epic/references/shared-conventions.md +12 -0
  164. package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +2 -0
  165. package/adapters/cursor/skills/forge-1-prd/references/shared-conventions.md +12 -0
  166. package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +2 -0
  167. package/adapters/cursor/skills/forge-2-tech/references/shared-conventions.md +12 -0
  168. package/adapters/cursor/skills/forge-2-tech/references/stacks/_generic.md +21 -0
  169. package/adapters/cursor/skills/forge-2-tech/references/stacks/go.md +19 -0
  170. package/adapters/cursor/skills/forge-2-tech/references/stacks/python.md +21 -0
  171. package/adapters/cursor/skills/forge-2-tech/references/stacks/rust.md +19 -0
  172. package/adapters/cursor/skills/forge-2-tech/references/stacks/typescript.md +23 -0
  173. package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +2 -0
  174. package/adapters/cursor/skills/forge-3-specs/references/shared-conventions.md +12 -0
  175. package/adapters/cursor/skills/forge-3-specs/references/stacks/_generic.md +21 -0
  176. package/adapters/cursor/skills/forge-3-specs/references/stacks/go.md +19 -0
  177. package/adapters/cursor/skills/forge-3-specs/references/stacks/python.md +21 -0
  178. package/adapters/cursor/skills/forge-3-specs/references/stacks/rust.md +19 -0
  179. package/adapters/cursor/skills/forge-3-specs/references/stacks/typescript.md +23 -0
  180. package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +5 -0
  181. package/adapters/cursor/skills/forge-4-backlog/references/forge-config-schema.json +2 -2
  182. package/adapters/cursor/skills/forge-4-backlog/references/shared-conventions.md +12 -0
  183. package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +7 -9
  184. package/adapters/cursor/skills/forge-5-loop/references/forge-config-schema.json +2 -2
  185. package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +41 -0
  186. package/adapters/cursor/skills/forge-5-loop/references/shared-conventions.md +12 -0
  187. package/adapters/cursor/skills/forge-6-docs/references/shared-conventions.md +12 -0
  188. package/adapters/cursor/skills/forge-fix/references/shared-conventions.md +12 -0
  189. package/adapters/cursor/skills/forge-guide/references/forge-config-schema.json +2 -2
  190. package/adapters/cursor/skills/forge-guide/references/shared-conventions.md +12 -0
  191. package/adapters/cursor/skills/forge-guide/references/stacks/_generic.md +21 -0
  192. package/adapters/cursor/skills/forge-guide/references/stacks/go.md +19 -0
  193. package/adapters/cursor/skills/forge-guide/references/stacks/python.md +21 -0
  194. package/adapters/cursor/skills/forge-guide/references/stacks/rust.md +19 -0
  195. package/adapters/cursor/skills/forge-guide/references/stacks/typescript.md +23 -0
  196. package/adapters/cursor/skills/forge-verify/forge-verify.mdc +3 -3
  197. package/adapters/cursor/skills/forge-verify/references/shared-conventions.md +12 -0
  198. package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +82 -3
  199. package/adapters/gemini/.feature-forge-bundle.json +1 -1
  200. package/adapters/gemini/gemini-extension.json +1 -1
  201. package/adapters/gemini/references/epic-manifest-schema.json +5 -0
  202. package/adapters/gemini/references/forge-config-schema.json +2 -2
  203. package/adapters/gemini/references/shared-conventions.md +12 -0
  204. package/adapters/gemini/references/stacks/_generic.md +21 -0
  205. package/adapters/gemini/references/stacks/go.md +19 -0
  206. package/adapters/gemini/references/stacks/python.md +21 -0
  207. package/adapters/gemini/references/stacks/rust.md +19 -0
  208. package/adapters/gemini/references/stacks/typescript.md +23 -0
  209. package/adapters/gemini/scripts/epic-manifest.py +75 -5
  210. package/adapters/gemini/scripts/forge-root.sh +102 -14
  211. package/adapters/gemini/scripts/forge-session.py +68 -9
  212. package/adapters/gemini/skills/forge/references/shared-conventions.md +12 -0
  213. package/adapters/gemini/skills/forge-0-epic/references/shared-conventions.md +12 -0
  214. package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +2 -0
  215. package/adapters/gemini/skills/forge-1-prd/references/shared-conventions.md +12 -0
  216. package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +2 -0
  217. package/adapters/gemini/skills/forge-2-tech/references/shared-conventions.md +12 -0
  218. package/adapters/gemini/skills/forge-2-tech/references/stacks/_generic.md +21 -0
  219. package/adapters/gemini/skills/forge-2-tech/references/stacks/go.md +19 -0
  220. package/adapters/gemini/skills/forge-2-tech/references/stacks/python.md +21 -0
  221. package/adapters/gemini/skills/forge-2-tech/references/stacks/rust.md +19 -0
  222. package/adapters/gemini/skills/forge-2-tech/references/stacks/typescript.md +23 -0
  223. package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +2 -0
  224. package/adapters/gemini/skills/forge-3-specs/references/shared-conventions.md +12 -0
  225. package/adapters/gemini/skills/forge-3-specs/references/stacks/_generic.md +21 -0
  226. package/adapters/gemini/skills/forge-3-specs/references/stacks/go.md +19 -0
  227. package/adapters/gemini/skills/forge-3-specs/references/stacks/python.md +21 -0
  228. package/adapters/gemini/skills/forge-3-specs/references/stacks/rust.md +19 -0
  229. package/adapters/gemini/skills/forge-3-specs/references/stacks/typescript.md +23 -0
  230. package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +5 -0
  231. package/adapters/gemini/skills/forge-4-backlog/references/forge-config-schema.json +2 -2
  232. package/adapters/gemini/skills/forge-4-backlog/references/shared-conventions.md +12 -0
  233. package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +7 -9
  234. package/adapters/gemini/skills/forge-5-loop/references/forge-config-schema.json +2 -2
  235. package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +41 -0
  236. package/adapters/gemini/skills/forge-5-loop/references/shared-conventions.md +12 -0
  237. package/adapters/gemini/skills/forge-6-docs/references/shared-conventions.md +12 -0
  238. package/adapters/gemini/skills/forge-fix/references/shared-conventions.md +12 -0
  239. package/adapters/gemini/skills/forge-guide/references/forge-config-schema.json +2 -2
  240. package/adapters/gemini/skills/forge-guide/references/shared-conventions.md +12 -0
  241. package/adapters/gemini/skills/forge-guide/references/stacks/_generic.md +21 -0
  242. package/adapters/gemini/skills/forge-guide/references/stacks/go.md +19 -0
  243. package/adapters/gemini/skills/forge-guide/references/stacks/python.md +21 -0
  244. package/adapters/gemini/skills/forge-guide/references/stacks/rust.md +19 -0
  245. package/adapters/gemini/skills/forge-guide/references/stacks/typescript.md +23 -0
  246. package/adapters/gemini/skills/forge-verify/forge-verify.md +3 -3
  247. package/adapters/gemini/skills/forge-verify/references/shared-conventions.md +12 -0
  248. package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +82 -3
  249. package/adapters/pi/.feature-forge-bundle.json +6 -0
  250. package/adapters/pi/agents/forge-researcher.md +139 -0
  251. package/adapters/pi/agents/forge-spec-writer.md +116 -0
  252. package/adapters/pi/agents/forge-verifier.md +126 -0
  253. package/adapters/pi/extensions/ask-user-question/LICENSE +21 -0
  254. package/adapters/pi/extensions/ask-user-question/README.md +91 -0
  255. package/adapters/pi/extensions/ask-user-question/ask-user-question.ts +298 -0
  256. package/adapters/pi/extensions/ask-user-question/config.ts +78 -0
  257. package/adapters/pi/extensions/ask-user-question/events.ts +57 -0
  258. package/adapters/pi/extensions/ask-user-question/index.ts +61 -0
  259. package/adapters/pi/extensions/ask-user-question/locales/de.json +27 -0
  260. package/adapters/pi/extensions/ask-user-question/locales/en.json +27 -0
  261. package/adapters/pi/extensions/ask-user-question/locales/es.json +27 -0
  262. package/adapters/pi/extensions/ask-user-question/locales/fr.json +27 -0
  263. package/adapters/pi/extensions/ask-user-question/locales/pt-BR.json +27 -0
  264. package/adapters/pi/extensions/ask-user-question/locales/pt.json +27 -0
  265. package/adapters/pi/extensions/ask-user-question/locales/ru.json +27 -0
  266. package/adapters/pi/extensions/ask-user-question/locales/uk.json +27 -0
  267. package/adapters/pi/extensions/ask-user-question/locales/zh.json +29 -0
  268. package/adapters/pi/extensions/ask-user-question/reconcile.ts +49 -0
  269. package/adapters/pi/extensions/ask-user-question/rpc-fallback.ts +168 -0
  270. package/adapters/pi/extensions/ask-user-question/state/build-questionnaire.ts +302 -0
  271. package/adapters/pi/extensions/ask-user-question/state/i18n-bridge.ts +53 -0
  272. package/adapters/pi/extensions/ask-user-question/state/key-router.ts +277 -0
  273. package/adapters/pi/extensions/ask-user-question/state/questionnaire-session.ts +234 -0
  274. package/adapters/pi/extensions/ask-user-question/state/row-intent.ts +145 -0
  275. package/adapters/pi/extensions/ask-user-question/state/selectors/contract.ts +26 -0
  276. package/adapters/pi/extensions/ask-user-question/state/selectors/derivations.ts +42 -0
  277. package/adapters/pi/extensions/ask-user-question/state/selectors/focus.ts +19 -0
  278. package/adapters/pi/extensions/ask-user-question/state/selectors/projections.ts +101 -0
  279. package/adapters/pi/extensions/ask-user-question/state/state-reducer.ts +292 -0
  280. package/adapters/pi/extensions/ask-user-question/state/state.ts +55 -0
  281. package/adapters/pi/extensions/ask-user-question/tool/format-answer.ts +31 -0
  282. package/adapters/pi/extensions/ask-user-question/tool/response-envelope.ts +49 -0
  283. package/adapters/pi/extensions/ask-user-question/tool/types.ts +147 -0
  284. package/adapters/pi/extensions/ask-user-question/tool/validate-questionnaire.ts +58 -0
  285. package/adapters/pi/extensions/ask-user-question/vendor-config-shim.ts +65 -0
  286. package/adapters/pi/extensions/ask-user-question/view/component-binding.ts +47 -0
  287. package/adapters/pi/extensions/ask-user-question/view/components/inline-input.ts +98 -0
  288. package/adapters/pi/extensions/ask-user-question/view/components/multi-select-view.ts +193 -0
  289. package/adapters/pi/extensions/ask-user-question/view/components/option-list-view.ts +70 -0
  290. package/adapters/pi/extensions/ask-user-question/view/components/preview/markdown-content-cache.ts +79 -0
  291. package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-block-renderer.ts +111 -0
  292. package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-box-renderer.ts +88 -0
  293. package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-layout-decider.ts +202 -0
  294. package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-pane.ts +228 -0
  295. package/adapters/pi/extensions/ask-user-question/view/components/submit-picker.ts +67 -0
  296. package/adapters/pi/extensions/ask-user-question/view/components/tab-bar.ts +59 -0
  297. package/adapters/pi/extensions/ask-user-question/view/components/wrapping-select.ts +293 -0
  298. package/adapters/pi/extensions/ask-user-question/view/dialog-builder.ts +224 -0
  299. package/adapters/pi/extensions/ask-user-question/view/props-adapter.ts +125 -0
  300. package/adapters/pi/extensions/ask-user-question/view/stateful-view.ts +26 -0
  301. package/adapters/pi/extensions/ask-user-question/view/tab-components.ts +18 -0
  302. package/adapters/pi/extensions/ask-user-question/view/tab-content-strategy.ts +252 -0
  303. package/adapters/pi/package.json +26 -0
  304. package/adapters/pi/references/epic-manifest-schema.json +125 -0
  305. package/adapters/pi/references/forge-config-schema.json +236 -0
  306. package/adapters/pi/references/pipeline-state-schema.json +191 -0
  307. package/adapters/pi/references/portable-root.md +71 -0
  308. package/adapters/pi/references/process-overview.md +143 -0
  309. package/adapters/pi/references/ralph-loop-contract.md +221 -0
  310. package/adapters/pi/references/shared-conventions.md +295 -0
  311. package/adapters/pi/references/skill-frontmatter.schema.json +17 -0
  312. package/adapters/pi/references/stack-resolution.md +54 -0
  313. package/adapters/pi/references/stacks/_generic.md +111 -0
  314. package/adapters/pi/references/stacks/go.md +157 -0
  315. package/adapters/pi/references/stacks/python.md +184 -0
  316. package/adapters/pi/references/stacks/rust.md +170 -0
  317. package/adapters/pi/references/stacks/typescript.md +134 -0
  318. package/adapters/pi/references/stage-exit-protocol.md +258 -0
  319. package/adapters/pi/references/templates/specs-hygiene/AGENTS.md +32 -0
  320. package/adapters/pi/references/templates/specs-hygiene/CLAUDE.md +31 -0
  321. package/adapters/pi/references/vendor-construct-inventory.md +50 -0
  322. package/adapters/pi/scripts/epic-manifest.py +1694 -0
  323. package/adapters/pi/scripts/forge-bootstrap.py +1070 -0
  324. package/adapters/pi/scripts/forge-init.sh +58 -0
  325. package/adapters/pi/scripts/forge-root.sh +179 -0
  326. package/adapters/pi/scripts/forge-session.py +1888 -0
  327. package/adapters/pi/scripts/validate-traceability.py +150 -0
  328. package/adapters/pi/skills/forge/SKILL.md +243 -0
  329. package/adapters/pi/skills/forge/references/pipeline-state-schema.json +191 -0
  330. package/adapters/pi/skills/forge/references/process-overview.md +143 -0
  331. package/adapters/pi/skills/forge/references/shared-conventions.md +295 -0
  332. package/adapters/pi/skills/forge/references/stage-exit-protocol.md +258 -0
  333. package/adapters/pi/skills/forge-0-epic/SKILL.md +308 -0
  334. package/adapters/pi/skills/forge-0-epic/references/edit-mode.md +266 -0
  335. package/adapters/pi/skills/forge-0-epic/references/epic-manifest-subcommands.md +75 -0
  336. package/adapters/pi/skills/forge-0-epic/references/pipeline-state-schema.json +191 -0
  337. package/adapters/pi/skills/forge-0-epic/references/portable-root.md +71 -0
  338. package/adapters/pi/skills/forge-0-epic/references/shared-conventions.md +295 -0
  339. package/adapters/pi/skills/forge-0-epic/references/stage-exit-protocol.md +258 -0
  340. package/adapters/pi/skills/forge-1-prd/SKILL.md +164 -0
  341. package/adapters/pi/skills/forge-1-prd/references/pipeline-state-schema.json +191 -0
  342. package/adapters/pi/skills/forge-1-prd/references/prd-template.md +106 -0
  343. package/adapters/pi/skills/forge-1-prd/references/shared-conventions.md +295 -0
  344. package/adapters/pi/skills/forge-1-prd/references/stage-exit-protocol.md +258 -0
  345. package/adapters/pi/skills/forge-2-tech/SKILL.md +225 -0
  346. package/adapters/pi/skills/forge-2-tech/references/pipeline-state-schema.json +191 -0
  347. package/adapters/pi/skills/forge-2-tech/references/shared-conventions.md +295 -0
  348. package/adapters/pi/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
  349. package/adapters/pi/skills/forge-2-tech/references/stack-resolution.md +54 -0
  350. package/adapters/pi/skills/forge-2-tech/references/stacks/_generic.md +111 -0
  351. package/adapters/pi/skills/forge-2-tech/references/stacks/go.md +157 -0
  352. package/adapters/pi/skills/forge-2-tech/references/stacks/python.md +184 -0
  353. package/adapters/pi/skills/forge-2-tech/references/stacks/rust.md +170 -0
  354. package/adapters/pi/skills/forge-2-tech/references/stacks/typescript.md +134 -0
  355. package/adapters/pi/skills/forge-2-tech/references/stage-exit-protocol.md +258 -0
  356. package/adapters/pi/skills/forge-3-specs/SKILL.md +178 -0
  357. package/adapters/pi/skills/forge-3-specs/references/pipeline-state-schema.json +191 -0
  358. package/adapters/pi/skills/forge-3-specs/references/shared-conventions.md +295 -0
  359. package/adapters/pi/skills/forge-3-specs/references/spec-archetypes.md +106 -0
  360. package/adapters/pi/skills/forge-3-specs/references/spec-examples.md +71 -0
  361. package/adapters/pi/skills/forge-3-specs/references/stacks/_generic.md +111 -0
  362. package/adapters/pi/skills/forge-3-specs/references/stacks/go.md +157 -0
  363. package/adapters/pi/skills/forge-3-specs/references/stacks/python.md +184 -0
  364. package/adapters/pi/skills/forge-3-specs/references/stacks/rust.md +170 -0
  365. package/adapters/pi/skills/forge-3-specs/references/stacks/typescript.md +134 -0
  366. package/adapters/pi/skills/forge-3-specs/references/stage-exit-protocol.md +258 -0
  367. package/adapters/pi/skills/forge-4-backlog/SKILL.md +175 -0
  368. package/adapters/pi/skills/forge-4-backlog/references/forge-config-schema.json +236 -0
  369. package/adapters/pi/skills/forge-4-backlog/references/pipeline-state-schema.json +191 -0
  370. package/adapters/pi/skills/forge-4-backlog/references/shared-conventions.md +295 -0
  371. package/adapters/pi/skills/forge-4-backlog/references/stage-exit-protocol.md +258 -0
  372. package/adapters/pi/skills/forge-5-loop/SKILL.md +314 -0
  373. package/adapters/pi/skills/forge-5-loop/references/forge-config-schema.json +236 -0
  374. package/adapters/pi/skills/forge-5-loop/references/ralph-loop-contract.md +221 -0
  375. package/adapters/pi/skills/forge-5-loop/references/result-reporting.md +85 -0
  376. package/adapters/pi/skills/forge-5-loop/references/runner-contract.md +341 -0
  377. package/adapters/pi/skills/forge-5-loop/references/shared-conventions.md +295 -0
  378. package/adapters/pi/skills/forge-5-loop/references/stage-exit-protocol.md +258 -0
  379. package/adapters/pi/skills/forge-6-docs/SKILL.md +202 -0
  380. package/adapters/pi/skills/forge-6-docs/references/doc-conventions.md +126 -0
  381. package/adapters/pi/skills/forge-6-docs/references/pipeline-state-schema.json +191 -0
  382. package/adapters/pi/skills/forge-6-docs/references/shared-conventions.md +295 -0
  383. package/adapters/pi/skills/forge-bootstrap/SKILL.md +250 -0
  384. package/adapters/pi/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
  385. package/adapters/pi/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
  386. package/adapters/pi/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
  387. package/adapters/pi/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
  388. package/adapters/pi/skills/forge-bootstrap/references/templates/go/main.go +12 -0
  389. package/adapters/pi/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
  390. package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +35 -0
  391. package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +36 -0
  392. package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
  393. package/adapters/pi/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
  394. package/adapters/pi/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
  395. package/adapters/pi/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
  396. package/adapters/pi/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
  397. package/adapters/pi/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
  398. package/adapters/pi/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
  399. package/adapters/pi/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
  400. package/adapters/pi/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
  401. package/adapters/pi/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
  402. package/adapters/pi/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
  403. package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
  404. package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
  405. package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
  406. package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
  407. package/adapters/pi/skills/forge-fix/SKILL.md +98 -0
  408. package/adapters/pi/skills/forge-fix/references/shared-conventions.md +295 -0
  409. package/adapters/pi/skills/forge-fix/references/stage-exit-protocol.md +258 -0
  410. package/adapters/pi/skills/forge-guide/SKILL.md +192 -0
  411. package/adapters/pi/skills/forge-guide/references/forge-config-schema.json +236 -0
  412. package/adapters/pi/skills/forge-guide/references/process-overview.md +143 -0
  413. package/adapters/pi/skills/forge-guide/references/ralph-loop-contract.md +221 -0
  414. package/adapters/pi/skills/forge-guide/references/shared-conventions.md +295 -0
  415. package/adapters/pi/skills/forge-guide/references/stack-resolution.md +54 -0
  416. package/adapters/pi/skills/forge-guide/references/stacks/_generic.md +111 -0
  417. package/adapters/pi/skills/forge-guide/references/stacks/go.md +157 -0
  418. package/adapters/pi/skills/forge-guide/references/stacks/python.md +184 -0
  419. package/adapters/pi/skills/forge-guide/references/stacks/rust.md +170 -0
  420. package/adapters/pi/skills/forge-guide/references/stacks/typescript.md +134 -0
  421. package/adapters/pi/skills/forge-init/SKILL.md +72 -0
  422. package/adapters/pi/skills/forge-verify/SKILL.md +273 -0
  423. package/adapters/pi/skills/forge-verify/references/pipeline-state-schema.json +191 -0
  424. package/adapters/pi/skills/forge-verify/references/shared-conventions.md +295 -0
  425. package/adapters/pi/skills/forge-verify/references/verification-checklists.md +477 -0
  426. package/dist/agent-targets.d.ts +1 -1
  427. package/dist/agent-targets.js +23 -3
  428. package/dist/detect.d.ts +1 -1
  429. package/dist/detect.js +2 -1
  430. package/dist/manifest.d.ts +1 -1
  431. package/dist/manifest.js +2 -2
  432. package/dist/placements.js +5 -1
  433. package/dist/rauf.d.ts +4 -4
  434. package/dist/rauf.js +3 -3
  435. package/dist/types.d.ts +31 -6
  436. package/dist/types.js +6 -3
  437. package/package.json +14 -3
@@ -117,8 +117,20 @@ VERIFY_TOKEN_BY_STAGE: Final[dict[str, str]] = {
117
117
 
118
118
  #: A production stage status that counts as "done" for next-stage selection.
119
119
  _DONE_STATUS: Final = "complete"
120
- #: Verify statuses that count as "resolved" (no outstanding verify needed).
120
+ #: The authoritative forge-verify status vocabulary. SOURCE OF TRUTH:
121
+ #: references/pipeline-state-schema.json (definitions.verifyEntry.properties.status.enum).
122
+ #: A status outside this set is unrecognized and must not be silently interpreted (#148).
123
+ #: NOTE: epic-manifest.py keeps a byte-identical copy — flat, self-contained scripts have
124
+ #: no shared import module (each is copied verbatim into per-agent adapter bundles).
125
+ KNOWN_VERIFY_STATUSES: Final = frozenset(
126
+ {"pending", "passed", "findings-reported", "findings-applied", "skipped"}
127
+ )
128
+ #: Verify statuses that count as "resolved" (no outstanding verify needed). A STRICT
129
+ #: subset of KNOWN_VERIFY_STATUSES — not collapsible into it (different meaning).
121
130
  _VERIFY_RESOLVED: Final = frozenset({"passed", "findings-applied", "skipped"})
131
+ #: Per-process dedupe for the unknown-verify-status diagnostic (#148) so a single
132
+ #: bogus status is flagged once, not once per verify_state() call in a command.
133
+ _UNKNOWN_VERIFY_WARNED: set[str] = set()
122
134
 
123
135
  #: Default context window when the model can't be inferred and config is silent.
124
136
  _DEFAULT_WINDOW: Final = 200_000
@@ -257,6 +269,25 @@ def _verify_entry(state: dict, verify_key: str) -> dict:
257
269
  return entry if isinstance(entry, dict) else {}
258
270
 
259
271
 
272
+ def _warn_unknown_verify_status(stage_name: str, status: object) -> None:
273
+ """Emit a one-time stderr diagnostic for an out-of-vocabulary verify status (#148).
274
+
275
+ The freshness classifier maps an unrecognized status to "never verified" — correct,
276
+ but silent, so a typo poisons the downstream gate (e.g. forge-5-loop's dependency
277
+ check) with no clue. Flagging it here makes the bad value visible where it is read.
278
+ """
279
+ key = f"{stage_name}={status!r}"
280
+ if key in _UNKNOWN_VERIFY_WARNED:
281
+ return
282
+ _UNKNOWN_VERIFY_WARNED.add(key)
283
+ known = ", ".join(sorted(KNOWN_VERIFY_STATUSES))
284
+ print(
285
+ f"feature-forge: unknown {stage_name} status {status!r} "
286
+ f"(treated as unverified; expected one of {known})",
287
+ file=sys.stderr,
288
+ )
289
+
290
+
260
291
  def verify_state(state: dict) -> tuple[str | None, str]:
261
292
  """Classify verify freshness for the most-recently-completed stage.
262
293
 
@@ -299,6 +330,12 @@ def verify_state(state: dict) -> tuple[str | None, str]:
299
330
  if status not in _VERIFY_RESOLVED:
300
331
  if status == "findings-reported":
301
332
  return stage, "failing"
333
+ # An unrecognized status (outside KNOWN_VERIFY_STATUSES) is treated as
334
+ # "never verified" — defensible, but flag it once so a typo (e.g. the
335
+ # eye-slip 'findings-resolved') doesn't silently poison the gate that
336
+ # reads this label (#148). ``pending``/``None`` are known/absent → quiet.
337
+ if status is not None and status not in KNOWN_VERIFY_STATUSES:
338
+ _warn_unknown_verify_status(f"forge-verify-{token}", status)
302
339
  return stage, "never"
303
340
  verified_version = entry.get("verifiedStageVersion")
304
341
  stage_version = _stage_version(state, stage)
@@ -1397,6 +1434,17 @@ def _resolve_feature_dir(specs_dir: Path, feature: str, epic: str | None) -> Pat
1397
1434
  return flat
1398
1435
 
1399
1436
 
1437
+ def _host_command(command: str, host: str) -> str:
1438
+ """Rewrite a `/feature-forge:` slash command to the host's surface.
1439
+
1440
+ Pi's slash-command surface is `/skill:` (matching the adapter body's
1441
+ `/feature-forge:` -> `/skill:` translation). The scripted stage-exit output bypasses
1442
+ that body translation, so it rewrites the commands it emits here. No-op for
1443
+ claude/generic, which keep the canonical `/feature-forge:` form.
1444
+ """
1445
+ return command.replace("/feature-forge:", "/skill:") if host == "pi" else command
1446
+
1447
+
1400
1448
  def _next_steps_block(
1401
1449
  next_command: str, host: str, reconcile: dict | None = None
1402
1450
  ) -> str:
@@ -1426,6 +1474,18 @@ def _next_steps_block(
1426
1474
  "2. Then start a fresh session and run the next stage below — or "
1427
1475
  "re-run `/feature-forge:forge` to let the navigator resume from disk."
1428
1476
  )
1477
+ elif host == "pi":
1478
+ # Pi's fresh-session command is `/new` (not `/clear`); its slash-command
1479
+ # surface is `/skill:` (the fenced command below is rewritten to match).
1480
+ clear_line = (
1481
+ "1. `/new` — recommended unconditionally at this stage boundary; every "
1482
+ "artifact is on disk, so the work survives starting a fresh session. "
1483
+ "I can't run `/new` for you — you have to run it yourself."
1484
+ )
1485
+ next_line = (
1486
+ "2. Then, in the new session, run the next stage below — or re-run "
1487
+ "`/skill:forge` to let the navigator resume from disk."
1488
+ )
1429
1489
  else:
1430
1490
  clear_line = (
1431
1491
  "1. Clear your session / start a fresh session — recommended "
@@ -1442,7 +1502,7 @@ def _next_steps_block(
1442
1502
  # epic-change request the primary is the reconcile command; otherwise it is the
1443
1503
  # normal next-stage command. The fence sits before the sentinel, so the
1444
1504
  # sentinel remains the absolute last line.
1445
- fenced_command = reconcile["command"] if blocking else next_command
1505
+ fenced_command = _host_command(reconcile["command"] if blocking else next_command, host)
1446
1506
  lines = ["**Next steps**", clear_line]
1447
1507
  if blocking:
1448
1508
  count = reconcile["count"]
@@ -1458,15 +1518,14 @@ def _next_steps_block(
1458
1518
  lines.append("")
1459
1519
  lines.append(f"```\n{fenced_command}\n```")
1460
1520
  if blocking and reconcile.get("deferred"):
1461
- lines.append(
1462
- f"After reconciling, continue the pipeline with: `{reconcile['deferred']}`"
1463
- )
1521
+ deferred_cmd = _host_command(reconcile["deferred"], host)
1522
+ lines.append(f"After reconciling, continue the pipeline with: `{deferred_cmd}`")
1464
1523
  elif reconcile and reconcile.get("reminder"):
1465
1524
  count = reconcile["count"]
1466
1525
  plural = "s" if count != 1 else ""
1467
1526
  lines.append(
1468
1527
  f"You also flagged {count} epic change{plural} to reconcile when "
1469
- f"convenient: `{reconcile['command']}`"
1528
+ f"convenient: `{_host_command(reconcile['command'], host)}`"
1470
1529
  )
1471
1530
  lines.append(NEXT_STEPS_SENTINEL)
1472
1531
  return "\n".join(lines)
@@ -1593,10 +1652,10 @@ def stage_exit(
1593
1652
  "verifyGate": verify_gate,
1594
1653
  "autoFixEligible": auto_fix_eligible,
1595
1654
  "verifyState": verify_label,
1596
- "verifyCommand": f"/feature-forge:forge-verify {feature}",
1655
+ "verifyCommand": _host_command(f"/feature-forge:forge-verify {feature}", host),
1597
1656
  "autoVerifyEffective": effective_auto_verify,
1598
1657
  "nextStage": next_stage_id,
1599
- "nextCommand": next_command,
1658
+ "nextCommand": _host_command(next_command, host) if next_command else next_command,
1600
1659
  "invalidAutoVerifyKeys": invalid_auto_verify_keys(config),
1601
1660
  "gitRepo": git_repo,
1602
1661
  "cleanTree": clean_tree,
@@ -1722,7 +1781,7 @@ def main() -> int:
1722
1781
  p_exit.add_argument("--epic", default=None, help="Epic name for a nested member")
1723
1782
  p_exit.add_argument("--next-feature", default=None, dest="next_feature",
1724
1783
  help="First actionable feature (epic handoff next-command arg)")
1725
- p_exit.add_argument("--host", default="claude", choices=("claude", "generic"),
1784
+ p_exit.add_argument("--host", default="claude", choices=("claude", "generic", "pi"),
1726
1785
  help="Host wording for the NEXT-STEPS block")
1727
1786
  p_exit.add_argument("--json", action="store_true", dest="json_output")
1728
1787
 
@@ -274,6 +274,18 @@ This write is **left uncommitted**: it is staged and committed as part of this s
274
274
 
275
275
  **Incremental artifact tracking:** When a stage writes multiple files (e.g. forge-3-specs writing a suite of spec documents), update the `stages.{stage}.artifacts` array in `.pipeline-state.json` after writing each file — not just at stage completion. This is what makes the Interrupted inventory above precise about which files were successfully written.
276
276
 
277
+ ## Stage-Completion Re-check
278
+
279
+ Invoke this block **at the head of any post-entry step that writes a stage artifact or runs the Scripted Stage Exit** — the Stage-Entry Guard runs only once, at the top of the skill. A **resumed or pasted mid-stage instruction** (e.g. "continue {stage}: write TRACEABILITY.md, run the stage exit") enters *below* the entry guard, so nothing re-checks completion before it overwrites a committed artifact and re-fires a finished exit — data-destructive if followed literally. This re-check is the idempotency backstop for that path. `{stage}` is the invoking skill's id.
280
+
281
+ **Re-read** `stages.{stage}` in `{resolvedFeatureDir}/.pipeline-state.json`, then classify by **provenance** — a legitimate completion runs in the same session that applied this stage's Entry Stamp; a replayed continuation finds a finished stage it did not produce:
282
+
283
+ 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.
284
+
285
+ 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.
286
+
287
+ 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).
288
+
277
289
  ## Force Mode
278
290
 
279
291
  If the user passes `--force` as an argument, skip prerequisite validation with a warning:
@@ -274,6 +274,18 @@ This write is **left uncommitted**: it is staged and committed as part of this s
274
274
 
275
275
  **Incremental artifact tracking:** When a stage writes multiple files (e.g. forge-3-specs writing a suite of spec documents), update the `stages.{stage}.artifacts` array in `.pipeline-state.json` after writing each file — not just at stage completion. This is what makes the Interrupted inventory above precise about which files were successfully written.
276
276
 
277
+ ## Stage-Completion Re-check
278
+
279
+ Invoke this block **at the head of any post-entry step that writes a stage artifact or runs the Scripted Stage Exit** — the Stage-Entry Guard runs only once, at the top of the skill. A **resumed or pasted mid-stage instruction** (e.g. "continue {stage}: write TRACEABILITY.md, run the stage exit") enters *below* the entry guard, so nothing re-checks completion before it overwrites a committed artifact and re-fires a finished exit — data-destructive if followed literally. This re-check is the idempotency backstop for that path. `{stage}` is the invoking skill's id.
280
+
281
+ **Re-read** `stages.{stage}` in `{resolvedFeatureDir}/.pipeline-state.json`, then classify by **provenance** — a legitimate completion runs in the same session that applied this stage's Entry Stamp; a replayed continuation finds a finished stage it did not produce:
282
+
283
+ 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.
284
+
285
+ 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.
286
+
287
+ 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).
288
+
277
289
  ## Force Mode
278
290
 
279
291
  If the user passes `--force` as an argument, skip prerequisite validation with a warning:
@@ -122,6 +122,8 @@ Iterate until the user confirms the PRD is complete.
122
122
 
123
123
  ## Step 6: Update Pipeline State and Commit
124
124
 
125
+ Before writing state or running the stage exit, invoke the **Stage-Completion Re-check** block in `references/shared-conventions.md` with `{stage}` = `forge-1-prd` — a resumed mid-stage continuation must not overwrite a committed `PRD.md` or re-fire a finished exit.
126
+
125
127
  Write pipeline state conforming to `references/pipeline-state-schema.json`.
126
128
 
127
129
  1. Create or update `{resolvedFeatureDir}/.pipeline-state.json`:
@@ -274,6 +274,18 @@ This write is **left uncommitted**: it is staged and committed as part of this s
274
274
 
275
275
  **Incremental artifact tracking:** When a stage writes multiple files (e.g. forge-3-specs writing a suite of spec documents), update the `stages.{stage}.artifacts` array in `.pipeline-state.json` after writing each file — not just at stage completion. This is what makes the Interrupted inventory above precise about which files were successfully written.
276
276
 
277
+ ## Stage-Completion Re-check
278
+
279
+ Invoke this block **at the head of any post-entry step that writes a stage artifact or runs the Scripted Stage Exit** — the Stage-Entry Guard runs only once, at the top of the skill. A **resumed or pasted mid-stage instruction** (e.g. "continue {stage}: write TRACEABILITY.md, run the stage exit") enters *below* the entry guard, so nothing re-checks completion before it overwrites a committed artifact and re-fires a finished exit — data-destructive if followed literally. This re-check is the idempotency backstop for that path. `{stage}` is the invoking skill's id.
280
+
281
+ **Re-read** `stages.{stage}` in `{resolvedFeatureDir}/.pipeline-state.json`, then classify by **provenance** — a legitimate completion runs in the same session that applied this stage's Entry Stamp; a replayed continuation finds a finished stage it did not produce:
282
+
283
+ 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.
284
+
285
+ 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.
286
+
287
+ 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).
288
+
277
289
  ## Force Mode
278
290
 
279
291
  If the user passes `--force` as an argument, skip prerequisite validation with a warning:
@@ -184,6 +184,8 @@ Use `AskUserQuestion` to collect this feedback.
184
184
 
185
185
  ## Step 7: Update Pipeline State and Commit
186
186
 
187
+ Before writing state or running the stage exit, invoke the **Stage-Completion Re-check** block in `references/shared-conventions.md` with `{stage}` = `forge-2-tech` — a resumed mid-stage continuation must not overwrite a committed `tech-spec.md` or re-fire a finished exit.
188
+
187
189
  Write pipeline state conforming to `references/pipeline-state-schema.json`.
188
190
 
189
191
  1. Update `{resolvedFeatureDir}/.pipeline-state.json`:
@@ -274,6 +274,18 @@ This write is **left uncommitted**: it is staged and committed as part of this s
274
274
 
275
275
  **Incremental artifact tracking:** When a stage writes multiple files (e.g. forge-3-specs writing a suite of spec documents), update the `stages.{stage}.artifacts` array in `.pipeline-state.json` after writing each file — not just at stage completion. This is what makes the Interrupted inventory above precise about which files were successfully written.
276
276
 
277
+ ## Stage-Completion Re-check
278
+
279
+ Invoke this block **at the head of any post-entry step that writes a stage artifact or runs the Scripted Stage Exit** — the Stage-Entry Guard runs only once, at the top of the skill. A **resumed or pasted mid-stage instruction** (e.g. "continue {stage}: write TRACEABILITY.md, run the stage exit") enters *below* the entry guard, so nothing re-checks completion before it overwrites a committed artifact and re-fires a finished exit — data-destructive if followed literally. This re-check is the idempotency backstop for that path. `{stage}` is the invoking skill's id.
280
+
281
+ **Re-read** `stages.{stage}` in `{resolvedFeatureDir}/.pipeline-state.json`, then classify by **provenance** — a legitimate completion runs in the same session that applied this stage's Entry Stamp; a replayed continuation finds a finished stage it did not produce:
282
+
283
+ 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.
284
+
285
+ 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.
286
+
287
+ 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).
288
+
277
289
  ## Force Mode
278
290
 
279
291
  If the user passes `--force` as an argument, skip prerequisite validation with a warning:
@@ -79,6 +79,27 @@ Replace stack-specific checks with these generic equivalents:
79
79
  | "JSDoc on every field" | "Documentation comments on every field" |
80
80
  | "tsconfig.json extends root" | "Build configuration follows project conventions" |
81
81
 
82
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
83
+
84
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
85
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
86
+ Since no dedicated profile applies, identify these by role rather than exact filename:
87
+
88
+ - **Runtime entrypoints (a legitimate non-test call site):** the process/main entry the build's
89
+ run command actually launches (from the CI/`Makefile`/manifest "start" target), an HTTP/RPC handler
90
+ or route, a scheduled/worker task, or a CLI subcommand — **not** a file in the project's test
91
+ directory or matching its test-file convention.
92
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** any
93
+ module/hook the framework runs **once per process before serving** — a startup/lifecycle hook, an
94
+ import-time initializer, a global preload, or a shared test-setup module that bootstraps production
95
+ graphs. Side effects here run on every process start (and, under a dev/watch runtime, on every
96
+ reload).
97
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** database/ORM
98
+ clients and connection pools, message/queue clients, telemetry/observability SDKs, or a broad
99
+ whole-service-layer import. An init pulling any of these into a universal bootstrap entry is the
100
+ CHECK-I23 pattern — recommend lazy initialization at the first handler/worker that needs the graph,
101
+ not eagerly at process start.
102
+
82
103
  ## Acceptance Criteria Patterns
83
104
 
84
105
  Use these placeholder patterns in backlog items. Replace `{typeCheckCommand}`, `{testCommand}`, and `{module}` with values from `forge.config.json` and the project structure:
@@ -84,6 +84,25 @@ When examining a Go project, check for:
84
84
  - **Formatting**: `gofmt -l .` or `goimports -l .` (should produce no output)
85
85
  - **Module tidiness**: `go mod tidy` (ensures `go.mod` and `go.sum` are consistent)
86
86
 
87
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
88
+
89
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
90
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
91
+
92
+ - **Runtime entrypoints (a legitimate non-test call site):** `func main()` in a `package main` under
93
+ `cmd/…` or the module root, an HTTP handler registered on a `*http.ServeMux` / router, a gRPC service
94
+ registration, or a worker/consumer goroutine started from `main` — not a `*_test.go` file.
95
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** a package-level
96
+ `func init()` that constructs heavy clients, package-level `var` initializers that dial/connect at
97
+ import time, or a single `bootstrap`/`wire` module `main` calls before serving. `init()` and
98
+ package-var side effects run on **every** binary start, before `main` gets control.
99
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** DB drivers/pools
100
+ (`database/sql` + a driver, `pgx`, `gorm`, `mongo-driver`), message/queue clients (`sarama`/Kafka,
101
+ `amqp`, `go-redis`), telemetry SDKs (`go.opentelemetry.io/*`, `sentry-go`), or a broad internal
102
+ service package. An `init()` or package-var that dials any of these is the CHECK-I23 pattern —
103
+ recommend a `sync.Once` lazy constructor invoked from the first handler that needs it, not an
104
+ eager package-level connect.
105
+
87
106
  ## Testing
88
107
 
89
108
  - **Framework**: `testing` stdlib package
@@ -111,6 +111,27 @@ async def refresh_session_token(
111
111
  - **Import validation**: `mypy` with `--strict` or `--disallow-untyped-defs` catches missing type annotations
112
112
  - **Module export validation**: `__all__` lists in `__init__.py` match spec's public API
113
113
 
114
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
115
+
116
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
117
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
118
+
119
+ - **Runtime entrypoints (a legitimate non-test call site):** a `if __name__ == "__main__":` block, a
120
+ `[project.scripts]` console-script target in `pyproject.toml`, an ASGI/WSGI app object
121
+ (`app = FastAPI()` / Django `wsgi.py` / `asgi.py`), a route/view/handler, a Celery/RQ task module, or
122
+ a management command — not a `test_*.py` / `conftest.py`.
123
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** a package
124
+ `__init__.py` that eagerly instantiates heavy clients at import time, a framework startup hook
125
+ (FastAPI `lifespan` / `@app.on_event("startup")`, Django `AppConfig.ready()`, a Gunicorn/uvicorn
126
+ `--preload` module), or a `conftest.py` that bootstraps production graphs. Import-time side effects
127
+ here run on every process start.
128
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** DB/ORM engines
129
+ (`sqlalchemy.create_engine`, `psycopg`, Django ORM, `pymongo`, `redis`), task queues (`celery`,
130
+ `rq`, `kafka`), telemetry SDKs (`opentelemetry`, `sentry_sdk`), or a whole-service-layer package
131
+ import. An init pulling any of these at a universal entry is the CHECK-I23 pattern — recommend lazy
132
+ init (module-level `@lru_cache` factory, `Depends()` provider, or first-use lazy import) at the
133
+ handler that needs it.
134
+
114
135
  ## Testing
115
136
 
116
137
  - **Framework**: pytest (with `conftest.py` for fixtures)
@@ -90,6 +90,25 @@ When examining a Rust project, check for:
90
90
  - **Formatting**: `cargo fmt --check` (ensures code matches `rustfmt` style)
91
91
  - **Unsafe audit**: `cargo geiger` (if security-sensitive — counts unsafe blocks)
92
92
 
93
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
94
+
95
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
96
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
97
+
98
+ - **Runtime entrypoints (a legitimate non-test call site):** `fn main()` in `main.rs` or a `[[bin]]`
99
+ target, an async runtime entry (`#[tokio::main]`), an HTTP handler registered on an axum/actix/warp
100
+ router, or a worker task spawned from `main` — not a `#[cfg(test)]` module or a `tests/` integration
101
+ file.
102
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** a `lazy_static!`
103
+ / `once_cell::sync::Lazy` static that eagerly constructs heavy clients, a single `bootstrap`/`setup`
104
+ fn `main` calls before serving, or a `#[ctor]`-style pre-`main` initializer. A `Lazy` static is only
105
+ a risk when it is *forced* at startup rather than on first use.
106
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** DB pools
107
+ (`sqlx::Pool`, `diesel`, `deadpool`, `mongodb`), message/queue clients (`rdkafka`, `lapin`,
108
+ `redis`), telemetry SDKs (`opentelemetry`, `sentry`), or a broad internal service crate. Constructing
109
+ any of these eagerly at a universal entry is the CHECK-I23 pattern — recommend a `OnceCell`/`Lazy`
110
+ forced on **first use** by the handler that needs it, not at process start.
111
+
93
112
  ## Testing
94
113
 
95
114
  - **Framework**: Built-in test harness (`#[test]`, `#[cfg(test)]`)
@@ -64,6 +64,29 @@ When examining a TypeScript project, check for:
64
64
  - **Cross-package type checks**: `bun run typecheck` (or equivalent) passes for both the feature package AND packages that depend on it
65
65
  - **Import path validation**: All import paths resolve correctly per the `exports` map in `package.json`
66
66
 
67
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
68
+
69
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
70
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
71
+
72
+ - **Runtime entrypoints (a legitimate non-test call site):** a `package.json` `bin` / CLI `main`; a
73
+ server entry that actually starts listening (`src/server.ts`, `src/index.ts` invoking `listen`); a
74
+ worker/consumer file; and for Next.js — `middleware.ts`, `app/**/route.ts` route handlers,
75
+ `app/**/{page,layout,template}.tsx`, server actions, and `instrumentation.ts`. Express/Hono/Fastify:
76
+ the file that constructs the app and calls `.listen()`.
77
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** Next.js
78
+ `instrumentation.ts` / `instrumentation.js` (its `register()` runs once per server process before
79
+ any request), an app-server preload/`register`/`--import` hook, a root `app/layout.tsx` that
80
+ eagerly imports server singletons, and global test setup (`vitest.setup.ts`, `jest.setup.ts`) if it
81
+ bootstraps production graphs. Wiring a heavy init here loads it on **every** cold start (and, under
82
+ the dev server, on every module re-evaluation).
83
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** DB/ORM clients
84
+ (`drizzle-orm`, `@prisma/client`, `pg`, `mongoose`, `kysely`), queue/worker libs (`bullmq`, `bull`,
85
+ `kafkajs`, `ioredis`), telemetry/observability SDKs (`@opentelemetry/*`, `@sentry/node`), and a
86
+ whole-service-layer barrel (`import * as services from "@repo/services"`). An init that pulls any of
87
+ these into a universal bootstrap entry is the CHECK-I23 pattern — recommend lazy init at the first
88
+ route/handler/worker that needs it.
89
+
67
90
  ## Testing
68
91
 
69
92
  - **Framework**: Vitest (most common in modern TS), Jest, or testing-library
@@ -117,6 +117,8 @@ do not reload everything. This keeps quality up under context pressure.
117
117
 
118
118
  ## Step 5: Cross-Reference Validation
119
119
 
120
+ Before writing `TRACEABILITY.md` or running the stage exit, invoke the **Stage-Completion Re-check** block in `references/shared-conventions.md` with `{stage}` = `forge-3-specs` — a resumed mid-stage continuation must not overwrite a committed `TRACEABILITY.md` or re-fire a finished exit.
121
+
120
122
  After writing all documents, verify:
121
123
 
122
124
  1. Every PRD requirement has coverage in at least one spec document
@@ -274,6 +274,18 @@ This write is **left uncommitted**: it is staged and committed as part of this s
274
274
 
275
275
  **Incremental artifact tracking:** When a stage writes multiple files (e.g. forge-3-specs writing a suite of spec documents), update the `stages.{stage}.artifacts` array in `.pipeline-state.json` after writing each file — not just at stage completion. This is what makes the Interrupted inventory above precise about which files were successfully written.
276
276
 
277
+ ## Stage-Completion Re-check
278
+
279
+ Invoke this block **at the head of any post-entry step that writes a stage artifact or runs the Scripted Stage Exit** — the Stage-Entry Guard runs only once, at the top of the skill. A **resumed or pasted mid-stage instruction** (e.g. "continue {stage}: write TRACEABILITY.md, run the stage exit") enters *below* the entry guard, so nothing re-checks completion before it overwrites a committed artifact and re-fires a finished exit — data-destructive if followed literally. This re-check is the idempotency backstop for that path. `{stage}` is the invoking skill's id.
280
+
281
+ **Re-read** `stages.{stage}` in `{resolvedFeatureDir}/.pipeline-state.json`, then classify by **provenance** — a legitimate completion runs in the same session that applied this stage's Entry Stamp; a replayed continuation finds a finished stage it did not produce:
282
+
283
+ 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.
284
+
285
+ 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.
286
+
287
+ 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).
288
+
277
289
  ## Force Mode
278
290
 
279
291
  If the user passes `--force` as an argument, skip prerequisite validation with a warning:
@@ -79,6 +79,27 @@ Replace stack-specific checks with these generic equivalents:
79
79
  | "JSDoc on every field" | "Documentation comments on every field" |
80
80
  | "tsconfig.json extends root" | "Build configuration follows project conventions" |
81
81
 
82
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
83
+
84
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
85
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
86
+ Since no dedicated profile applies, identify these by role rather than exact filename:
87
+
88
+ - **Runtime entrypoints (a legitimate non-test call site):** the process/main entry the build's
89
+ run command actually launches (from the CI/`Makefile`/manifest "start" target), an HTTP/RPC handler
90
+ or route, a scheduled/worker task, or a CLI subcommand — **not** a file in the project's test
91
+ directory or matching its test-file convention.
92
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** any
93
+ module/hook the framework runs **once per process before serving** — a startup/lifecycle hook, an
94
+ import-time initializer, a global preload, or a shared test-setup module that bootstraps production
95
+ graphs. Side effects here run on every process start (and, under a dev/watch runtime, on every
96
+ reload).
97
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** database/ORM
98
+ clients and connection pools, message/queue clients, telemetry/observability SDKs, or a broad
99
+ whole-service-layer import. An init pulling any of these into a universal bootstrap entry is the
100
+ CHECK-I23 pattern — recommend lazy initialization at the first handler/worker that needs the graph,
101
+ not eagerly at process start.
102
+
82
103
  ## Acceptance Criteria Patterns
83
104
 
84
105
  Use these placeholder patterns in backlog items. Replace `{typeCheckCommand}`, `{testCommand}`, and `{module}` with values from `forge.config.json` and the project structure:
@@ -84,6 +84,25 @@ When examining a Go project, check for:
84
84
  - **Formatting**: `gofmt -l .` or `goimports -l .` (should produce no output)
85
85
  - **Module tidiness**: `go mod tidy` (ensures `go.mod` and `go.sum` are consistent)
86
86
 
87
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
88
+
89
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
90
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
91
+
92
+ - **Runtime entrypoints (a legitimate non-test call site):** `func main()` in a `package main` under
93
+ `cmd/…` or the module root, an HTTP handler registered on a `*http.ServeMux` / router, a gRPC service
94
+ registration, or a worker/consumer goroutine started from `main` — not a `*_test.go` file.
95
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** a package-level
96
+ `func init()` that constructs heavy clients, package-level `var` initializers that dial/connect at
97
+ import time, or a single `bootstrap`/`wire` module `main` calls before serving. `init()` and
98
+ package-var side effects run on **every** binary start, before `main` gets control.
99
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** DB drivers/pools
100
+ (`database/sql` + a driver, `pgx`, `gorm`, `mongo-driver`), message/queue clients (`sarama`/Kafka,
101
+ `amqp`, `go-redis`), telemetry SDKs (`go.opentelemetry.io/*`, `sentry-go`), or a broad internal
102
+ service package. An `init()` or package-var that dials any of these is the CHECK-I23 pattern —
103
+ recommend a `sync.Once` lazy constructor invoked from the first handler that needs it, not an
104
+ eager package-level connect.
105
+
87
106
  ## Testing
88
107
 
89
108
  - **Framework**: `testing` stdlib package
@@ -111,6 +111,27 @@ async def refresh_session_token(
111
111
  - **Import validation**: `mypy` with `--strict` or `--disallow-untyped-defs` catches missing type annotations
112
112
  - **Module export validation**: `__all__` lists in `__init__.py` match spec's public API
113
113
 
114
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
115
+
116
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
117
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
118
+
119
+ - **Runtime entrypoints (a legitimate non-test call site):** a `if __name__ == "__main__":` block, a
120
+ `[project.scripts]` console-script target in `pyproject.toml`, an ASGI/WSGI app object
121
+ (`app = FastAPI()` / Django `wsgi.py` / `asgi.py`), a route/view/handler, a Celery/RQ task module, or
122
+ a management command — not a `test_*.py` / `conftest.py`.
123
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** a package
124
+ `__init__.py` that eagerly instantiates heavy clients at import time, a framework startup hook
125
+ (FastAPI `lifespan` / `@app.on_event("startup")`, Django `AppConfig.ready()`, a Gunicorn/uvicorn
126
+ `--preload` module), or a `conftest.py` that bootstraps production graphs. Import-time side effects
127
+ here run on every process start.
128
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** DB/ORM engines
129
+ (`sqlalchemy.create_engine`, `psycopg`, Django ORM, `pymongo`, `redis`), task queues (`celery`,
130
+ `rq`, `kafka`), telemetry SDKs (`opentelemetry`, `sentry_sdk`), or a whole-service-layer package
131
+ import. An init pulling any of these at a universal entry is the CHECK-I23 pattern — recommend lazy
132
+ init (module-level `@lru_cache` factory, `Depends()` provider, or first-use lazy import) at the
133
+ handler that needs it.
134
+
114
135
  ## Testing
115
136
 
116
137
  - **Framework**: pytest (with `conftest.py` for fixtures)
@@ -90,6 +90,25 @@ When examining a Rust project, check for:
90
90
  - **Formatting**: `cargo fmt --check` (ensures code matches `rustfmt` style)
91
91
  - **Unsafe audit**: `cargo geiger` (if security-sensitive — counts unsafe blocks)
92
92
 
93
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
94
+
95
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
96
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
97
+
98
+ - **Runtime entrypoints (a legitimate non-test call site):** `fn main()` in `main.rs` or a `[[bin]]`
99
+ target, an async runtime entry (`#[tokio::main]`), an HTTP handler registered on an axum/actix/warp
100
+ router, or a worker task spawned from `main` — not a `#[cfg(test)]` module or a `tests/` integration
101
+ file.
102
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** a `lazy_static!`
103
+ / `once_cell::sync::Lazy` static that eagerly constructs heavy clients, a single `bootstrap`/`setup`
104
+ fn `main` calls before serving, or a `#[ctor]`-style pre-`main` initializer. A `Lazy` static is only
105
+ a risk when it is *forced* at startup rather than on first use.
106
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** DB pools
107
+ (`sqlx::Pool`, `diesel`, `deadpool`, `mongodb`), message/queue clients (`rdkafka`, `lapin`,
108
+ `redis`), telemetry SDKs (`opentelemetry`, `sentry`), or a broad internal service crate. Constructing
109
+ any of these eagerly at a universal entry is the CHECK-I23 pattern — recommend a `OnceCell`/`Lazy`
110
+ forced on **first use** by the handler that needs it, not at process start.
111
+
93
112
  ## Testing
94
113
 
95
114
  - **Framework**: Built-in test harness (`#[test]`, `#[cfg(test)]`)
@@ -64,6 +64,29 @@ When examining a TypeScript project, check for:
64
64
  - **Cross-package type checks**: `bun run typecheck` (or equivalent) passes for both the feature package AND packages that depend on it
65
65
  - **Import path validation**: All import paths resolve correctly per the `exports` map in `package.json`
66
66
 
67
+ ### Runtime Entrypoints & Bootstrap-Wiring Sites
68
+
69
+ Used by `CHECK-I22` (a runtime-required bootstrap needs a **non-test** caller on one of these) and
70
+ `CHECK-I23` (a heavy init wired into a **universal** bootstrap entry should move to a lazier site).
71
+
72
+ - **Runtime entrypoints (a legitimate non-test call site):** a `package.json` `bin` / CLI `main`; a
73
+ server entry that actually starts listening (`src/server.ts`, `src/index.ts` invoking `listen`); a
74
+ worker/consumer file; and for Next.js — `middleware.ts`, `app/**/route.ts` route handlers,
75
+ `app/**/{page,layout,template}.tsx`, server actions, and `instrumentation.ts`. Express/Hono/Fastify:
76
+ the file that constructs the app and calls `.listen()`.
77
+ - **Universal bootstrap entries (run on every startup — the `CHECK-I23` risk site):** Next.js
78
+ `instrumentation.ts` / `instrumentation.js` (its `register()` runs once per server process before
79
+ any request), an app-server preload/`register`/`--import` hook, a root `app/layout.tsx` that
80
+ eagerly imports server singletons, and global test setup (`vitest.setup.ts`, `jest.setup.ts`) if it
81
+ bootstraps production graphs. Wiring a heavy init here loads it on **every** cold start (and, under
82
+ the dev server, on every module re-evaluation).
83
+ - **Heavy server-only import markers (what makes an init "heavy" for `CHECK-I23`):** DB/ORM clients
84
+ (`drizzle-orm`, `@prisma/client`, `pg`, `mongoose`, `kysely`), queue/worker libs (`bullmq`, `bull`,
85
+ `kafkajs`, `ioredis`), telemetry/observability SDKs (`@opentelemetry/*`, `@sentry/node`), and a
86
+ whole-service-layer barrel (`import * as services from "@repo/services"`). An init that pulls any of
87
+ these into a universal bootstrap entry is the CHECK-I23 pattern — recommend lazy init at the first
88
+ route/handler/worker that needs it.
89
+
67
90
  ## Testing
68
91
 
69
92
  - **Framework**: Vitest (most common in modern TS), Jest, or testing-library
@@ -94,6 +94,9 @@ After presenting the plan as text, use `AskUserQuestion` following the **Decisio
94
94
 
95
95
  **Forge-specific item requirements** layered on top of `author-backlog`'s output:
96
96
  - `specReferences` must be paths **relative to the project root** (e.g. `specs/auth/00-core-definitions.md`), NOT relative to the backlog file. The validator resolves them from the project root (not from `--specs-dir`, which only gates the check).
97
+ - **Epic members — cross-member shared-state coupling (#144).** When authoring the backlog for an epic member, check whether this feature writes or migrates a file that a *sibling* member's already-shipped tests pin (its `mutatesShared[]` hint in `epic-manifest.json`, or a shared data corpus / generated fixture its specs say it mutates). If so, schedule a **reconciliation item up front** — before the first mutating item — that regenerates or re-pins the sibling's fixture (or updates the sibling test to the new shape), so the sibling suite stays green instead of red-gating every commit mid-loop. This is the authoring counterpart to forge-verify's CHECK-E10.
98
+ - **Generated-artifact freshness vs. `testCommand` `--check` gates (#145).** If the project's `testCommand` gates on staleness of generated artifacts (`<generator> --check`-style sub-commands that fail when a checked-in generated file is out of date), then any item that regenerates **one** such artifact must regenerate **and commit all** the sibling artifacts those `--check` gates depend on — enumerate the whole gated set, not just the artifact the item is "about", or the item passes locally yet red-gates on the stale-generated check. Pass this to `author-backlog` alongside `testCommand` so the full regeneration sequence lands in each affected item; forge-verify's CHECK-B26 flags a partial set or an ungated regenerator after the fact.
99
+ - **Lifecycle-gated artifacts — no test item forcing a forbidden transition (#150).** A test/e2e item whose acceptance asserts a *published / released / approved / human-reviewed* artifact state must either (a) `dependsOn` an explicit, human-gated publish/review item that legitimately produces that state, or (b) assert the state via a **dev-build / fixture path**. A test item must **never** be the only thing forcing a lifecycle transition another item pins the other way (e.g. one item keeps artifact `X` *draft* while a test demands it *published*, with nothing between to publish it) — the loop, unable to publish or obtain a human sign-off, will **fabricate** the provenance. `author-backlog` owns the general rule; forge-verify's CHECK-B27 flags a contradictory pair with no publisher in the dependency closure after the fact.
97
100
 
98
101
  > **Backlog schema & rauf contract are unchanged (REQ-COMPAT-03).** Epic membership adds **no** fields to backlog items — dependency edges live in the epic manifest, never in any backlog item. The JSON written here is byte-for-byte the same shape as a pre-epic standalone feature's backlog, and rauf is still launched against a single per-feature backlog path. Only the *path composition* changes (the `{feature}` segment in the backlog-directory rule above), not the schema or rauf's CLI surface.
99
102
 
@@ -131,6 +134,8 @@ State that the backlog is ready and invite adjustments before committing — a s
131
134
 
132
135
  ## Step 7: Update Pipeline State and Commit
133
136
 
137
+ Before writing state or running the stage exit, invoke the **Stage-Completion Re-check** block in `references/shared-conventions.md` with `{stage}` = `forge-4-backlog` — a resumed mid-stage continuation must not overwrite a committed `backlog.json` or re-fire a finished exit.
138
+
134
139
  Write pipeline state conforming to `references/pipeline-state-schema.json`. Follow the Git Commit Protocol in `references/shared-conventions.md`.
135
140
 
136
141
  1. Update `{resolvedFeatureDir}/.pipeline-state.json`:
@@ -217,8 +217,8 @@
217
217
  },
218
218
  "installHint": {
219
219
  "type": "string",
220
- "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.12.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.12.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
221
- "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.12.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
220
+ "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.13.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.13.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
221
+ "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.13.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
222
222
  },
223
223
  "schemaVersion": {
224
224
  "type": "string",