@garygentry/feature-forge 0.2.4 → 0.2.5
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/references/portable-root.md +6 -3
- package/adapters/claude/references/shared-conventions.md +19 -6
- package/adapters/claude/references/stage-exit-protocol.md +144 -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 +1 -1
- package/adapters/claude/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/codex/.feature-forge-bundle.json +1 -1
- 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 +144 -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 +1 -1
- package/adapters/codex/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/copilot/.feature-forge-bundle.json +1 -1
- 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 +144 -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 +1 -1
- package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/cursor/.feature-forge-bundle.json +1 -1
- 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 +144 -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 +1 -1
- package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +1 -1
- package/adapters/gemini/.feature-forge-bundle.json +1 -1
- 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 +144 -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 +1 -1
- package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +1 -1
- package/package.json +1 -1
|
@@ -21,14 +21,14 @@ For pipeline architecture details, read `references/process-overview.md`.
|
|
|
21
21
|
**If a feature name is provided** (e.g., `/feature-forge:forge auth`):
|
|
22
22
|
- **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.
|
|
23
23
|
- 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.
|
|
24
|
-
- On `not-found`
|
|
24
|
+
- 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).
|
|
25
25
|
- If resolution succeeds, display the per-feature pipeline status dashboard (see format below) from `{resolvedFeatureDir}/`.
|
|
26
26
|
|
|
27
27
|
**If no feature name is provided:** list in two tiers.
|
|
28
28
|
|
|
29
29
|
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:
|
|
30
30
|
```bash
|
|
31
|
-
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')"
|
|
31
|
+
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')"
|
|
32
32
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
33
33
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
34
34
|
```
|
|
@@ -36,7 +36,7 @@ python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specs
|
|
|
36
36
|
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**.
|
|
37
37
|
- **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 your session / start a fresh session):
|
|
38
38
|
```bash
|
|
39
|
-
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')"
|
|
39
|
+
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')"
|
|
40
40
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
41
41
|
python3 "$R/scripts/forge-session.py" rank-features --specs-dir "{specsDir}" --json
|
|
42
42
|
```
|
|
@@ -92,14 +92,14 @@ After rendering a **per-feature** dashboard for an **active** pipeline (skip thi
|
|
|
92
92
|
|
|
93
93
|
**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:
|
|
94
94
|
```bash
|
|
95
|
-
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')"
|
|
95
|
+
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')"
|
|
96
96
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
97
97
|
python3 "$R/scripts/forge-session.py" context-usage --json
|
|
98
98
|
```
|
|
99
99
|
- `{"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).
|
|
100
100
|
- `{"available": false, ...}` → omit context advice silently (non-Claude host, or a fresh session with no transcript). Never treat this as an error.
|
|
101
101
|
|
|
102
|
-
**2b. Auto-verify
|
|
102
|
+
**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):
|
|
103
103
|
|
|
104
104
|
- **`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 your session / start a fresh session is needed and only a compact digest returns). Guard the clean-room assumption: proceed unattended **only when the host's subagent mechanism + `forge-verifier` subagent are available**. Invoke `feature-forge:forge-verify` via the host's skill-invocation mechanism 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:
|
|
105
105
|
- **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 your session / start a fresh session, then verify in a clean session." Verify state stays outstanding; the stage is never advanced on false assurance.
|
|
@@ -132,7 +132,7 @@ This applies whether the feature was named explicitly (`/feature-forge:forge {fe
|
|
|
132
132
|
When the named argument is an epic (`{specsDir}/{name}/epic-manifest.json` exists), render the epic dashboard instead of a per-feature one. Run:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
135
|
-
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')"
|
|
135
|
+
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')"
|
|
136
136
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
137
137
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
138
138
|
```
|
|
@@ -203,7 +203,7 @@ Support these sub-commands for pipeline lifecycle management:
|
|
|
203
203
|
|
|
204
204
|
- Set the manifest's top-level `status` (`paused` / `active` / `abandoned`) via the helper's `set-status` mutator — an atomic write that also bumps `updatedAt`:
|
|
205
205
|
```bash
|
|
206
|
-
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')"
|
|
206
|
+
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')"
|
|
207
207
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
208
208
|
python3 "$R/scripts/epic-manifest.py" set-status "{epic}" --status paused --specs-dir "{specsDir}"
|
|
209
209
|
```
|
|
@@ -38,7 +38,7 @@ checks but still load any on-disk artifacts.
|
|
|
38
38
|
plugin path and the configured specs dir:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
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')"
|
|
41
|
+
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')"
|
|
42
42
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
43
43
|
python3 "$R/scripts/epic-manifest.py" <subcommand> ... --specs-dir "{specsDir}"
|
|
44
44
|
```
|
|
@@ -72,7 +72,7 @@ Resolve the epic subtree path `{specsDir}/{epic}/` and decide which branch to ru
|
|
|
72
72
|
epic, confirm the epic name itself does not collide with any existing feature or epic:
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
|
-
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')"
|
|
75
|
+
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')"
|
|
76
76
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
77
77
|
python3 "$R/scripts/epic-manifest.py" check-name "{epic}" --specs-dir "{specsDir}"
|
|
78
78
|
```
|
|
@@ -116,7 +116,7 @@ For **each** proposed feature name, before accepting it into the set, enforce gl
|
|
|
116
116
|
and name safety via the helper:
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
|
-
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')"
|
|
119
|
+
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')"
|
|
120
120
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
121
121
|
python3 "$R/scripts/epic-manifest.py" check-name "{feature}" --specs-dir "{specsDir}"
|
|
122
122
|
```
|
|
@@ -176,7 +176,7 @@ For the *initial* creation write the skill writes the file directly — atomic g
|
|
|
176
176
|
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:
|
|
177
177
|
|
|
178
178
|
```bash
|
|
179
|
-
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')"
|
|
179
|
+
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')"
|
|
180
180
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
181
181
|
python3 "$R/scripts/epic-manifest.py" validate "{epic}" --specs-dir "{specsDir}" --json
|
|
182
182
|
```
|
|
@@ -236,34 +236,24 @@ now self-contained: manifest + EPIC.md + one subdirectory per member.
|
|
|
236
236
|
|
|
237
237
|
### Step C8 — Review, Pipeline State & Commit
|
|
238
238
|
|
|
239
|
-
1. **Review.** Present a summary (epic name, N features, dependency edges, contracts) as text,
|
|
240
|
-
then use the host's question mechanism: "Does this epic decomposition look right? Any feature, dependency,
|
|
241
|
-
or contract to change before I commit?" If the user wants changes, loop back to the relevant
|
|
242
|
-
creation step, re-compose, and re-validate.
|
|
239
|
+
1. **Review.** Present a summary (epic name, N features, dependency edges, contracts) as text, then use the host's question mechanism: "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.
|
|
243
240
|
|
|
244
|
-
2. **Commit (Git Commit Protocol).** If `gitCommitAfterStage` is true, follow the Git Commit
|
|
245
|
-
|
|
246
|
-
- Stage the whole epic subtree only: `git add {specsDir}/{epic}/` — never `git add -A`. This
|
|
247
|
-
captures `epic-manifest.json`, `EPIC.md`, and all member `.pipeline-state.json` files
|
|
248
|
-
atomically.
|
|
241
|
+
2. **Commit (Git Commit Protocol).** If `gitCommitAfterStage` is true, follow the Git Commit Protocol in shared-conventions:
|
|
242
|
+
- 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.
|
|
249
243
|
- Commit with message `"{commitPrefix}({epic}): create epic with {N} features"`.
|
|
250
|
-
- On success, capture the commit hash for the closing message only — the epic manifest has no
|
|
251
|
-
`commitHash` field, so nothing is written back into a committed file and the two-commit step of
|
|
252
|
-
the Git Commit Protocol does not apply here. On failure (pre-commit hook, conflict), report and
|
|
253
|
-
do not mark complete; never use `--amend`/`--no-verify`/`--force`.
|
|
244
|
+
- 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`.
|
|
254
245
|
|
|
255
246
|
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):
|
|
256
247
|
|
|
257
|
-
**
|
|
248
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
258
249
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
250
|
+
```bash
|
|
251
|
+
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')"
|
|
252
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
253
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{epic}" --stage forge-0-epic --next-feature "{first-actionable-feature}" --specs-dir "{specsDir}" --host generic
|
|
254
|
+
```
|
|
263
255
|
|
|
264
|
-
|
|
265
|
-
2. **Then clear your session / start a fresh session.** 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 your session / start a fresh session for you — you have to run it yourself.**
|
|
266
|
-
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.
|
|
256
|
+
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.**
|
|
267
257
|
|
|
268
258
|
---
|
|
269
259
|
|
|
@@ -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}" \
|
|
@@ -113,16 +113,15 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
113
113
|
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`.
|
|
114
114
|
4. **Close with the Stage Exit Protocol** (single-sourced in `references/stage-exit-protocol.md`; do not improvise a "Next steps" list):
|
|
115
115
|
|
|
116
|
-
**
|
|
116
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
```bash
|
|
119
|
+
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')"
|
|
120
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
121
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-1-prd --specs-dir "{specsDir}" --host generic
|
|
122
|
+
```
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
2. **Then clear your session / start a fresh session.** 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 your session / start a fresh session for you — you have to run it yourself.**
|
|
125
|
-
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.
|
|
124
|
+
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.**
|
|
126
125
|
|
|
127
126
|
## Gotchas
|
|
128
127
|
|
|
@@ -190,16 +190,15 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
190
190
|
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`.
|
|
191
191
|
4. **Close with the Stage Exit Protocol** (single-sourced in `references/stage-exit-protocol.md`; do not improvise a "Next steps" list):
|
|
192
192
|
|
|
193
|
-
**
|
|
193
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
194
194
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
```bash
|
|
196
|
+
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')"
|
|
197
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
198
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-2-tech --specs-dir "{specsDir}" --host generic
|
|
199
|
+
```
|
|
199
200
|
|
|
200
|
-
|
|
201
|
-
2. **Then clear your session / start a fresh session.** 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 your session / start a fresh session for you — you have to run it yourself.**
|
|
202
|
-
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.
|
|
201
|
+
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.**
|
|
203
202
|
|
|
204
203
|
## Gotchas
|
|
205
204
|
|
|
@@ -144,16 +144,15 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
144
144
|
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`.
|
|
145
145
|
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:
|
|
146
146
|
|
|
147
|
-
**
|
|
147
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
148
148
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
```bash
|
|
150
|
+
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')"
|
|
151
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
152
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-3-specs --specs-dir "{specsDir}" --host generic
|
|
153
|
+
```
|
|
153
154
|
|
|
154
|
-
|
|
155
|
-
2. **Then clear your session / start a fresh session.** 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 your session / start a fresh session for you — you have to run it yourself.**
|
|
156
|
-
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.
|
|
155
|
+
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.**
|
|
157
156
|
|
|
158
157
|
## Gotchas
|
|
159
158
|
|
|
@@ -138,16 +138,15 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`. Foll
|
|
|
138
138
|
4. If verification was available but the user chose to skip it, record `stages.forge-verify-backlog.status` as `"skipped"` in pipeline state.
|
|
139
139
|
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:
|
|
140
140
|
|
|
141
|
-
**
|
|
141
|
+
**Close this stage with the Scripted Stage Exit** (contract: `references/stage-exit-protocol.md`; do not improvise a "Next steps" list). Run:
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
```bash
|
|
144
|
+
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')"
|
|
145
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
146
|
+
python3 "$R/scripts/forge-session.py" stage-exit --feature "{feature}" --stage forge-4-backlog --specs-dir "{specsDir}" --host generic
|
|
147
|
+
```
|
|
147
148
|
|
|
148
|
-
|
|
149
|
-
2. **Then clear your session / start a fresh session.** 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 your session / start a fresh session for you — you have to run it yourself.**
|
|
150
|
-
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.
|
|
149
|
+
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.**
|
|
151
150
|
|
|
152
151
|
## Gotchas
|
|
153
152
|
|
|
@@ -60,7 +60,7 @@ Read the resolved feature's `.pipeline-state.json`. **If it has no `epic` key, s
|
|
|
60
60
|
1. Run `render-status "{epic}" --specs-dir "{specsDir}" --json` via the helper:
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
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')"
|
|
63
|
+
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')"
|
|
64
64
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
65
65
|
python3 "$R/scripts/epic-manifest.py" \
|
|
66
66
|
render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
@@ -281,7 +281,7 @@ Update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
|
281
281
|
|
|
282
282
|
**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:
|
|
283
283
|
|
|
284
|
-
1. **Verify feature {feature}'s loop first — if it isn't already verified.**
|
|
284
|
+
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 the host's question mechanism with exactly these three options — but only when the host has a question mechanism **and** the clean-room path is available (the host's subagent mechanism plus a dispatchable `forge-verifier` subagent):
|
|
285
285
|
- **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.
|
|
286
286
|
- **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.
|
|
287
287
|
- **Skip for now** — go straight to clear your session / start a fresh session 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.
|
|
@@ -292,7 +292,7 @@ Update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
|
292
292
|
|
|
293
293
|
## Gotchas
|
|
294
294
|
|
|
295
|
-
- **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`.
|
|
295
|
+
- **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`.
|
|
296
296
|
- `{backlogDir}` is a **directory path**, not a file path. Pass `specs/auth`, not `specs/auth/backlog.json`.
|
|
297
297
|
- 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.
|
|
298
298
|
- 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.
|
|
@@ -43,7 +43,7 @@ Check `.pipeline-state.json` for `stages.forge-verify-impl`. If it is **absent**
|
|
|
43
43
|
If the resolved feature has an `epic` back-pointer in its `.pipeline-state.json`, run:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
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')"
|
|
46
|
+
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')"
|
|
47
47
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
48
48
|
python3 "$R/scripts/epic-manifest.py" render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
49
49
|
```
|
|
@@ -58,7 +58,7 @@ Every bash invocation begins with the byte-identical portable-root prelude, then
|
|
|
58
58
|
helper. Pass `--specs-dir ./specs` (the default) so the gate allow-lists the specs directory.
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
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')"
|
|
61
|
+
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')"
|
|
62
62
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
63
63
|
python3 "$R/scripts/forge-bootstrap.py" check "<target-dir>" --json --specs-dir ./specs
|
|
64
64
|
```
|
|
@@ -135,7 +135,7 @@ when running under a Claude host (e.g. the host's question mechanism is availabl
|
|
|
135
135
|
`CLAUDE.md` only when `host == "claude"`.
|
|
136
136
|
|
|
137
137
|
```bash
|
|
138
|
-
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')"
|
|
138
|
+
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')"
|
|
139
139
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
140
140
|
python3 "$R/scripts/forge-bootstrap.py" scaffold "<target-dir>" --json --answers '<Answers JSON>'
|
|
141
141
|
```
|
|
@@ -143,7 +143,7 @@ python3 "$R/scripts/forge-bootstrap.py" scaffold "<target-dir>" --json --answers
|
|
|
143
143
|
### Step 5 — verify
|
|
144
144
|
|
|
145
145
|
```bash
|
|
146
|
-
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')"
|
|
146
|
+
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')"
|
|
147
147
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
148
148
|
python3 "$R/scripts/forge-bootstrap.py" verify "<target-dir>" --json --answers '<Answers JSON>'
|
|
149
149
|
```
|
|
@@ -169,7 +169,7 @@ and removes the sentinel before staging so it never enters history. Read
|
|
|
169
169
|
leave the sentinel in-progress (resumable) — do **not** declare success.
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
|
-
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')"
|
|
172
|
+
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')"
|
|
173
173
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
174
174
|
python3 "$R/scripts/forge-bootstrap.py" commit "<target-dir>" --json --answers '<Answers JSON>' [--stage-only]
|
|
175
175
|
```
|
|
@@ -8,14 +8,16 @@ description: Apply fixes from the most recent forge-verify findings document. Us
|
|
|
8
8
|
|
|
9
9
|
Apply fixes from the most recent forge-verify findings document, with step-level tracking for crash recovery.
|
|
10
10
|
|
|
11
|
-
Usually invoked by the user, but
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
navigator
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
Usually invoked by the user, but an **`autoFix` caller** may also invoke this skill automatically
|
|
12
|
+
when `autoFix: true` is configured **and** its preconditions hold (the findings document has zero
|
|
13
|
+
unresolved decision points, the working tree is clean, and a mandatory re-verify passes afterward).
|
|
14
|
+
Two callers drive that chain: an **authoring stage's in-stage auto-verify** (the primary path — see
|
|
15
|
+
`references/stage-exit-protocol.md`, the in-stage verify block) and the **`/feature-forge:forge`
|
|
16
|
+
navigator's catch-up** (§3b). The **fix application** below is identical either way — this skill is
|
|
17
|
+
not "auto-aware" about *applying* findings; it always applies the latest findings document. The
|
|
18
|
+
**caller** owns the gating decisions, including the closing re-verify: the Step 6 gate is presented
|
|
19
|
+
**only on a direct invocation**, because under an `autoFix` chain the caller (stage skill or
|
|
20
|
+
navigator) runs the mandatory re-verify itself.
|
|
19
21
|
|
|
20
22
|
## Prerequisites
|
|
21
23
|
|
|
@@ -75,7 +77,7 @@ Follow the Git Commit Protocol in `references/shared-conventions.md`.
|
|
|
75
77
|
|
|
76
78
|
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`).
|
|
77
79
|
|
|
78
|
-
**Skip this gate when
|
|
80
|
+
**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.
|
|
79
81
|
|
|
80
82
|
On a direct invocation, present the gate using the host's question mechanism with these three options — but only when the host has a question mechanism **and** the clean-room path is available (the host's subagent mechanism plus a dispatchable `forge-verifier` subagent):
|
|
81
83
|
- **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.
|
|
@@ -103,7 +103,7 @@ green baseline. On non-Claude agents, install via `npx @garygentry/feature-forge
|
|
|
103
103
|
- **Stack** — `stack`, `typeCheckCommand`, `testCommand`: null until Stage 2 auto-detects them.
|
|
104
104
|
- **Context** — `contextWindowTokens`, `contextWarnThreshold` (0.7): the navigator warns to
|
|
105
105
|
clear your session / start a fresh session past this fullness. On 1M-context models set `contextWindowTokens` explicitly.
|
|
106
|
-
- **Verification** — `autoVerify` (false), `autoVerifyStages`, `autoFix` (false).
|
|
106
|
+
- **Verification** — `autoVerify` (false; when on, each authoring stage verifies in-stage before its exit block), `autoVerifyStages`, `autoFix` (false).
|
|
107
107
|
- **Stage flow** — `autoInvokeNextStage` (true on Claude, print-only elsewhere).
|
|
108
108
|
- **Loop** — `loopRunner` block (binary, command templates, version gate, agent selection);
|
|
109
109
|
defaults to **rauf** when absent. `workspaces` supports monorepos.
|
|
@@ -113,8 +113,11 @@ green baseline. On non-Claude agents, install via `npx @garygentry/feature-forge
|
|
|
113
113
|
`forge-verify <feature>` dispatches the read-only `forge-verifier` subagent to find gaps,
|
|
114
114
|
inconsistencies, and quality issues; it writes a findings doc, and `forge-fix` applies them.
|
|
115
115
|
Because verification runs in a **fresh subagent**, it's clean-room by construction — it never
|
|
116
|
-
needs a clear your session / start a fresh session, and it's safe to automate with `autoVerify: true
|
|
117
|
-
|
|
116
|
+
needs a clear your session / start a fresh session, and it's safe to automate with `autoVerify: true`. When on, the just-completed
|
|
117
|
+
authoring stage runs verify **in-stage** — in the same session, right before its exit block — so
|
|
118
|
+
the digest and any fix land where the context still exists (the navigator only catches up if a
|
|
119
|
+
host couldn't run it clean-room). Fixing stays human-gated unless `autoFix: true`. The cost is one
|
|
120
|
+
extra clean-room verify per stage. **Always verify before Stage 5 (the loop)** — catching errors in
|
|
118
121
|
specs/backlog is far cheaper than mid-loop. Verifying after PRD and after backlog is also
|
|
119
122
|
recommended. A findings pass is fresh only while the artifact `version` matches what was
|
|
120
123
|
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 host's question mechanism 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 your session / start a fresh session 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**.
|
|
@@ -248,7 +248,7 @@ Do NOT mark as `findings-applied` — that happens after the fix pass.
|
|
|
248
248
|
- For specs verification, also run the deterministic traceability validator to supplement agent-driven traceability checks. Include any uncovered requirements or orphaned references as findings:
|
|
249
249
|
|
|
250
250
|
```bash
|
|
251
|
-
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')"
|
|
251
|
+
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')"
|
|
252
252
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
253
253
|
python3 "$R/scripts/validate-traceability.py" {resolvedFeatureDir}/PRD.md {resolvedFeatureDir}/ --json
|
|
254
254
|
```
|
|
@@ -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
|
```
|