@garygentry/feature-forge 0.2.4 → 0.2.6
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.
- package/adapters/claude/.feature-forge-bundle.json +1 -1
- package/adapters/claude/agents/forge-verifier.md +2 -0
- package/adapters/claude/references/portable-root.md +6 -3
- package/adapters/claude/references/shared-conventions.md +19 -6
- package/adapters/claude/references/stage-exit-protocol.md +148 -37
- package/adapters/claude/scripts/forge-root.sh +20 -1
- package/adapters/claude/scripts/forge-session.py +691 -1
- package/adapters/claude/skills/forge/SKILL.md +7 -7
- package/adapters/claude/skills/forge-0-epic/SKILL.md +15 -25
- package/adapters/claude/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/claude/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/claude/skills/forge-1-prd/SKILL.md +7 -8
- package/adapters/claude/skills/forge-2-tech/SKILL.md +7 -8
- package/adapters/claude/skills/forge-3-specs/SKILL.md +7 -8
- package/adapters/claude/skills/forge-4-backlog/SKILL.md +7 -8
- package/adapters/claude/skills/forge-5-loop/SKILL.md +3 -3
- package/adapters/claude/skills/forge-6-docs/SKILL.md +1 -1
- package/adapters/claude/skills/forge-bootstrap/SKILL.md +4 -4
- package/adapters/claude/skills/forge-fix/SKILL.md +11 -9
- package/adapters/claude/skills/forge-guide/SKILL.md +6 -3
- package/adapters/claude/skills/forge-init/SKILL.md +5 -4
- package/adapters/claude/skills/forge-verify/SKILL.md +9 -2
- package/adapters/claude/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/codex/.feature-forge-bundle.json +1 -1
- package/adapters/codex/agents/forge-verifier.toml +2 -0
- package/adapters/codex/references/portable-root.md +6 -3
- package/adapters/codex/references/shared-conventions.md +19 -6
- package/adapters/codex/references/stage-exit-protocol.md +148 -37
- package/adapters/codex/scripts/forge-root.sh +20 -1
- package/adapters/codex/scripts/forge-session.py +691 -1
- package/adapters/codex/skills/forge/SKILL.md +7 -7
- package/adapters/codex/skills/forge-0-epic/SKILL.md +15 -25
- package/adapters/codex/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/codex/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/codex/skills/forge-1-prd/SKILL.md +7 -8
- package/adapters/codex/skills/forge-2-tech/SKILL.md +7 -8
- package/adapters/codex/skills/forge-3-specs/SKILL.md +7 -8
- package/adapters/codex/skills/forge-4-backlog/SKILL.md +7 -8
- package/adapters/codex/skills/forge-5-loop/SKILL.md +3 -3
- package/adapters/codex/skills/forge-6-docs/SKILL.md +1 -1
- package/adapters/codex/skills/forge-bootstrap/SKILL.md +4 -4
- package/adapters/codex/skills/forge-fix/SKILL.md +11 -9
- package/adapters/codex/skills/forge-guide/SKILL.md +6 -3
- package/adapters/codex/skills/forge-init/SKILL.md +5 -4
- package/adapters/codex/skills/forge-verify/SKILL.md +9 -2
- package/adapters/codex/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/copilot/.feature-forge-bundle.json +1 -1
- package/adapters/copilot/agents/forge-verifier.md +2 -0
- package/adapters/copilot/references/portable-root.md +6 -3
- package/adapters/copilot/references/shared-conventions.md +19 -6
- package/adapters/copilot/references/stage-exit-protocol.md +148 -37
- package/adapters/copilot/scripts/forge-root.sh +20 -1
- package/adapters/copilot/scripts/forge-session.py +691 -1
- package/adapters/copilot/skills/forge/forge.md +7 -7
- package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +15 -25
- package/adapters/copilot/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/copilot/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +7 -8
- package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +7 -8
- package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +7 -8
- package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +7 -8
- package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +3 -3
- package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +1 -1
- package/adapters/copilot/skills/forge-bootstrap/forge-bootstrap.md +4 -4
- package/adapters/copilot/skills/forge-fix/forge-fix.md +11 -9
- package/adapters/copilot/skills/forge-guide/forge-guide.md +6 -3
- package/adapters/copilot/skills/forge-init/forge-init.md +5 -4
- package/adapters/copilot/skills/forge-verify/forge-verify.md +9 -2
- package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/cursor/.feature-forge-bundle.json +1 -1
- package/adapters/cursor/agents/forge-verifier.mdc +2 -0
- package/adapters/cursor/references/portable-root.md +6 -3
- package/adapters/cursor/references/shared-conventions.md +19 -6
- package/adapters/cursor/references/stage-exit-protocol.md +148 -37
- package/adapters/cursor/scripts/forge-root.sh +20 -1
- package/adapters/cursor/scripts/forge-session.py +691 -1
- package/adapters/cursor/skills/forge/forge.mdc +7 -7
- package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +15 -25
- package/adapters/cursor/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/cursor/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +7 -8
- package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +7 -8
- package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +7 -8
- package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +7 -8
- package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +3 -3
- package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +1 -1
- package/adapters/cursor/skills/forge-bootstrap/forge-bootstrap.mdc +4 -4
- package/adapters/cursor/skills/forge-fix/forge-fix.mdc +11 -9
- package/adapters/cursor/skills/forge-guide/forge-guide.mdc +6 -3
- package/adapters/cursor/skills/forge-init/forge-init.mdc +5 -4
- package/adapters/cursor/skills/forge-verify/forge-verify.mdc +9 -2
- package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/gemini/.feature-forge-bundle.json +1 -1
- package/adapters/gemini/agents/forge-verifier.md +2 -0
- package/adapters/gemini/gemini-extension.json +1 -1
- package/adapters/gemini/references/portable-root.md +6 -3
- package/adapters/gemini/references/shared-conventions.md +19 -6
- package/adapters/gemini/references/stage-exit-protocol.md +148 -37
- package/adapters/gemini/scripts/forge-root.sh +20 -1
- package/adapters/gemini/scripts/forge-session.py +691 -1
- package/adapters/gemini/skills/forge/forge.md +7 -7
- package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +15 -25
- package/adapters/gemini/skills/forge-0-epic/references/edit-mode.md +2 -2
- package/adapters/gemini/skills/forge-0-epic/references/epic-manifest-subcommands.md +1 -1
- package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +7 -8
- package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +7 -8
- package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +7 -8
- package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +7 -8
- package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +3 -3
- package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +1 -1
- package/adapters/gemini/skills/forge-bootstrap/forge-bootstrap.md +4 -4
- package/adapters/gemini/skills/forge-fix/forge-fix.md +11 -9
- package/adapters/gemini/skills/forge-guide/forge-guide.md +6 -3
- package/adapters/gemini/skills/forge-init/forge-init.md +5 -4
- package/adapters/gemini/skills/forge-verify/forge-verify.md +9 -2
- package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +1 -1
- package/package.json +1 -1
|
@@ -22,14 +22,14 @@ For pipeline architecture details, read `references/process-overview.md`.
|
|
|
22
22
|
**If a feature name is provided** (e.g., `/feature-forge:forge auth`):
|
|
23
23
|
- **First test whether the name is an epic:** if `{specsDir}/{name}/epic-manifest.json` exists, render the **Epic Dashboard** (see format below) and stop — do not treat it as a feature.
|
|
24
24
|
- Otherwise, resolve the name via the **Feature Directory Resolution** block in `references/shared-conventions.md` (so a nested epic-member name finds its dashboard too). On a resolution failure (`not-found` / `ambiguous` at exit 1; `unsafe-name` or a path-containment escape at exit 2), surface it verbatim.
|
|
25
|
-
- On `not-found`
|
|
25
|
+
- On `not-found`, first run the cross-branch discovery step from that same Feature Directory Resolution block (`forge-session.py discover-feature` — the state may live on a topic branch or an unfetched remote branch). Candidates → offer switch / fetch+switch per that block (explicit accept + clean tree only), then re-resolve and render the dashboard. Only when discovery also returns nothing, ask: "No pipeline exists for '{feature}' on any branch. Want to start one? Run `/feature-forge:forge-1-prd {feature}` to begin." Never render a dashboard from memory of earlier sessions (anti-fabrication guard).
|
|
26
26
|
- If resolution succeeds, display the per-feature pipeline status dashboard (see format below) from `{resolvedFeatureDir}/`.
|
|
27
27
|
|
|
28
28
|
**If no feature name is provided:** list in two tiers.
|
|
29
29
|
|
|
30
30
|
1. **Epics first.** Identify epic directories as any `{specsDir}/*/` that directly contains an `epic-manifest.json` **and no `.pipeline-state.json` of its own** (an epic root is never itself a feature). For each epic, run:
|
|
31
31
|
```bash
|
|
32
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
32
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
33
33
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
34
34
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
35
35
|
```
|
|
@@ -37,7 +37,7 @@ python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specs
|
|
|
37
37
|
2. **Standalone features below.** Scan the remaining `{specsDir}/*/` that directly contain a `.pipeline-state.json` **without** an `epic` back-pointer. A nested member's `.pipeline-state.json` is **attributed to its epic (Tier 1), never listed as a standalone feature**.
|
|
38
38
|
- **Rank by recency.** Run the recency ranker so the most-recently-touched active feature is the default — the user rarely has to type a name (especially on mobile after a `/clear`):
|
|
39
39
|
```bash
|
|
40
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
40
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
41
41
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
42
42
|
python3 "$R/scripts/forge-session.py" rank-features --specs-dir "{specsDir}" --json
|
|
43
43
|
```
|
|
@@ -93,14 +93,14 @@ After rendering a **per-feature** dashboard for an **active** pipeline (skip thi
|
|
|
93
93
|
|
|
94
94
|
**2. Check the context window.** Run the context-usage helper so you can advise whether to continue here or start the next stage in a fresh session:
|
|
95
95
|
```bash
|
|
96
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
96
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
97
97
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
98
98
|
python3 "$R/scripts/forge-session.py" context-usage --json
|
|
99
99
|
```
|
|
100
100
|
- `{"available": true, ...}` → note `pct` (e.g. "context ~68% full") and `overThreshold`. Window/threshold come from `contextWindowTokens` / `contextWarnThreshold` in `forge.config.json` (the helper defaults to a 200k window and 0.7 threshold, and auto-bumps the assumed window to 1M once observed usage exceeds 200k; **on a 1M-context model set `contextWindowTokens: 1000000` so the percentage is accurate below 200k too** — 1M can't be detected from the transcript until usage crosses 200k).
|
|
101
101
|
- `{"available": false, ...}` → omit context advice silently (non-Claude host, or a fresh session with no transcript). Never treat this as an error.
|
|
102
102
|
|
|
103
|
-
**2b. Auto-verify
|
|
103
|
+
**2b. Auto-verify catch-up (when `verifyPending` is true).** Under this behavior the just-completed authoring stage runs auto-verify **in-stage** (`references/stage-exit-protocol.md`, in-stage verify block), which clears `verifyPending` — so on the normal path this branch does **nothing**. It fires only as a **catch-up**: `verifyPending` is still true because the producing stage could not dispatch a clean-room subagent (non-Claude host), or ran before this behavior landed. When it does fire, decide whether verify runs automatically (identical logic to the in-stage run, so a stage that already verified is never double-verified):
|
|
104
104
|
|
|
105
105
|
- **`autoVerify` is true for the just-completed `verifyStage`** → **skip the verify question entirely** and run verify now, *provided it can run clean-room*. Auto-verify is safe to run unattended only because verify executes in a fresh `forge-verifier` subagent that inherits none of this session's context (so no `/clear` is needed and only a compact digest returns). Guard the clean-room assumption: proceed unattended **only when the `Agent` tool + `forge-verifier` subagent are available**. Invoke `feature-forge:forge-verify` via the `Skill` tool in **require-clean (`auto`) mode** — in that mode forge-verify refuses to run inline and returns a sentinel if the subagent is not dispatchable (see `skills/forge-verify/SKILL.md`). Then:
|
|
106
106
|
- **Sentinel returned (clean-room unavailable)** → do **not** run verify inline. Degrade to the manual gate: fall through to step 3 with the **"Verify `{stage}` first (manual)"** option included, and if `overThreshold`, recommend "/clear, then verify in a clean session." Verify state stays outstanding; the stage is never advanced on false assurance.
|
|
@@ -133,7 +133,7 @@ This applies whether the feature was named explicitly (`/feature-forge:forge {fe
|
|
|
133
133
|
When the named argument is an epic (`{specsDir}/{name}/epic-manifest.json` exists), render the epic dashboard instead of a per-feature one. Run:
|
|
134
134
|
|
|
135
135
|
```bash
|
|
136
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
136
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
137
137
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
138
138
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
139
139
|
```
|
|
@@ -204,7 +204,7 @@ Support these sub-commands for pipeline lifecycle management:
|
|
|
204
204
|
|
|
205
205
|
- Set the manifest's top-level `status` (`paused` / `active` / `abandoned`) via the helper's `set-status` mutator — an atomic write that also bumps `updatedAt`:
|
|
206
206
|
```bash
|
|
207
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
207
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
208
208
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
209
209
|
python3 "$R/scripts/epic-manifest.py" set-status "{epic}" --status paused --specs-dir "{specsDir}"
|
|
210
210
|
```
|
|
@@ -39,7 +39,7 @@ checks but still load any on-disk artifacts.
|
|
|
39
39
|
plugin path and the configured specs dir:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
42
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
43
43
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
44
44
|
python3 "$R/scripts/epic-manifest.py" <subcommand> ... --specs-dir "{specsDir}"
|
|
45
45
|
```
|
|
@@ -73,7 +73,7 @@ Resolve the epic subtree path `{specsDir}/{epic}/` and decide which branch to ru
|
|
|
73
73
|
epic, confirm the epic name itself does not collide with any existing feature or epic:
|
|
74
74
|
|
|
75
75
|
```bash
|
|
76
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
76
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
77
77
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
78
78
|
python3 "$R/scripts/epic-manifest.py" check-name "{epic}" --specs-dir "{specsDir}"
|
|
79
79
|
```
|
|
@@ -117,7 +117,7 @@ For **each** proposed feature name, before accepting it into the set, enforce gl
|
|
|
117
117
|
and name safety via the helper:
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
120
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
121
121
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
122
122
|
python3 "$R/scripts/epic-manifest.py" check-name "{feature}" --specs-dir "{specsDir}"
|
|
123
123
|
```
|
|
@@ -177,7 +177,7 @@ For the *initial* creation write the skill writes the file directly — atomic g
|
|
|
177
177
|
required for in-place mutation, which is the helper mutators' job. Creating the epic dir first creates `{specsDir}/`, so after writing the manifest invoke the **Specs Directory Hygiene** block in `references/shared-conventions.md` (idempotent; stage anything it writes with this stage's commit). Then validate:
|
|
178
178
|
|
|
179
179
|
```bash
|
|
180
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
180
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
181
181
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
182
182
|
python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
|
|
183
183
|
```
|
|
@@ -237,34 +237,24 @@ now self-contained: manifest + EPIC.md + one subdirectory per member.
|
|
|
237
237
|
|
|
238
238
|
### Step C8 — Review, Pipeline State & Commit
|
|
239
239
|
|
|
240
|
-
1. **Review.** Present a summary (epic name, N features, dependency edges, contracts) as text,
|
|
241
|
-
then use `AskUserQuestion`: "Does this epic decomposition look right? Any feature, dependency,
|
|
242
|
-
or contract to change before I commit?" If the user wants changes, loop back to the relevant
|
|
243
|
-
creation step, re-compose, and re-validate.
|
|
240
|
+
1. **Review.** Present a summary (epic name, N features, dependency edges, contracts) as text, then use `AskUserQuestion`: "Does this epic decomposition look right? Any feature, dependency, or contract to change before I commit?" If the user wants changes, loop back to the relevant creation step, re-compose, and re-validate.
|
|
244
241
|
|
|
245
|
-
2. **Commit (Git Commit Protocol).** If `gitCommitAfterStage` is true, follow the Git Commit
|
|
246
|
-
|
|
247
|
-
- Stage the whole epic subtree only: `git add {specsDir}/{epic}/` — never `git add -A`. This
|
|
248
|
-
captures `epic-manifest.json`, `EPIC.md`, and all member `.pipeline-state.json` files
|
|
249
|
-
atomically.
|
|
242
|
+
2. **Commit (Git Commit Protocol).** If `gitCommitAfterStage` is true, follow the Git Commit Protocol in shared-conventions:
|
|
243
|
+
- Stage the whole epic subtree only: `git add {specsDir}/{epic}/` — never `git add -A`. This captures `epic-manifest.json`, `EPIC.md`, and all member `.pipeline-state.json` files atomically.
|
|
250
244
|
- Commit with message `"{commitPrefix}({epic}): create epic with {N} features"`.
|
|
251
|
-
- On success, capture the commit hash for the closing message only — the epic manifest has no
|
|
252
|
-
`commitHash` field, so nothing is written back into a committed file and the two-commit step of
|
|
253
|
-
the Git Commit Protocol does not apply here. On failure (pre-commit hook, conflict), report and
|
|
254
|
-
do not mark complete; never use `--amend`/`--no-verify`/`--force`.
|
|
245
|
+
- On success, capture the commit hash for the closing message only — the epic manifest has no `commitHash` field, so nothing is written back into a committed file and the two-commit step of the Git Commit Protocol does not apply here. On failure (pre-commit hook, conflict), report and do not mark complete; never use `--amend`/`--no-verify`/`--force`.
|
|
255
246
|
|
|
256
247
|
3. **Closing message — the Stage Exit Protocol.** Congratulate the user ("Epic `{epic}` created with {N} features."), then close with the Stage Exit Protocol below (single-sourced in `references/stage-exit-protocol.md`; the epic → first-PRD boundary is a full stage boundary — do not improvise a "Next steps" list). `{first-actionable-feature}` = any feature with empty `dependsOn` (or the first entry of `render-status`'s `actionable` set):
|
|
257
248
|
|
|
258
|
-
**
|
|
249
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
259
250
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
251
|
+
```bash
|
|
252
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
253
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
254
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{epic}" --stage forge-0-epic --next-feature "{first-actionable-feature}" --specs-dir "{specsDir}" --host claude
|
|
255
|
+
```
|
|
264
256
|
|
|
265
|
-
|
|
266
|
-
2. **Then `/clear`.** Recommended **unconditionally** at this boundary for a clean start — independent of how full the context window is. Every artifact is on disk, so the work survives the clear. **I can't `/clear` for you — you have to run it yourself.**
|
|
267
|
-
3. **Then run `/feature-forge:forge-1-prd {first-actionable-feature}`** in the fresh session — or re-run `/feature-forge:forge` to let the navigator resume from disk.
|
|
257
|
+
Obey the DIRECTIVES it prints, in order, per the directive contract: `runInStageVerify: true` → dispatch the in-stage clean-room verify now (honoring `autoFixEligible`); `verifyGate: "standard"` → present the Standard Verify Gate; `verifyGate: "manual-print"` → print the `verifyCommand` for the user; non-empty `invalidAutoVerifyKeys` → print a one-line warning. Then **print the NEXT-STEPS block verbatim as your absolute last output — nothing after its sentinel line.**
|
|
268
258
|
|
|
269
259
|
---
|
|
270
260
|
|
|
@@ -16,7 +16,7 @@ question goes through `AskUserQuestion`.
|
|
|
16
16
|
Before offering any edit, validate the existing manifest:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
19
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
20
20
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
21
21
|
python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
|
|
22
22
|
```
|
|
@@ -77,7 +77,7 @@ status is **not** `not-started`, warn the user. Read the **live** status (never
|
|
|
77
77
|
completion in prose):
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
80
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
81
81
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
82
82
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
83
83
|
```
|
|
@@ -12,7 +12,7 @@ the write if it would introduce a cycle, dangling ref, duplicate, or schema viol
|
|
|
12
12
|
flag surface (owned by 02 §7):
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
15
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
16
16
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
17
17
|
# Add a feature — seeds EMPTY exposes/consumes; contracts are populated below.
|
|
18
18
|
python3 "$R/scripts/epic-manifest.py" add-feature "{epic}" "{feature}" \
|
|
@@ -114,16 +114,15 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
114
114
|
3. If `gitCommitAfterStage` is true, follow the Git Commit Protocol in `references/shared-conventions.md`: stage files (including `{specsDir}/AGENTS.md` / `{specsDir}/CLAUDE.md` if the Specs Directory Hygiene step just wrote them), attempt commit with message `"{commitPrefix}({feature}): complete PRD v{n}"` (marking `stages.forge-1-prd.status` `complete` with `commitHash: null` in that commit), then record the artifact-commit hash via the protocol's two-commit follow-up (never `--amend`) only on success. If commit fails, leave status as `in-progress`.
|
|
115
115
|
4. **Close with the Stage Exit Protocol** (single-sourced in `references/stage-exit-protocol.md`; do not improvise a "Next steps" list):
|
|
116
116
|
|
|
117
|
-
**
|
|
117
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
```bash
|
|
120
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
121
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
122
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-1-prd --specs-dir "{specsDir}" --host claude
|
|
123
|
+
```
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
2. **Then `/clear`.** Recommended **unconditionally** at this boundary for a clean start — independent of how full the context window is. Every artifact is on disk, so the work survives the clear. **I can't `/clear` for you — you have to run it yourself.**
|
|
126
|
-
3. **Then run `/feature-forge:forge-2-tech {feature}`** in the fresh session — or re-run `/feature-forge:forge` to let the navigator resume from disk.
|
|
125
|
+
Obey the DIRECTIVES it prints, in order, per the directive contract: `runInStageVerify: true` → dispatch the in-stage clean-room verify now (honoring `autoFixEligible`); `verifyGate: "standard"` → present the Standard Verify Gate; `verifyGate: "manual-print"` → print the `verifyCommand` for the user; non-empty `invalidAutoVerifyKeys` → print a one-line warning. Then **print the NEXT-STEPS block verbatim as your absolute last output — nothing after its sentinel line.**
|
|
127
126
|
|
|
128
127
|
## Gotchas
|
|
129
128
|
|
|
@@ -191,16 +191,15 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
191
191
|
3. If `gitCommitAfterStage` is true, follow the Git Commit Protocol in `references/shared-conventions.md`: stage files, attempt commit with message `"{commitPrefix}({feature}): complete tech-spec v{n}"` (marking `stages.forge-2-tech.status` `complete` with `commitHash: null` in that commit), then record the artifact-commit hash via the protocol's two-commit follow-up (never `--amend`) only on success. If commit fails, leave status as `in-progress`.
|
|
192
192
|
4. **Close with the Stage Exit Protocol** (single-sourced in `references/stage-exit-protocol.md`; do not improvise a "Next steps" list):
|
|
193
193
|
|
|
194
|
-
**
|
|
194
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
196
|
+
```bash
|
|
197
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
198
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
199
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-2-tech --specs-dir "{specsDir}" --host claude
|
|
200
|
+
```
|
|
200
201
|
|
|
201
|
-
|
|
202
|
-
2. **Then `/clear`.** Recommended **unconditionally** at this boundary for a clean start — independent of how full the context window is. Every artifact is on disk, so the work survives the clear. **I can't `/clear` for you — you have to run it yourself.**
|
|
203
|
-
3. **Then run `/feature-forge:forge-3-specs {feature}`** in the fresh session — or re-run `/feature-forge:forge` to let the navigator resume from disk.
|
|
202
|
+
Obey the DIRECTIVES it prints, in order, per the directive contract: `runInStageVerify: true` → dispatch the in-stage clean-room verify now (honoring `autoFixEligible`); `verifyGate: "standard"` → present the Standard Verify Gate; `verifyGate: "manual-print"` → print the `verifyCommand` for the user; non-empty `invalidAutoVerifyKeys` → print a one-line warning. Then **print the NEXT-STEPS block verbatim as your absolute last output — nothing after its sentinel line.**
|
|
204
203
|
|
|
205
204
|
## Gotchas
|
|
206
205
|
|
|
@@ -145,16 +145,15 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
145
145
|
3. If `gitCommitAfterStage` is true, follow the Git Commit Protocol in `references/shared-conventions.md`: stage files, attempt commit with message `"{commitPrefix}({feature}): complete implementation specs v{n}"` (marking `stages.forge-3-specs.status` `complete` with `commitHash: null` in that commit), then record the artifact-commit hash via the protocol's two-commit follow-up (never `--amend`) only on success. If commit fails, leave status as `in-progress`.
|
|
146
146
|
4. **Close with the Stage Exit Protocol** (single-sourced in `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Specs feed every downstream stage, so the verify gate matters here:
|
|
147
147
|
|
|
148
|
-
**
|
|
148
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
```bash
|
|
151
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
152
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
153
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-3-specs --specs-dir "{specsDir}" --host claude
|
|
154
|
+
```
|
|
154
155
|
|
|
155
|
-
|
|
156
|
-
2. **Then `/clear`.** Recommended **unconditionally** at this boundary for a clean start — independent of how full the context window is. Every artifact is on disk, so the work survives the clear. **I can't `/clear` for you — you have to run it yourself.**
|
|
157
|
-
3. **Then run `/feature-forge:forge-4-backlog {feature}`** in the fresh session — or re-run `/feature-forge:forge` to let the navigator resume from disk.
|
|
156
|
+
Obey the DIRECTIVES it prints, in order, per the directive contract: `runInStageVerify: true` → dispatch the in-stage clean-room verify now (honoring `autoFixEligible`); `verifyGate: "standard"` → present the Standard Verify Gate; `verifyGate: "manual-print"` → print the `verifyCommand` for the user; non-empty `invalidAutoVerifyKeys` → print a one-line warning. Then **print the NEXT-STEPS block verbatim as your absolute last output — nothing after its sentinel line.**
|
|
158
157
|
|
|
159
158
|
## Gotchas
|
|
160
159
|
|
|
@@ -139,16 +139,15 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`. Foll
|
|
|
139
139
|
4. If verification was available but the user chose to skip it, record `stages.forge-verify-backlog.status` as `"skipped"` in pipeline state.
|
|
140
140
|
5. **Close with the Stage Exit Protocol** (single-sourced in `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Lead with the item count ("Backlog complete with {N} items."), then:
|
|
141
141
|
|
|
142
|
-
**
|
|
142
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
```bash
|
|
145
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
146
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
147
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-4-backlog --specs-dir "{specsDir}" --host claude
|
|
148
|
+
```
|
|
148
149
|
|
|
149
|
-
|
|
150
|
-
2. **Then `/clear`.** Recommended **unconditionally** at this boundary for a clean start — independent of how full the context window is. Every artifact is on disk, so the work survives the clear. **I can't `/clear` for you — you have to run it yourself.**
|
|
151
|
-
3. **Then run `/feature-forge:forge-5-loop {feature}`** in the fresh session — or re-run `/feature-forge:forge` to let the navigator resume from disk.
|
|
150
|
+
Obey the DIRECTIVES it prints, in order, per the directive contract: `runInStageVerify: true` → dispatch the in-stage clean-room verify now (honoring `autoFixEligible`); `verifyGate: "standard"` → present the Standard Verify Gate; `verifyGate: "manual-print"` → print the `verifyCommand` for the user; non-empty `invalidAutoVerifyKeys` → print a one-line warning. Then **print the NEXT-STEPS block verbatim as your absolute last output — nothing after its sentinel line.**
|
|
152
151
|
|
|
153
152
|
## Gotchas
|
|
154
153
|
|
|
@@ -61,7 +61,7 @@ Read the resolved feature's `.pipeline-state.json`. **If it has no `epic` key, s
|
|
|
61
61
|
1. Run `render-status "{epic}" --specs-dir "{specsDir}" --json` via the helper:
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
64
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
65
65
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
66
66
|
python3 "$R/scripts/epic-manifest.py" \
|
|
67
67
|
render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
@@ -282,7 +282,7 @@ Update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
|
282
282
|
|
|
283
283
|
**This stage is done — walk the user through the Stage Exit Protocol** before moving on. The order is fixed, and step 2 is something only the user can do:
|
|
284
284
|
|
|
285
|
-
1. **Verify feature {feature}'s loop first — if it isn't already verified.**
|
|
285
|
+
1. **Verify feature {feature}'s loop first — if it isn't already verified.** If verify already ran in this session — via the in-stage auto-verify on the authoring stages, or the interactive impl-verify offered above on the loop — or is already fresh on record, or the stage was explicitly skipped, say so and go straight to step 2. Only when `autoVerify` is off for this stage **and** verify is **missing or stale** do you present the **Standard Verify Gate**: verify **now, before clearing**, using `AskUserQuestion` with exactly these three options — but only when the host has a question mechanism **and** the clean-room path is available (the `Agent` tool plus a dispatchable `forge-verifier` subagent):
|
|
286
286
|
- **Verify feature {feature}'s loop now** *(recommended)* — dispatch the clean-room `forge-verifier` subagent from this session in require-clean mode; the digest returns here so any fix decision keeps its context. One-time — it does **not** change config.
|
|
287
287
|
- **Verify now + enable auto-verify going forward** — verify now **and** patch `"autoVerify": true` into `forge.config.json` in place (preserve formatting and every other key) so future stages verify automatically, no prompt. This complements the `forge-init` opt-in. **Do not auto-commit this config change** — treat it like `notes`: a user-facing edit the user commits on their own cadence, never folded into a stage's artifact commit.
|
|
288
288
|
- **Skip for now** — go straight to `/clear` and the next command without verifying. Record this stage's verify status as `"skipped"` in pipeline state (mirroring the existing skip handling) **only** on an explicit skip — a skip does not go stale.
|
|
@@ -293,7 +293,7 @@ Update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
|
293
293
|
|
|
294
294
|
## Gotchas
|
|
295
295
|
|
|
296
|
-
- **Plugin-root discovery (1b-epic helper) covers installed paths, not workspace-dev checkouts.** The `forge-root.sh` search in 1b-epic probes `~/.claude/skills/feature-forge`, `~/.claude/plugins/*/feature-forge`, and `./.agents/skills/feature-forge` — the locations of an **installed** plugin. A feature-forge **source checkout** (e.g. `~/workspace/feature-forge`) is not on that list, so the helper exits "cannot locate plugin root." That is expected in a dev environment, not a bug; run the epic-manifest script from the checkout directly (`python3 <checkout>/scripts/epic-manifest.py …`). The bootstrap prelude wraps its candidate loop in `bash -c` so the `~/.claude/plugins/*/feature-forge` glob is zsh-safe: an empty expansion no longer aborts the loop under zsh's `nomatch`.
|
|
296
|
+
- **Plugin-root discovery (1b-epic helper) covers installed paths, not workspace-dev checkouts.** The `forge-root.sh` search in 1b-epic probes `~/.claude/skills/feature-forge`, `~/.claude/plugins/cache/*/feature-forge/*` (marketplace-cache installs), `~/.claude/plugins/*/feature-forge`, and `./.agents/skills/feature-forge` — the locations of an **installed** plugin. A feature-forge **source checkout** (e.g. `~/workspace/feature-forge`) is not on that list, so the helper exits "cannot locate plugin root." That is expected in a dev environment, not a bug; run the epic-manifest script from the checkout directly (`python3 <checkout>/scripts/epic-manifest.py …`). The bootstrap prelude wraps its candidate loop in `bash -c` so the `~/.claude/plugins/*/feature-forge` glob is zsh-safe: an empty expansion no longer aborts the loop under zsh's `nomatch`.
|
|
297
297
|
- `{backlogDir}` is a **directory path**, not a file path. Pass `specs/auth`, not `specs/auth/backlog.json`.
|
|
298
298
|
- rauf resolves `RAUF.md` with fallback: checks `{backlogDir}/.rauf/RAUF.md` first, then the project's `.rauf/RAUF.md`. As long as the runner is installed in the project, the prompt template will be found.
|
|
299
299
|
- State files (state.json, {loopRunner.logFile}, etc.) are created at `{backlogDir}/{loopRunner.stateDir}/` — this is within the feature's spec directory and is expected. State is isolated per backlog dir, so concurrent features don't collide.
|
|
@@ -44,7 +44,7 @@ Check `.pipeline-state.json` for `stages.forge-verify-impl`. If it is **absent**
|
|
|
44
44
|
If the resolved feature has an `epic` back-pointer in its `.pipeline-state.json`, run:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
47
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
48
48
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
49
49
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
50
50
|
```
|
|
@@ -59,7 +59,7 @@ Every bash invocation begins with the byte-identical portable-root prelude, then
|
|
|
59
59
|
helper. Pass `--specs-dir ./specs` (the default) so the gate allow-lists the specs directory.
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
62
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
63
63
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
64
64
|
python3 "$R/scripts/forge-bootstrap.py" check "<target-dir>" --json --specs-dir ./specs
|
|
65
65
|
```
|
|
@@ -136,7 +136,7 @@ when running under a Claude host (e.g. `AskUserQuestion` is available), else `"c
|
|
|
136
136
|
`CLAUDE.md` only when `host == "claude"`.
|
|
137
137
|
|
|
138
138
|
```bash
|
|
139
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
139
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
140
140
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
141
141
|
python3 "$R/scripts/forge-bootstrap.py" scaffold "<target-dir>" --json --answers '<Answers JSON>'
|
|
142
142
|
```
|
|
@@ -144,7 +144,7 @@ python3 "$R/scripts/forge-bootstrap.py" scaffold "<target-dir>" --json --answers
|
|
|
144
144
|
### Step 5 — verify
|
|
145
145
|
|
|
146
146
|
```bash
|
|
147
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
147
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
148
148
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
149
149
|
python3 "$R/scripts/forge-bootstrap.py" verify "<target-dir>" --json --answers '<Answers JSON>'
|
|
150
150
|
```
|
|
@@ -170,7 +170,7 @@ and removes the sentinel before staging so it never enters history. Read
|
|
|
170
170
|
leave the sentinel in-progress (resumable) — do **not** declare success.
|
|
171
171
|
|
|
172
172
|
```bash
|
|
173
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
173
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
174
174
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
175
175
|
python3 "$R/scripts/forge-bootstrap.py" commit "<target-dir>" --json --answers '<Answers JSON>' [--stage-only]
|
|
176
176
|
```
|
|
@@ -9,14 +9,16 @@ argument-hint: <feature-name>
|
|
|
9
9
|
|
|
10
10
|
Apply fixes from the most recent forge-verify findings document, with step-level tracking for crash recovery.
|
|
11
11
|
|
|
12
|
-
Usually invoked by the user, but
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
navigator
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
Usually invoked by the user, but an **`autoFix` caller** may also invoke this skill automatically
|
|
13
|
+
when `autoFix: true` is configured **and** its preconditions hold (the findings document has zero
|
|
14
|
+
unresolved decision points, the working tree is clean, and a mandatory re-verify passes afterward).
|
|
15
|
+
Two callers drive that chain: an **authoring stage's in-stage auto-verify** (the primary path — see
|
|
16
|
+
`references/stage-exit-protocol.md`, the in-stage verify block) and the **`/feature-forge:forge`
|
|
17
|
+
navigator's catch-up** (§3b). The **fix application** below is identical either way — this skill is
|
|
18
|
+
not "auto-aware" about *applying* findings; it always applies the latest findings document. The
|
|
19
|
+
**caller** owns the gating decisions, including the closing re-verify: the Step 6 gate is presented
|
|
20
|
+
**only on a direct invocation**, because under an `autoFix` chain the caller (stage skill or
|
|
21
|
+
navigator) runs the mandatory re-verify itself.
|
|
20
22
|
|
|
21
23
|
## Prerequisites
|
|
22
24
|
|
|
@@ -76,7 +78,7 @@ Follow the Git Commit Protocol in `references/shared-conventions.md`.
|
|
|
76
78
|
|
|
77
79
|
Fixes are applied and recorded (`findings-applied`), so the stage reads **fresh** in the navigator's ledger (Step 5 set `verifiedStageVersion` to the current version). A re-verify is nonetheless the only thing that *confirms* the fixes actually resolved the findings, so on a **direct/manual** `forge-fix` invocation, **prompt** it rather than leaving it as a passive suggestion — this is the same **Standard Verify Gate** the stage skills stamp (`references/stage-exit-protocol.md`).
|
|
78
80
|
|
|
79
|
-
**Skip this gate when
|
|
81
|
+
**Skip this gate when an `autoFix` caller invoked you as part of a chain** — the authoring stage's in-stage auto-verify (`references/stage-exit-protocol.md`, in-stage verify block) or the navigator's catch-up (`skills/forge/SKILL.md` §3b step 2b): there the caller owns the mandatory re-verify, so a second gate here would block the unattended flow or double the re-verify. Just return and let the caller proceed.
|
|
80
82
|
|
|
81
83
|
On a direct invocation, present the gate using `AskUserQuestion` with these three options — but only when the host has a question mechanism **and** the clean-room path is available (the `Agent` tool plus a dispatchable `forge-verifier` subagent):
|
|
82
84
|
- **Re-verify {feature} now** *(recommended)* — dispatch the clean-room `forge-verifier` subagent from this session in require-clean mode to confirm every finding is resolved; the digest returns here so any remaining issue keeps its context. One-time — it does **not** change config.
|
|
@@ -104,7 +104,7 @@ green baseline. On non-Claude agents, install via `npx @garygentry/feature-forge
|
|
|
104
104
|
- **Stack** — `stack`, `typeCheckCommand`, `testCommand`: null until Stage 2 auto-detects them.
|
|
105
105
|
- **Context** — `contextWindowTokens`, `contextWarnThreshold` (0.7): the navigator warns to
|
|
106
106
|
`/clear` past this fullness. On 1M-context models set `contextWindowTokens` explicitly.
|
|
107
|
-
- **Verification** — `autoVerify` (false), `autoVerifyStages`, `autoFix` (false).
|
|
107
|
+
- **Verification** — `autoVerify` (false; when on, each authoring stage verifies in-stage before its exit block), `autoVerifyStages`, `autoFix` (false).
|
|
108
108
|
- **Stage flow** — `autoInvokeNextStage` (true on Claude, print-only elsewhere).
|
|
109
109
|
- **Loop** — `loopRunner` block (binary, command templates, version gate, agent selection);
|
|
110
110
|
defaults to **rauf** when absent. `workspaces` supports monorepos.
|
|
@@ -114,8 +114,11 @@ green baseline. On non-Claude agents, install via `npx @garygentry/feature-forge
|
|
|
114
114
|
`forge-verify <feature>` dispatches the read-only `forge-verifier` subagent to find gaps,
|
|
115
115
|
inconsistencies, and quality issues; it writes a findings doc, and `forge-fix` applies them.
|
|
116
116
|
Because verification runs in a **fresh subagent**, it's clean-room by construction — it never
|
|
117
|
-
needs a `/clear`, and it's safe to automate with `autoVerify: true
|
|
118
|
-
|
|
117
|
+
needs a `/clear`, and it's safe to automate with `autoVerify: true`. When on, the just-completed
|
|
118
|
+
authoring stage runs verify **in-stage** — in the same session, right before its exit block — so
|
|
119
|
+
the digest and any fix land where the context still exists (the navigator only catches up if a
|
|
120
|
+
host couldn't run it clean-room). Fixing stays human-gated unless `autoFix: true`. The cost is one
|
|
121
|
+
extra clean-room verify per stage. **Always verify before Stage 5 (the loop)** — catching errors in
|
|
119
122
|
specs/backlog is far cheaper than mid-loop. Verifying after PRD and after backlog is also
|
|
120
123
|
recommended. A findings pass is fresh only while the artifact `version` matches what was
|
|
121
124
|
verified; revise upstream and downstream re-verifies.
|
|
@@ -9,7 +9,7 @@ description: Initialize feature-forge configuration in the current project. Use
|
|
|
9
9
|
Run the initialization script to create `forge.config.json` with default settings:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
12
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
13
13
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
14
14
|
bash "$R/scripts/forge-init.sh"
|
|
15
15
|
```
|
|
@@ -26,7 +26,7 @@ After initialization, the config file will contain defaults for:
|
|
|
26
26
|
- `autoInvokeNextStage`: `true` (the navigator auto-starts the next stage after you confirm; set `false` to only print the command)
|
|
27
27
|
- `contextWindowTokens`: `null` (the navigator infers the context window; set to your model's window, e.g. `1000000` for a 1M-context model, for accurate context-usage advice)
|
|
28
28
|
- `contextWarnThreshold`: `0.7` (fraction of the window past which the navigator suggests a clean session)
|
|
29
|
-
- `autoVerify`: `false` (set `true` to run `forge-verify` automatically after each stage completes)
|
|
29
|
+
- `autoVerify`: `false` (set `true` to run `forge-verify` automatically after each authoring stage completes — in-stage, in the same session, before the exit block; it costs an extra clean-room verify per stage, so it trades a little time/tokens for catching errors early)
|
|
30
30
|
- `autoVerifyStages`: `{}` (per-stage overrides for `autoVerify`)
|
|
31
31
|
- `autoFix`: `false` (set `true` to chain `forge-fix` after an auto-verify finds issues)
|
|
32
32
|
|
|
@@ -40,8 +40,9 @@ auto-verify on, then write the choice back into `forge.config.json`.
|
|
|
40
40
|
|
|
41
41
|
If the `AskUserQuestion` tool is available, ask exactly one question:
|
|
42
42
|
|
|
43
|
-
> **Enable auto-verify?** Verification runs in a clean-room subagent after each
|
|
44
|
-
> completes —
|
|
43
|
+
> **Enable auto-verify?** Verification runs in a clean-room subagent in-stage after each
|
|
44
|
+
> authoring stage completes — in the same session, before the exit block, so any fix
|
|
45
|
+
> decision keeps its context. It never needs a `/clear` and only returns a compact digest.
|
|
45
46
|
> **Recommended: on.** (Change later by editing `autoVerify` in `forge.config.json`.)
|
|
46
47
|
|
|
47
48
|
Options: **Enable (recommended)** / **Leave off**.
|
|
@@ -9,7 +9,14 @@ argument-hint: '<feature-name> [stage: prd|tech|specs|backlog|impl] [--require-c
|
|
|
9
9
|
|
|
10
10
|
Analyze feature artifacts for completeness, consistency, and quality. Produce structured, actionable findings designed for a fresh-context agent to apply.
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Which role are you? (read this first)
|
|
13
|
+
|
|
14
|
+
This skill is loaded in two different roles. Determine yours before proceeding:
|
|
15
|
+
|
|
16
|
+
- **You ARE the `forge-verifier` subagent** — you were dispatched via the Agent tool, you have read-only tools (Read, Glob, Grep, Bash) and **no** Agent/Task tool, and this skill is pre-loaded in your context. **SKIP "Subagent Delegation (parent orchestrator only)" and "Synthesize" below — those describe how a *parent* dispatches *you*, not work for you to do.** Do **not** dispatch anything, do **not** try to spawn a verifier. Go straight to **Prerequisites → Steps 1–6**, execute the checks yourself, and **return your findings as your response** (the parent writes the document to disk). Dispatching a subagent from here is the classic self-referential loop — never do it.
|
|
17
|
+
- **You are the parent orchestrator** — a navigator (`/feature-forge:forge`), a stage skill's in-stage auto-verify, or a direct `/feature-forge:forge-verify` invocation, and you have the Agent tool. Use "Subagent Delegation" to dispatch the `forge-verifier` subagent, then "Synthesize" to assemble and write the document.
|
|
18
|
+
|
|
19
|
+
## Subagent Delegation (parent orchestrator only)
|
|
13
20
|
|
|
14
21
|
This skill is delegated to the `forge-verifier` subagent via the Agent tool. The verifier subagent has:
|
|
15
22
|
- **Read-only tools** (Read, Glob, Grep, Bash) — it cannot accidentally modify specs
|
|
@@ -249,7 +256,7 @@ Do NOT mark as `findings-applied` — that happens after the fix pass.
|
|
|
249
256
|
- For specs verification, also run the deterministic traceability validator to supplement agent-driven traceability checks. Include any uncovered requirements or orphaned references as findings:
|
|
250
257
|
|
|
251
258
|
```bash
|
|
252
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
259
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
253
260
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
254
261
|
python3 "$R/scripts/validate-traceability.py" {resolvedFeatureDir}/PRD.md {resolvedFeatureDir}/ --json
|
|
255
262
|
```
|
|
@@ -192,7 +192,7 @@ findings to E01/E02/E03/E08. Then perform the judgment checks E04–E07 by readi
|
|
|
192
192
|
manifest, EPIC.md, and completed members' specs.
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
|
-
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
195
|
+
R="$(bash -c 'for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
196
196
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
197
197
|
python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
|
|
198
198
|
```
|