@garygentry/feature-forge 0.1.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 (231) hide show
  1. package/LICENSE +21 -0
  2. package/adapters/GENERATION-REPORT.md +128 -0
  3. package/adapters/claude/agents/forge-researcher.md +137 -0
  4. package/adapters/claude/agents/forge-spec-writer.md +115 -0
  5. package/adapters/claude/agents/forge-verifier.md +121 -0
  6. package/adapters/claude/references/epic-manifest-schema.json +120 -0
  7. package/adapters/claude/references/forge-config-schema.json +166 -0
  8. package/adapters/claude/references/pipeline-state-schema.json +110 -0
  9. package/adapters/claude/references/portable-root.md +56 -0
  10. package/adapters/claude/references/process-overview.md +123 -0
  11. package/adapters/claude/references/ralph-loop-contract.md +221 -0
  12. package/adapters/claude/references/shared-conventions.md +144 -0
  13. package/adapters/claude/references/skill-frontmatter.schema.json +17 -0
  14. package/adapters/claude/references/stack-resolution.md +51 -0
  15. package/adapters/claude/references/stacks/_generic.md +90 -0
  16. package/adapters/claude/references/stacks/go.md +138 -0
  17. package/adapters/claude/references/stacks/python.md +163 -0
  18. package/adapters/claude/references/stacks/rust.md +151 -0
  19. package/adapters/claude/references/stacks/typescript.md +111 -0
  20. package/adapters/claude/references/vendor-construct-inventory.md +49 -0
  21. package/adapters/claude/scripts/forge-root.sh +50 -0
  22. package/adapters/claude/skills/forge/SKILL.md +165 -0
  23. package/adapters/claude/skills/forge-0-epic/SKILL.md +303 -0
  24. package/adapters/claude/skills/forge-0-epic/references/edit-mode.md +222 -0
  25. package/adapters/claude/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
  26. package/adapters/claude/skills/forge-1-prd/SKILL.md +121 -0
  27. package/adapters/claude/skills/forge-1-prd/references/prd-template.md +106 -0
  28. package/adapters/claude/skills/forge-2-tech/SKILL.md +198 -0
  29. package/adapters/claude/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
  30. package/adapters/claude/skills/forge-3-specs/SKILL.md +154 -0
  31. package/adapters/claude/skills/forge-3-specs/references/spec-archetypes.md +106 -0
  32. package/adapters/claude/skills/forge-3-specs/references/spec-examples.md +71 -0
  33. package/adapters/claude/skills/forge-4-backlog/SKILL.md +146 -0
  34. package/adapters/claude/skills/forge-5-loop/SKILL.md +303 -0
  35. package/adapters/claude/skills/forge-5-loop/references/result-reporting.md +63 -0
  36. package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +214 -0
  37. package/adapters/claude/skills/forge-6-docs/SKILL.md +179 -0
  38. package/adapters/claude/skills/forge-6-docs/references/doc-conventions.md +126 -0
  39. package/adapters/claude/skills/forge-fix/SKILL.md +65 -0
  40. package/adapters/claude/skills/forge-init/SKILL.md +29 -0
  41. package/adapters/claude/skills/forge-verify/SKILL.md +219 -0
  42. package/adapters/claude/skills/forge-verify/references/verification-checklists.md +379 -0
  43. package/adapters/codex/agents/forge-researcher.md +133 -0
  44. package/adapters/codex/agents/forge-spec-writer.md +112 -0
  45. package/adapters/codex/agents/forge-verifier.md +115 -0
  46. package/adapters/codex/agents/openai.yaml +10 -0
  47. package/adapters/codex/references/epic-manifest-schema.json +120 -0
  48. package/adapters/codex/references/forge-config-schema.json +166 -0
  49. package/adapters/codex/references/pipeline-state-schema.json +110 -0
  50. package/adapters/codex/references/portable-root.md +56 -0
  51. package/adapters/codex/references/process-overview.md +123 -0
  52. package/adapters/codex/references/ralph-loop-contract.md +221 -0
  53. package/adapters/codex/references/shared-conventions.md +144 -0
  54. package/adapters/codex/references/skill-frontmatter.schema.json +17 -0
  55. package/adapters/codex/references/stack-resolution.md +51 -0
  56. package/adapters/codex/references/stacks/_generic.md +90 -0
  57. package/adapters/codex/references/stacks/go.md +138 -0
  58. package/adapters/codex/references/stacks/python.md +163 -0
  59. package/adapters/codex/references/stacks/rust.md +151 -0
  60. package/adapters/codex/references/stacks/typescript.md +111 -0
  61. package/adapters/codex/references/vendor-construct-inventory.md +49 -0
  62. package/adapters/codex/scripts/forge-root.sh +50 -0
  63. package/adapters/codex/skills/forge/forge.md +164 -0
  64. package/adapters/codex/skills/forge-0-epic/forge-0-epic.md +302 -0
  65. package/adapters/codex/skills/forge-0-epic/references/edit-mode.md +222 -0
  66. package/adapters/codex/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
  67. package/adapters/codex/skills/forge-1-prd/forge-1-prd.md +120 -0
  68. package/adapters/codex/skills/forge-1-prd/references/prd-template.md +106 -0
  69. package/adapters/codex/skills/forge-2-tech/forge-2-tech.md +197 -0
  70. package/adapters/codex/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
  71. package/adapters/codex/skills/forge-3-specs/forge-3-specs.md +153 -0
  72. package/adapters/codex/skills/forge-3-specs/references/spec-archetypes.md +106 -0
  73. package/adapters/codex/skills/forge-3-specs/references/spec-examples.md +71 -0
  74. package/adapters/codex/skills/forge-4-backlog/forge-4-backlog.md +145 -0
  75. package/adapters/codex/skills/forge-5-loop/forge-5-loop.md +302 -0
  76. package/adapters/codex/skills/forge-5-loop/references/result-reporting.md +63 -0
  77. package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +214 -0
  78. package/adapters/codex/skills/forge-6-docs/forge-6-docs.md +178 -0
  79. package/adapters/codex/skills/forge-6-docs/references/doc-conventions.md +126 -0
  80. package/adapters/codex/skills/forge-fix/forge-fix.md +64 -0
  81. package/adapters/codex/skills/forge-init/forge-init.md +29 -0
  82. package/adapters/codex/skills/forge-verify/forge-verify.md +218 -0
  83. package/adapters/codex/skills/forge-verify/references/verification-checklists.md +379 -0
  84. package/adapters/copilot/agents/forge-researcher.md +133 -0
  85. package/adapters/copilot/agents/forge-spec-writer.md +112 -0
  86. package/adapters/copilot/agents/forge-verifier.md +115 -0
  87. package/adapters/copilot/references/epic-manifest-schema.json +120 -0
  88. package/adapters/copilot/references/forge-config-schema.json +166 -0
  89. package/adapters/copilot/references/pipeline-state-schema.json +110 -0
  90. package/adapters/copilot/references/portable-root.md +56 -0
  91. package/adapters/copilot/references/process-overview.md +123 -0
  92. package/adapters/copilot/references/ralph-loop-contract.md +221 -0
  93. package/adapters/copilot/references/shared-conventions.md +144 -0
  94. package/adapters/copilot/references/skill-frontmatter.schema.json +17 -0
  95. package/adapters/copilot/references/stack-resolution.md +51 -0
  96. package/adapters/copilot/references/stacks/_generic.md +90 -0
  97. package/adapters/copilot/references/stacks/go.md +138 -0
  98. package/adapters/copilot/references/stacks/python.md +163 -0
  99. package/adapters/copilot/references/stacks/rust.md +151 -0
  100. package/adapters/copilot/references/stacks/typescript.md +111 -0
  101. package/adapters/copilot/references/vendor-construct-inventory.md +49 -0
  102. package/adapters/copilot/scripts/forge-root.sh +50 -0
  103. package/adapters/copilot/skills/forge/forge.md +164 -0
  104. package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +302 -0
  105. package/adapters/copilot/skills/forge-0-epic/references/edit-mode.md +222 -0
  106. package/adapters/copilot/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
  107. package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +120 -0
  108. package/adapters/copilot/skills/forge-1-prd/references/prd-template.md +106 -0
  109. package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +197 -0
  110. package/adapters/copilot/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
  111. package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +153 -0
  112. package/adapters/copilot/skills/forge-3-specs/references/spec-archetypes.md +106 -0
  113. package/adapters/copilot/skills/forge-3-specs/references/spec-examples.md +71 -0
  114. package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +145 -0
  115. package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +302 -0
  116. package/adapters/copilot/skills/forge-5-loop/references/result-reporting.md +63 -0
  117. package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +214 -0
  118. package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +178 -0
  119. package/adapters/copilot/skills/forge-6-docs/references/doc-conventions.md +126 -0
  120. package/adapters/copilot/skills/forge-fix/forge-fix.md +64 -0
  121. package/adapters/copilot/skills/forge-init/forge-init.md +29 -0
  122. package/adapters/copilot/skills/forge-verify/forge-verify.md +218 -0
  123. package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +379 -0
  124. package/adapters/cursor/agents/forge-researcher.mdc +134 -0
  125. package/adapters/cursor/agents/forge-spec-writer.mdc +113 -0
  126. package/adapters/cursor/agents/forge-verifier.mdc +116 -0
  127. package/adapters/cursor/references/epic-manifest-schema.json +120 -0
  128. package/adapters/cursor/references/forge-config-schema.json +166 -0
  129. package/adapters/cursor/references/pipeline-state-schema.json +110 -0
  130. package/adapters/cursor/references/portable-root.md +56 -0
  131. package/adapters/cursor/references/process-overview.md +123 -0
  132. package/adapters/cursor/references/ralph-loop-contract.md +221 -0
  133. package/adapters/cursor/references/shared-conventions.md +144 -0
  134. package/adapters/cursor/references/skill-frontmatter.schema.json +17 -0
  135. package/adapters/cursor/references/stack-resolution.md +51 -0
  136. package/adapters/cursor/references/stacks/_generic.md +90 -0
  137. package/adapters/cursor/references/stacks/go.md +138 -0
  138. package/adapters/cursor/references/stacks/python.md +163 -0
  139. package/adapters/cursor/references/stacks/rust.md +151 -0
  140. package/adapters/cursor/references/stacks/typescript.md +111 -0
  141. package/adapters/cursor/references/vendor-construct-inventory.md +49 -0
  142. package/adapters/cursor/scripts/forge-root.sh +50 -0
  143. package/adapters/cursor/skills/forge/forge.mdc +165 -0
  144. package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +303 -0
  145. package/adapters/cursor/skills/forge-0-epic/references/edit-mode.md +222 -0
  146. package/adapters/cursor/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
  147. package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +121 -0
  148. package/adapters/cursor/skills/forge-1-prd/references/prd-template.md +106 -0
  149. package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +198 -0
  150. package/adapters/cursor/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
  151. package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +154 -0
  152. package/adapters/cursor/skills/forge-3-specs/references/spec-archetypes.md +106 -0
  153. package/adapters/cursor/skills/forge-3-specs/references/spec-examples.md +71 -0
  154. package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +146 -0
  155. package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +303 -0
  156. package/adapters/cursor/skills/forge-5-loop/references/result-reporting.md +63 -0
  157. package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +214 -0
  158. package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +179 -0
  159. package/adapters/cursor/skills/forge-6-docs/references/doc-conventions.md +126 -0
  160. package/adapters/cursor/skills/forge-fix/forge-fix.mdc +65 -0
  161. package/adapters/cursor/skills/forge-init/forge-init.mdc +30 -0
  162. package/adapters/cursor/skills/forge-verify/forge-verify.mdc +219 -0
  163. package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +379 -0
  164. package/adapters/gemini/agents/forge-researcher.md +133 -0
  165. package/adapters/gemini/agents/forge-spec-writer.md +112 -0
  166. package/adapters/gemini/agents/forge-verifier.md +115 -0
  167. package/adapters/gemini/gemini-extension.json +54 -0
  168. package/adapters/gemini/references/epic-manifest-schema.json +120 -0
  169. package/adapters/gemini/references/forge-config-schema.json +166 -0
  170. package/adapters/gemini/references/pipeline-state-schema.json +110 -0
  171. package/adapters/gemini/references/portable-root.md +56 -0
  172. package/adapters/gemini/references/process-overview.md +123 -0
  173. package/adapters/gemini/references/ralph-loop-contract.md +221 -0
  174. package/adapters/gemini/references/shared-conventions.md +144 -0
  175. package/adapters/gemini/references/skill-frontmatter.schema.json +17 -0
  176. package/adapters/gemini/references/stack-resolution.md +51 -0
  177. package/adapters/gemini/references/stacks/_generic.md +90 -0
  178. package/adapters/gemini/references/stacks/go.md +138 -0
  179. package/adapters/gemini/references/stacks/python.md +163 -0
  180. package/adapters/gemini/references/stacks/rust.md +151 -0
  181. package/adapters/gemini/references/stacks/typescript.md +111 -0
  182. package/adapters/gemini/references/vendor-construct-inventory.md +49 -0
  183. package/adapters/gemini/scripts/forge-root.sh +50 -0
  184. package/adapters/gemini/skills/forge/forge.md +164 -0
  185. package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +302 -0
  186. package/adapters/gemini/skills/forge-0-epic/references/edit-mode.md +222 -0
  187. package/adapters/gemini/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
  188. package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +120 -0
  189. package/adapters/gemini/skills/forge-1-prd/references/prd-template.md +106 -0
  190. package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +197 -0
  191. package/adapters/gemini/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
  192. package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +153 -0
  193. package/adapters/gemini/skills/forge-3-specs/references/spec-archetypes.md +106 -0
  194. package/adapters/gemini/skills/forge-3-specs/references/spec-examples.md +71 -0
  195. package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +145 -0
  196. package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +302 -0
  197. package/adapters/gemini/skills/forge-5-loop/references/result-reporting.md +63 -0
  198. package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +214 -0
  199. package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +178 -0
  200. package/adapters/gemini/skills/forge-6-docs/references/doc-conventions.md +126 -0
  201. package/adapters/gemini/skills/forge-fix/forge-fix.md +64 -0
  202. package/adapters/gemini/skills/forge-init/forge-init.md +29 -0
  203. package/adapters/gemini/skills/forge-verify/forge-verify.md +218 -0
  204. package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +379 -0
  205. package/dist/agent-targets.d.ts +70 -0
  206. package/dist/agent-targets.js +111 -0
  207. package/dist/apply.d.ts +49 -0
  208. package/dist/apply.js +246 -0
  209. package/dist/cli.d.ts +94 -0
  210. package/dist/cli.js +508 -0
  211. package/dist/detect.d.ts +45 -0
  212. package/dist/detect.js +72 -0
  213. package/dist/fsutil.d.ts +56 -0
  214. package/dist/fsutil.js +175 -0
  215. package/dist/hash.d.ts +50 -0
  216. package/dist/hash.js +107 -0
  217. package/dist/index.d.ts +8 -0
  218. package/dist/index.js +9 -0
  219. package/dist/manifest.d.ts +72 -0
  220. package/dist/manifest.js +222 -0
  221. package/dist/plan.d.ts +66 -0
  222. package/dist/plan.js +166 -0
  223. package/dist/rauf.d.ts +83 -0
  224. package/dist/rauf.js +118 -0
  225. package/dist/report.d.ts +35 -0
  226. package/dist/report.js +110 -0
  227. package/dist/source.d.ts +69 -0
  228. package/dist/source.js +164 -0
  229. package/dist/types.d.ts +264 -0
  230. package/dist/types.js +57 -0
  231. package/package.json +42 -0
@@ -0,0 +1,303 @@
1
+ ---
2
+ # GENERATED — DO NOT EDIT. Source: skills/forge-0-epic/SKILL.md. Regenerate: python3 scripts/build-adapters.py
3
+ description: 'Create or edit a forge epic: decompose a large change into discrete member features with dependencies, charters, and structured contracts, producing epic-manifest.json + EPIC.md. Re-run on an existing epic to enter edit mode (add/remove/reorder features, change dependencies). Use when the user runs /feature-forge:forge-0-epic or explicitly asks to start/modify an epic. Do NOT trigger for single-feature PRD work (that is forge-1-prd) or for general project planning outside forge.'
4
+ globs: []
5
+ alwaysApply: false
6
+ ---
7
+
8
+ # forge-0-epic — Epic Decomposition & Orchestration
9
+
10
+ Create an epic — a named grouping of related forge features with declared dependencies
11
+ and shared contracts — through a structured decomposition interview, OR edit an existing
12
+ epic. The manifest is the source of truth; EPIC.md mirrors it. All graph/validation work
13
+ is delegated to `scripts/epic-manifest.py`.
14
+
15
+ This skill **composes** JSON and **issues** helper commands. It NEVER eyeballs a dependency
16
+ graph for cycles, NEVER hand-rolls a manifest write where a mutator exists, and NEVER asks a
17
+ question in inline prose — every question goes through `AskUserQuestion`.
18
+
19
+ ## Prerequisites
20
+
21
+ Read and follow `references/shared-conventions.md` for:
22
+ - the **Feature Name Requirement** (applied here to the *epic* name — see below),
23
+ - the **User Input Protocol** (the AskUserQuestion guardrail — all questions go through the tool),
24
+ - **Configuration Reading**, and
25
+ - the **Git Commit Protocol**.
26
+
27
+ **Epic name handling.** The single positional argument is the **epic** name (not a feature).
28
+ If no name is given, STOP and ask for one — do not guess. Convert multi-word input to a single
29
+ kebab-case token. The name must satisfy `SAFE_NAME_RE` (`^[a-z0-9]+(?:-[a-z0-9]+)*$`); the
30
+ helper rejects unsafe names. Member feature names are elicited later, in the interview.
31
+
32
+ **Force mode.** `--force` is honored as in shared-conventions: skip pipeline-state prerequisite
33
+ checks but still load any on-disk artifacts.
34
+
35
+ **Config values read** (defaults from shared-conventions): `specsDir` (default `./specs`),
36
+ `gitCommitAfterStage` (default true), `commitPrefix` (default `forge`).
37
+
38
+ **Helper invocation.** Every helper call uses the convention from 01 §2.2 — the absolute
39
+ plugin path and the configured specs dir:
40
+
41
+ ```bash
42
+ R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
43
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
44
+ python3 "$R/scripts/epic-manifest.py" <subcommand> ... --specs-dir "{specsDir}"
45
+ ```
46
+
47
+ `$R` resolves to the installed plugin root via the portable resolver (`scripts/forge-root.sh`,
48
+ bootstrapped by the prelude above; see `references/portable-root.md`). Pass `--specs-dir "{specsDir}"`
49
+ on every invocation.
50
+
51
+ ---
52
+
53
+ ## Step 0 — Dispatch Detection
54
+
55
+ Resolve the epic subtree path `{specsDir}/{epic}/` and decide which branch to run.
56
+
57
+ 1. **Collision check — is this name already a standalone feature?** If `{specsDir}/{epic}/`
58
+ exists and directly contains a `.pipeline-state.json` of its own (i.e. it is itself a
59
+ *feature* directory, not an epic root), STOP. Surface verbatim:
60
+ > `{epic}` is already a standalone feature, not an epic. Choose a different epic name or
61
+ > relocate the feature.
62
+
63
+ 2. **Manifest existence probe** — does this epic already have a manifest?
64
+
65
+ ```bash
66
+ test -f "{specsDir}/{epic}/epic-manifest.json" && echo EXISTS || echo NEW
67
+ ```
68
+
69
+ - **NEW** (no `epic-manifest.json`) → **Creation branch** (Step C1 onward).
70
+ - **EXISTS** → **Edit branch** (§ Edit Mode below).
71
+
72
+ 3. **Pre-flight epic-name uniqueness (creation only).** Before composing anything for a NEW
73
+ epic, confirm the epic name itself does not collide with any existing feature or epic:
74
+
75
+ ```bash
76
+ R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
77
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
78
+ python3 "$R/scripts/epic-manifest.py" check-name "{epic}" --specs-dir "{specsDir}"
79
+ ```
80
+
81
+ - Exit `0` → the name is free; proceed to C1.
82
+ - Exit `1` (`duplicate-name`) → STOP and surface the helper's finding **verbatim**; ask
83
+ (via `AskUserQuestion`) for a different epic name, then re-run check-name.
84
+ - Exit `2` (unsafe name) → STOP and surface the finding; ask for a corrected name.
85
+
86
+ ---
87
+
88
+ ## Creation Branch
89
+
90
+ ### Step 1 — Branch Setup (optional)
91
+
92
+ If `gitCommitAfterStage` is true and the project uses git, use `AskUserQuestion`:
93
+ "Create a `forge/{epic}` branch for this epic? (Recommended — keeps epic work isolated.)"
94
+ If yes, create and checkout the branch before proceeding.
95
+
96
+ ### Step C1 — Epic Framing Interview
97
+
98
+ Output context as text (what an epic is, that a decomposition interview will follow). Then
99
+ call `AskUserQuestion` to elicit:
100
+
101
+ 1. **Epic goal / problem** — the overarching change being decomposed. Becomes the EPIC.md
102
+ "Overall Goal" narrative and seeds the manifest `description`.
103
+ 2. **One-paragraph description** — a confirmed/edited summary. Becomes the manifest `description`.
104
+
105
+ The epic `name` is the validated CLI argument from Step 0 — do NOT prompt for it again.
106
+
107
+ ### Step C2 — Feature-List Interview
108
+
109
+ Drive a decomposition dialogue. Output your analysis as text first (how the goal might split,
110
+ right-sizing guidance: each feature should be a single pipeline-sized unit — a unit forge-1-prd
111
+ through forge-5-loop would carry end-to-end — not item-level interleaving). Then use
112
+ `AskUserQuestion` to elicit the candidate feature list. Probe with questions like "Is any of
113
+ these two features really one?" and "Is any one of these really two?" Iterate until the user
114
+ confirms the set.
115
+
116
+ For **each** proposed feature name, before accepting it into the set, enforce global uniqueness
117
+ and name safety via the helper:
118
+
119
+ ```bash
120
+ R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
121
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
122
+ python3 "$R/scripts/epic-manifest.py" check-name "{feature}" --specs-dir "{specsDir}"
123
+ ```
124
+
125
+ - Exit `0` → accept the name.
126
+ - Exit `1` (`duplicate-name`) → reject that name; surface the finding verbatim and re-prompt
127
+ (via `AskUserQuestion`) for a different name.
128
+ - Exit `2` (`unsafe-name`) → reject; surface the finding and re-prompt.
129
+
130
+ Never accept a feature name that has not passed `check-name` exit 0.
131
+
132
+ ### Step C3 — Per-Feature Charter + Structured Contracts
133
+
134
+ For each confirmed feature, run a focused `AskUserQuestion` batch (one feature at a time,
135
+ 2–3 questions per call) eliciting:
136
+
137
+ - **Charter** — a single paragraph: scope statement + contract obligations. This is a
138
+ **charter only, NOT a PRD**. Do NOT conduct a full requirements interview here. If the user
139
+ starts dictating detailed requirements, redirect (as context text, then continue the batch):
140
+ > "That's PRD-level detail — `forge-1-prd` will capture it when this feature is ready. For
141
+ > the charter I just need the one-paragraph scope and what it must expose/consume."
142
+ - **`exposes`** — zero or more structured `Contract` objects this feature provides to
143
+ dependents. Each is `{ "name", "kind", "summary" }` where `kind` ∈
144
+ `function | type | endpoint | module | event`.
145
+ - **`consumes`** — zero or more structured `ConsumedContract` objects this feature relies on.
146
+ Each is `{ "from", "name", "summary" }`, where `from` is a sibling feature name in this epic.
147
+
148
+ Collect these into plain JSON objects per feature. Do NOT free-form the contracts in prose —
149
+ the structured arrays are the source of truth; EPIC.md renders them as prose later (Step C6).
150
+
151
+ ### Step C4 — Dependency-Edge Interview
152
+
153
+ For each feature, use `AskUserQuestion`: "Which sibling features must be complete before this
154
+ one can build?" → populates `dependsOn: [names]`.
155
+
156
+ **Seed the suggestion from `consumes`:** a `consumes.from` X strongly implies `dependsOn` X.
157
+ Offer the union of each feature's `consumes.from` set as the default, but let the user confirm —
158
+ `dependsOn` is the authoritative edge set.
159
+
160
+ The `features[]` array order is the user-declared sequence from C2 (order is a presentation
161
+ sequence, **not** a dependency ordering). Preserve the C2 order unless the user asks to reorder.
162
+
163
+ ### Step C5 — Compose & Validate the Manifest
164
+
165
+ Compose the full `epic-manifest.json` per the 00 §2 schema, setting:
166
+
167
+ - `schemaVersion`: `1`
168
+ - `epic`: `"{epic}"`
169
+ - `description`: from C1
170
+ - `status`: `"active"`
171
+ - `narrativeDoc`: `"EPIC.md"`
172
+ - `createdAt` and `updatedAt`: the **same** current ISO-8601 UTC timestamp (`createdAt == updatedAt`)
173
+ - `features[]`: in declared order, each with `name`, `charter`, `dependsOn`, `exposes`,
174
+ `consumes`. **No per-feature `status` field** — including one makes the manifest fail
175
+ validation (the `cached-status` finding).
176
+
177
+ Write the composed JSON to `{specsDir}/{epic}/epic-manifest.json` (creating the epic dir first).
178
+ For the *initial* creation write the skill writes the file directly — atomic guarantees are only
179
+ required for in-place mutation, which is the helper mutators' job. Then validate:
180
+
181
+ ```bash
182
+ R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
183
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
184
+ python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
185
+ ```
186
+
187
+ - Exit `0` → proceed to C6.
188
+ - Exit `1` → the manifest is malformed. Surface **every** `findings[]` entry **verbatim**, do
189
+ NOT proceed, and loop back into the relevant interview step to correct, then re-compose and
190
+ re-validate:
191
+ - `cycle` → re-open the dependency interview (C4).
192
+ - `dangling-ref` → re-open C4 (bad `dependsOn`) or C3 (bad `consumes.from`).
193
+ - `duplicate-name` / `unsafe-name` → re-open the feature-list interview (C2).
194
+ - `cached-status` / schema violation → fix the composed JSON and re-validate.
195
+ - Exit `2` → IO/usage error (missing manifest or unreadable). Surface and STOP.
196
+
197
+ Acyclicity, uniqueness, and dangling-ref checks are thus ALWAYS performed by the helper, never
198
+ by the LLM eyeballing the graph.
199
+
200
+ > **Contracts have no mutator.** There is intentionally no `--exposes-json`/`--consumes-json`
201
+ > flag. At creation, the skill populates each feature's `exposes`/`consumes` directly in the
202
+ > composed manifest entry (above), then re-runs `validate` — exactly as described here. The
203
+ > same pattern applies after an edit-mode `add-feature` (see Edit Mode).
204
+
205
+ ### Step C6 — Generate EPIC.md
206
+
207
+ Generate `{specsDir}/{epic}/EPIC.md` from the **validated** manifest. It is the human-readable
208
+ **mirror** of the manifest (the manifest is the source of truth). For the full EPIC.md structure
209
+ skeleton, read `references/edit-mode.md` (EPIC.md Mirror Template section) — the same template the
210
+ edit-mode E5 patch applies.
211
+
212
+ **The mirror rule.** Render each feature's `exposes`/`consumes` arrays as prose, one bullet per
213
+ contract entry, preserving `name`, `kind`/`from`, and `summary`. Do not invent a contract that
214
+ is not in the manifest, and do not omit one that is. The Overall Goal and Decomposition
215
+ Rationale are the only prose without a 1:1 manifest counterpart. The skill does NOT itself diff
216
+ EPIC.md against the manifest — drift detection is `forge-verify` epic mode CHECK-E06.
217
+
218
+ ### Step C7 — Create Member Subdirectories + Back-Pointer States
219
+
220
+ After the manifest validates and EPIC.md is written, create one subdirectory per member feature
221
+ so the navigator and resolver can see them before any stage runs. For each `features[].name`:
222
+
223
+ 1. Create `{specsDir}/{epic}/{feature}/`.
224
+ 2. Write `{specsDir}/{epic}/{feature}/.pipeline-state.json` conforming to
225
+ `references/pipeline-state-schema.json`, carrying:
226
+ - `epic`: `"{epic}"` — the back-pointer.
227
+ - `currentStage`: `"forge-1-prd"` — the next actionable stage for the member.
228
+ - `stages["forge-0-epic"]`: `{ "status": "complete", "version": 1, "completedAt": "<ts>" }`
229
+ — recording that the epic stage seeded this member.
230
+ - No other stages (all other stages absent/pending), exactly as a freshly-initialized
231
+ standalone feature. **No per-feature `status` beyond the stage entry** — the member state
232
+ holds derived stage progress only.
233
+
234
+ For an example member state, read `references/edit-mode.md` (Member State Example section).
235
+
236
+ The member subtree holds the **same** artifact set a standalone feature holds; only
237
+ `.pipeline-state.json` exists at creation. No PRD/specs are authored here. The epic subtree is
238
+ now self-contained: manifest + EPIC.md + one subdirectory per member.
239
+
240
+ ### Step C8 — Review, Pipeline State & Commit
241
+
242
+ 1. **Review.** Present a summary (epic name, N features, dependency edges, contracts) as text,
243
+ then use `AskUserQuestion`: "Does this epic decomposition look right? Any feature, dependency,
244
+ or contract to change before I commit?" If the user wants changes, loop back to the relevant
245
+ creation step, re-compose, and re-validate.
246
+
247
+ 2. **Commit (Git Commit Protocol).** If `gitCommitAfterStage` is true, follow the Git Commit
248
+ Protocol in shared-conventions:
249
+ - Stage the whole epic subtree only: `git add {specsDir}/{epic}/` — never `git add -A`. This
250
+ captures `epic-manifest.json`, `EPIC.md`, and all member `.pipeline-state.json` files
251
+ atomically.
252
+ - Commit with message `"{commitPrefix}({epic}): create epic with {N} features"`.
253
+ - On success, capture the commit hash. On failure (pre-commit hook, conflict), report and do
254
+ not mark complete; never use `--no-verify`/`--force`.
255
+
256
+ 3. **Closing message.** After a successful creation, tell the user the next steps:
257
+
258
+ > Epic `{epic}` created with {N} features. Next steps:
259
+ > - `/feature-forge:forge {epic}` to see the epic dashboard
260
+ > - `/feature-forge:forge-verify {epic}` to verify the epic
261
+ > - `/feature-forge:forge-1-prd {first-actionable-feature}` to start the first feature
262
+
263
+ The first-actionable feature is any feature with empty `dependsOn` (or the first entry of
264
+ `render-status`'s `actionable` set).
265
+
266
+ ---
267
+
268
+ ## Edit Mode
269
+
270
+ Entered from Step 0 when `{specsDir}/{epic}/epic-manifest.json` already exists (the **EXISTS**
271
+ branch). The edit branch mutates the manifest **only** through helper mutators — atomic
272
+ (temp file + `os.replace`) and internally re-validated, so a refused write leaves the manifest
273
+ **byte-identical**; the skill never hand-rolls an in-place write. Every question goes through
274
+ `AskUserQuestion`, and **every mutation is committed individually** so git history is the audit trail.
275
+
276
+ For the full E1–E6 mechanics — the E1 refuse-if-invalid protocol, E2 operation→mutator table, E3
277
+ contracts/remove-feature caveats (incl. the verbatim WARN block), E4 impact-warning rules, E5
278
+ EPIC.md patch rule, and the E6 Observability / Pipeline State & Commit machinery
279
+ (`.epic-state.json` schema, `updatedAt` rules, Git Commit Protocol shared with C8) — read
280
+ `references/edit-mode.md`. For the exact `epic-manifest.py` mutator flag surface and
281
+ per-subcommand exit-code (`0`/`1`/`2`) handling, read `references/epic-manifest-subcommands.md`.
282
+
283
+ ---
284
+
285
+ ## Error Handling
286
+
287
+ The skill **never** repairs a corrupt manifest automatically and **never** proceeds past a gating
288
+ helper exit `≥ 1`. All findings are surfaced **verbatim**. For the full condition → helper-signal →
289
+ skill-behavior disposition table, read `references/epic-manifest-subcommands.md` (Error Handling
290
+ section).
291
+
292
+ ---
293
+
294
+ ## Gotchas
295
+
296
+ - The argument names an **epic**, not a feature — this is the only stage where that is true.
297
+ Member feature names come from the C2 interview, each gated through `check-name`.
298
+ - Never eyeball the dependency graph for cycles. Compose the manifest, run `validate`, and
299
+ surface findings. The helper owns acyclicity, uniqueness, dangling-ref, and schema checks.
300
+ - A charter is one paragraph, not a PRD. Redirect requirement-level detail to `forge-1-prd`.
301
+ - Contracts have no mutator: edit `exposes`/`consumes` in the composed manifest entry, then
302
+ re-run `validate`.
303
+ - All questions go through `AskUserQuestion`. Never put a question in your text output.
@@ -0,0 +1,222 @@
1
+ # forge-0-epic — Edit Mode (E1–E6) + Observability / Pipeline State & Commit
2
+
3
+ Lookup detail relocated out of the `forge-0-epic` SKILL.md body. The skill body keeps the
4
+ entry condition (the **EXISTS** branch from Step 0) and the high-level "every mutation is
5
+ committed individually" rule, and points here for the full mechanics. The exact mutator flag
6
+ surface and per-subcommand exit-code handling live in `references/epic-manifest-subcommands.md`.
7
+
8
+ Entered from Step 0 when `{specsDir}/{epic}/epic-manifest.json` already exists (the **EXISTS**
9
+ branch). The edit branch mutates the manifest **only** through helper mutators — the skill never
10
+ hand-rolls an in-place write. Every mutator is atomic (temp file + `os.replace`) and re-validates
11
+ the edited graph internally, so a refused write leaves the manifest **byte-identical**. Every
12
+ question goes through `AskUserQuestion`.
13
+
14
+ ## Step E1 — Load + Validate, Refuse if Invalid
15
+
16
+ Before offering any edit, validate the existing manifest:
17
+
18
+ ```bash
19
+ R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
20
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
21
+ python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
22
+ ```
23
+
24
+ - Exit `0` → the manifest is well-formed; proceed to E2.
25
+ - Exit `1` or `2` → the manifest is corrupt or invalid (hand-edited, `corrupt-json`, `cycle`,
26
+ `dangling-ref`, `duplicate-name`, `cached-status`, `unsafe-name`, …). Surface **every**
27
+ `findings[]` entry **verbatim**, then **refuse ALL mutation** until the user repairs the
28
+ manifest by hand. **Never auto-repair**, never offer an edit operation, and never proceed past
29
+ this gate. Tell the user what is wrong and STOP.
30
+
31
+ ## Step E2 — Choose Operation
32
+
33
+ Use `AskUserQuestion` to offer the edit operations, each mapping to one helper mutator:
34
+
35
+ | Operation | Helper subcommand |
36
+ |-----------|-------------------|
37
+ | Add a feature | `add-feature` |
38
+ | Remove a feature | `remove-feature` |
39
+ | Reorder features | `reorder` |
40
+ | Change a dependency edge | `set-dep` |
41
+ | Change epic lifecycle status | `set-status` |
42
+
43
+ For **add-feature**, first run `check-name "{feature}"` (exactly as C2) so no new duplicate is
44
+ introduced — surface a `duplicate-name`/`unsafe-name` finding verbatim and re-prompt — then
45
+ elicit the new feature's **charter** + **`exposes`/`consumes`** + **`dependsOn`** exactly as in
46
+ C3/C4.
47
+
48
+ ## Step E3 — Apply via Helper Mutator (re-validated)
49
+
50
+ Issue the chosen mutator. Each writes atomically and re-runs full validation internally, refusing
51
+ the write if it would introduce a cycle, dangling ref, duplicate, or schema violation. For the
52
+ exact `epic-manifest.py` mutator flag surface and per-subcommand exit-code handling, read
53
+ `references/epic-manifest-subcommands.md`.
54
+
55
+ **Contracts have no mutator.** `add-feature` seeds empty `exposes`/`consumes`. To populate the
56
+ new feature's contracts, edit its `exposes`/`consumes` arrays **directly in the composed manifest
57
+ entry** (exactly as creation C5 does), then re-run `validate "{epic}" --json` to confirm — there
58
+ is intentionally no `--exposes-json`/`--consumes-json` flag.
59
+
60
+ **remove-feature leaves the member directory in place (§7.5).** The mutator drops only the
61
+ manifest entry. The skill does **not** delete or relocate `{specsDir}/{epic}/{feature}/`. WARN the
62
+ user verbatim:
63
+
64
+ > Removed `{feature}` from the manifest. Its directory `{specsDir}/{epic}/{feature}/` is left in
65
+ > place; move it to `{specsDir}/{feature}/` by hand if you want it as a standalone feature.
66
+ > Relocation is manual — there is no migration tooling.
67
+
68
+ The orphaned subdir still holds a `.pipeline-state.json` with an `epic` back-pointer the manifest
69
+ no longer lists; per the conflict rule the **manifest wins**, and `forge-verify` epic mode
70
+ CHECK-E07 reports the inconsistency non-fatally. The skill does **not** silently edit the orphaned
71
+ state file.
72
+
73
+ ## Step E4 — Impact Warning (in-flight / completed features)
74
+
75
+ Before applying — or immediately after eliciting — a mutation that affects a feature whose derived
76
+ status is **not** `not-started`, warn the user. Read the **live** status (never re-derive
77
+ completion in prose):
78
+
79
+ ```bash
80
+ R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
81
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
82
+ python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
83
+ ```
84
+
85
+ If the operation removes, reorders-around, or re-deps a feature whose derived status is
86
+ `in-progress` or `complete`, use `AskUserQuestion` with an explicit warning naming the affected
87
+ in-flight/completed feature(s) and **require confirmation** before applying. Example: "`token-service`
88
+ is already in-progress (forge-3-specs). Removing `config-store`, which it consumes `JWT_SECRET`
89
+ from, may invalidate its in-flight specs. Proceed?" If `render-status` exits `≥ 1`, surface the
90
+ findings and STOP (do not mutate over an invalid graph).
91
+
92
+ ## Step E5 — Patch EPIC.md
93
+
94
+ Patch **only** the affected feature/Contracts section(s) — the section(s) for the added, removed,
95
+ or changed feature and any feature whose `dependsOn`/`consumes` changed — applying the §C6 mirror
96
+ rule (one bullet per `exposes`/`consumes` entry). **Full regeneration happens only on explicit
97
+ user request**: offer it via `AskUserQuestion` but default to the targeted patch. The skill keeps
98
+ EPIC.md in sync but does not itself diff it against the manifest — drift detection is `forge-verify`
99
+ epic mode CHECK-E06.
100
+
101
+ ## Step E6 — Pipeline State & Commit
102
+
103
+ Proceed to the **Observability, Pipeline State & Commit** section below. Each edit-mode mutation is
104
+ committed individually so git history is the audit trail.
105
+
106
+ ## Observability, Pipeline State & Commit
107
+
108
+ ### Manifest `updatedAt`
109
+
110
+ Every helper mutator bumps the manifest's top-level `updatedAt` to the current ISO-8601 UTC
111
+ timestamp as part of the same atomic write. The skill does **not** bump it manually in edit mode.
112
+ For the initial creation write (C5) the skill sets `createdAt == updatedAt`.
113
+
114
+ ### Pipeline state
115
+
116
+ - **Epic-level:** the epic subtree has **no `.pipeline-state.json` of its own** (that is what
117
+ distinguishes an epic root from a feature). The epic's lifecycle lives in the manifest `status`
118
+ field. The `forge-0-epic` run is recorded in **member** states, not in an epic-level state file.
119
+ - **Member-level (creation):** each member's `.pipeline-state.json` records
120
+ `stages["forge-0-epic"].status = "complete"` and `currentStage = "forge-1-prd"` (see C7).
121
+ - **Edit mode:** edits mutate the **manifest**, not member pipeline states — except the
122
+ newly-created subdir for `add-feature`, which follows C7 (create the member subdir + back-pointer
123
+ state). The skill does **not** rewrite existing members' `stages` on an edit.
124
+ - **`.epic-state.json` (lazily created, written by skills — NOT the helper):** epic-*scoped* stage
125
+ entries that belong to no single member — currently only `forge-verify-epic` — are persisted in a
126
+ dedicated `{specsDir}/{epic}/.epic-state.json`. It holds **only** epic-scoped stage entries,
127
+ never derived per-feature status (so it does not violate REQ-STATE-02). `forge-0-epic` does
128
+ **not** create this file — no epic-scoped stage runs during creation or edit; it appears only once
129
+ `forge-verify` epic mode runs. When a skill does write it (e.g. forge-verify epic mode), it writes
130
+ **directly** using an atomic temp-file + `os.replace` pattern — the helper exposes no subcommand
131
+ for it. On I/O failure the skill reports and leaves any prior file intact (never a partial write).
132
+ Minimal schema:
133
+
134
+ ```jsonc
135
+ {
136
+ "epic": "auth-overhaul", // matches manifest `epic`
137
+ "stages": {
138
+ "forge-verify-epic": {
139
+ "status": "findings-reported", // "findings-reported" | "passed" | "findings-applied"
140
+ "findingsFile": ".verification/VERIFY-epic-2026-06-12.md",
141
+ "findingsCount": 3,
142
+ "verifiedAt": "2026-06-12T00:00:00Z"
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ The git-commit step below stages the whole epic subtree, so `.epic-state.json` is captured
149
+ automatically when present.
150
+
151
+ ### Git Commit Protocol
152
+
153
+ After creation (C8) **and after each edit-mode mutation (E6)**, if `gitCommitAfterStage` is true,
154
+ follow the Git Commit Protocol in shared-conventions:
155
+
156
+ 1. Stage the whole epic subtree only: `git add {specsDir}/{epic}/` — **never** `git add -A`. This
157
+ captures `epic-manifest.json`, `EPIC.md`, member `.pipeline-state.json` files, and any
158
+ `.epic-state.json` together atomically.
159
+ 2. Commit with message `"{commitPrefix}({epic}): <action>"`, e.g.
160
+ `"forge({epic}): create epic with 4 features"`, `"forge({epic}): add feature api-gateway"`,
161
+ `"forge({epic}): remove feature legacy-session"`, `"forge({epic}): reorder features"`,
162
+ `"forge({epic}): set dependency on token-service"`, or `"forge({epic}): set status paused"`.
163
+ 3. On success, capture the commit hash. On failure (pre-commit hook, conflict), report and do
164
+ **not** mark complete; never use `--no-verify`/`--force`.
165
+
166
+ Because every mutation is committed, the git history of `epic-manifest.json` is the audit trail; no
167
+ separate in-manifest audit log is kept.
168
+
169
+ ### Closing message
170
+
171
+ After a successful **creation**, present the next-steps message (already specified in C8). After a
172
+ successful **edit-mode mutation**, confirm the change and re-surface the dashboard pointer:
173
+
174
+ > Epic `{epic}` updated (`<action>`). Run `/feature-forge:forge {epic}` to see the refreshed
175
+ > dashboard, or re-run `/feature-forge:forge-0-epic {epic}` to make another change.
176
+
177
+ ## EPIC.md Mirror Template (creation C6 / edit E5)
178
+
179
+ `forge-0-epic` Step C6 generates `{specsDir}/{epic}/EPIC.md` from the **validated** manifest; the
180
+ edit-mode E5 patch applies the **same mirror rule** to the affected sections. The full skeleton:
181
+
182
+ ```markdown
183
+ # {epic} — Epic
184
+
185
+ ## Overall Goal
186
+ {the epic goal from C1, expanded into narrative prose}
187
+
188
+ ## Decomposition Rationale
189
+ {why the change was split this way; right-sizing notes; ordering rationale}
190
+
191
+ ## Features
192
+ {for each feature, in manifest order:}
193
+
194
+ ### {feature.name}
195
+ {feature.charter, as prose}
196
+
197
+ **Depends on:** {comma-separated dependsOn, or "nothing"}
198
+
199
+ #### Contracts
200
+ **Exposes:**
201
+ - `{exposes[i].name}` ({exposes[i].kind}) — {exposes[i].summary}
202
+ {… or "Nothing exposed." if the exposes array is empty}
203
+
204
+ **Consumes:**
205
+ - `{consumes[i].name}` from `{consumes[i].from}` — {consumes[i].summary}
206
+ {… or "Nothing consumed." if the consumes array is empty}
207
+ ```
208
+
209
+ ## Member State Example (creation C7)
210
+
211
+ Each member's `.pipeline-state.json` (created in Step C7) conforms to
212
+ `references/pipeline-state-schema.json`. Example member state:
213
+
214
+ ```json
215
+ {
216
+ "epic": "{epic}",
217
+ "currentStage": "forge-1-prd",
218
+ "stages": {
219
+ "forge-0-epic": { "status": "complete", "version": 1, "completedAt": "<iso-8601-utc>" }
220
+ }
221
+ }
222
+ ```
@@ -0,0 +1,64 @@
1
+ # forge-0-epic — `epic-manifest.py` Subcommand Reference
2
+
3
+ Lookup detail relocated out of the `forge-0-epic` SKILL.md body (Step E3 command
4
+ catalog + exit-code disposition, and the Error Handling table). The skill body keeps
5
+ the decision logic and step ordering; this file is the flag-surface catalog and the
6
+ per-subcommand exit-code reference.
7
+
8
+ ## Edit-Mode Mutator Flag Surface (Step E3)
9
+
10
+ Issue the chosen mutator. Each writes atomically and re-runs full validation internally, refusing
11
+ the write if it would introduce a cycle, dangling ref, duplicate, or schema violation. The exact
12
+ flag surface (owned by 02 §7):
13
+
14
+ ```bash
15
+ R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
16
+ [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
17
+ # Add a feature — seeds EMPTY exposes/consumes; contracts are populated below.
18
+ python3 "$R/scripts/epic-manifest.py" add-feature "{epic}" "{feature}" \
19
+ --charter "…" --specs-dir "{specsDir}" [--depends-on a,b]
20
+
21
+ # Remove a feature (drops its manifest entry; directory is left in place — see E3 note).
22
+ python3 "$R/scripts/epic-manifest.py" remove-feature "{epic}" "{feature}" \
23
+ --specs-dir "{specsDir}"
24
+
25
+ # Reorder the features[] sequence (must be an exact permutation of current member names).
26
+ python3 "$R/scripts/epic-manifest.py" reorder "{epic}" \
27
+ --order "feat-a,feat-c,feat-b" --specs-dir "{specsDir}"
28
+
29
+ # Change a dependency edge (--depends-on "" clears it).
30
+ python3 "$R/scripts/epic-manifest.py" set-dep "{epic}" "{feature}" \
31
+ --depends-on "config-store,token-service" --specs-dir "{specsDir}"
32
+
33
+ # Change epic lifecycle status (active|paused|abandoned|complete).
34
+ python3 "$R/scripts/epic-manifest.py" set-status "{epic}" \
35
+ --status paused --specs-dir "{specsDir}"
36
+ ```
37
+
38
+ ### Per-Subcommand Exit-Code Disposition (Step E3)
39
+
40
+ - Exit `0` → the mutator wrote the manifest and bumped `updatedAt`. Proceed to E4/E5.
41
+ - Exit `1` → surface the `findings[]` **verbatim** and **abort the edit**. The manifest is
42
+ unchanged (the write was refused atomically — byte-identical). Loop back to E2 or re-elicit.
43
+ - Exit `2` → unsafe name / missing|corrupt manifest / bad `--status` value / write failure.
44
+ Surface and STOP.
45
+
46
+ ## Error Handling
47
+
48
+ The skill **never** repairs a corrupt manifest automatically and **never** proceeds past a gating
49
+ helper exit `≥ 1`. All findings are surfaced **verbatim**.
50
+
51
+ | Condition | Helper signal | Skill behavior |
52
+ |-----------|---------------|----------------|
53
+ | Epic name duplicates an existing name | `check-name` exit 1 (`duplicate-name`) | STOP creation; surface finding; ask for a new name via `AskUserQuestion` |
54
+ | Member feature name duplicates | `check-name` exit 1 (`duplicate-name`) | Reject that name in C2 / add-feature; surface verbatim; re-prompt |
55
+ | Unsafe name (`/`, `..`, absolute) | `check-name`/mutator exit 2 (`unsafe-name`) | Reject; surface; re-prompt |
56
+ | Composed manifest has a cycle | `validate` exit 1 (`cycle`) | Surface verbatim; re-open the dependency interview (C4); never finalize |
57
+ | Dangling `dependsOn`/`consumes.from` | `validate` exit 1 (`dangling-ref`) | Surface verbatim; re-open C4 (bad `dependsOn`) or C3 (bad `consumes.from`) |
58
+ | Corrupt/unparseable manifest (edit) | `validate` exit 1 (`corrupt-json`) | Surface ALL findings verbatim; **refuse all mutation** until repaired; never auto-repair |
59
+ | Existing manifest otherwise invalid (edit) | `validate` exit 1/2 | Surface ALL findings verbatim; **refuse all mutation** (E1) |
60
+ | Mutator would introduce cycle/dangling ref/duplicate | mutator exit 1 | Abort the edit; manifest byte-identical (atomic refusal); surface finding |
61
+ | Bad `--status` value | `set-status` exit 2 (argparse) | Surface; re-prompt via `AskUserQuestion` with the valid choices |
62
+ | Edit affects in-flight/completed feature | `render-status` derived status (`in-progress`/`complete`) | Warn naming the affected feature(s); require confirmation before applying (E4) |
63
+ | `render-status` over an invalid graph | `render-status` exit ≥ 1 | Surface findings; STOP (do not mutate over an invalid graph) |
64
+ | Git commit fails | — | Report; leave state `in-progress`; never bypass hooks (`--no-verify`/`--force`) |