@garygentry/feature-forge 0.1.3 → 0.1.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/README.md +1 -1
- package/adapters/GENERATION-REPORT.md +5 -1
- package/adapters/claude/references/forge-config-schema.json +36 -10
- package/adapters/claude/references/pipeline-state-schema.json +4 -0
- package/adapters/claude/references/process-overview.md +14 -4
- package/adapters/claude/references/shared-conventions.md +46 -0
- package/adapters/claude/references/templates/specs-hygiene/AGENTS.md +23 -0
- package/adapters/claude/references/templates/specs-hygiene/CLAUDE.md +22 -0
- package/adapters/claude/skills/forge-0-epic/SKILL.md +7 -5
- package/adapters/claude/skills/forge-1-prd/SKILL.md +4 -2
- package/adapters/claude/skills/forge-5-loop/SKILL.md +18 -16
- package/adapters/claude/skills/forge-5-loop/references/result-reporting.md +13 -0
- package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +40 -0
- package/adapters/claude/skills/forge-6-docs/SKILL.md +10 -0
- package/adapters/claude/skills/forge-bootstrap/SKILL.md +240 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/go/main.go +12 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
- package/adapters/claude/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
- package/adapters/codex/references/forge-config-schema.json +36 -10
- package/adapters/codex/references/pipeline-state-schema.json +4 -0
- package/adapters/codex/references/process-overview.md +14 -4
- package/adapters/codex/references/shared-conventions.md +46 -0
- package/adapters/codex/references/templates/specs-hygiene/AGENTS.md +23 -0
- package/adapters/codex/references/templates/specs-hygiene/CLAUDE.md +22 -0
- package/adapters/codex/skills/forge-0-epic/forge-0-epic.md +7 -5
- package/adapters/codex/skills/forge-1-prd/forge-1-prd.md +4 -2
- package/adapters/codex/skills/forge-5-loop/forge-5-loop.md +18 -16
- package/adapters/codex/skills/forge-5-loop/references/result-reporting.md +13 -0
- package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +40 -0
- package/adapters/codex/skills/forge-6-docs/forge-6-docs.md +10 -0
- package/adapters/codex/skills/forge-bootstrap/forge-bootstrap.md +239 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/go/main.go +12 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
- package/adapters/codex/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
- package/adapters/copilot/references/forge-config-schema.json +36 -10
- package/adapters/copilot/references/pipeline-state-schema.json +4 -0
- package/adapters/copilot/references/process-overview.md +14 -4
- package/adapters/copilot/references/shared-conventions.md +46 -0
- package/adapters/copilot/references/templates/specs-hygiene/AGENTS.md +23 -0
- package/adapters/copilot/references/templates/specs-hygiene/CLAUDE.md +22 -0
- package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +7 -5
- package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +4 -2
- package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +18 -16
- package/adapters/copilot/skills/forge-5-loop/references/result-reporting.md +13 -0
- package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +40 -0
- package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +10 -0
- package/adapters/copilot/skills/forge-bootstrap/forge-bootstrap.md +239 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/go/main.go +12 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
- package/adapters/copilot/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
- package/adapters/cursor/references/forge-config-schema.json +36 -10
- package/adapters/cursor/references/pipeline-state-schema.json +4 -0
- package/adapters/cursor/references/process-overview.md +14 -4
- package/adapters/cursor/references/shared-conventions.md +46 -0
- package/adapters/cursor/references/templates/specs-hygiene/AGENTS.md +23 -0
- package/adapters/cursor/references/templates/specs-hygiene/CLAUDE.md +22 -0
- package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +7 -5
- package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +4 -2
- package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +18 -16
- package/adapters/cursor/skills/forge-5-loop/references/result-reporting.md +13 -0
- package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +40 -0
- package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +10 -0
- package/adapters/cursor/skills/forge-bootstrap/forge-bootstrap.mdc +240 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/go/main.go +12 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
- package/adapters/cursor/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
- package/adapters/gemini/gemini-extension.json +4 -0
- package/adapters/gemini/references/forge-config-schema.json +36 -10
- package/adapters/gemini/references/pipeline-state-schema.json +4 -0
- package/adapters/gemini/references/process-overview.md +14 -4
- package/adapters/gemini/references/shared-conventions.md +46 -0
- package/adapters/gemini/references/templates/specs-hygiene/AGENTS.md +23 -0
- package/adapters/gemini/references/templates/specs-hygiene/CLAUDE.md +22 -0
- package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +7 -5
- package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +4 -2
- package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +18 -16
- package/adapters/gemini/skills/forge-5-loop/references/result-reporting.md +13 -0
- package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +40 -0
- package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +10 -0
- package/adapters/gemini/skills/forge-bootstrap/forge-bootstrap.md +239 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/go/main.go +12 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +24 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +25 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
- package/adapters/gemini/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
- package/dist/cli.js +15 -2
- package/dist/manifest.d.ts +1 -1
- package/dist/rauf.d.ts +4 -4
- package/dist/rauf.js +3 -3
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "{{PURPOSE}}",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"typecheck": "tsc --noEmit",
|
|
9
|
+
"test": "vitest run"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"typescript": "^5.4.0",
|
|
13
|
+
"vitest": "^1.6.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noEmit": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"types": ["vitest/globals"]
|
|
12
|
+
},
|
|
13
|
+
"include": ["src", "test"]
|
|
14
|
+
}
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"description": "Root directory for generated architecture documentation."
|
|
16
16
|
},
|
|
17
17
|
"backlogDir": {
|
|
18
|
-
"type": "string",
|
|
19
|
-
"description": "Optional override for backlog location. If set, backlog.json is written here instead of with the feature specs. Default behavior: backlog.json is written to {specsDir}/{feature}/backlog.json."
|
|
18
|
+
"type": ["string", "null"],
|
|
19
|
+
"description": "Optional override for backlog location. If set, backlog.json is written here instead of with the feature specs. Default behavior (null): backlog.json is written to {specsDir}/{feature}/backlog.json."
|
|
20
20
|
},
|
|
21
21
|
"gitCommitAfterStage": {
|
|
22
22
|
"type": "boolean",
|
|
@@ -28,17 +28,27 @@
|
|
|
28
28
|
"default": "forge",
|
|
29
29
|
"description": "Prefix for conventional commit messages, e.g., forge(auth): complete PRD"
|
|
30
30
|
},
|
|
31
|
-
"
|
|
31
|
+
"branchPerFeature": {
|
|
32
|
+
"type": "boolean",
|
|
33
|
+
"default": true,
|
|
34
|
+
"description": "Offer to create an isolated git branch when a feature/epic starts on the default branch (main/master). Gated only on the project using git — independent of gitCommitAfterStage. When false, forge never prompts for a branch and works on whatever branch is checked out. See the Branch Setup block in references/shared-conventions.md."
|
|
35
|
+
},
|
|
36
|
+
"branchPrefix": {
|
|
32
37
|
"type": "string",
|
|
33
|
-
"
|
|
38
|
+
"default": "forge/",
|
|
39
|
+
"description": "Prefix for the branch name suggested by Branch Setup, e.g. 'forge/' yields 'forge/{feature}' or 'forge/{epic}'. Ignored when branchPerFeature is false."
|
|
40
|
+
},
|
|
41
|
+
"stack": {
|
|
42
|
+
"type": ["string", "null"],
|
|
43
|
+
"description": "Detected or configured project stack identifier. Selects guidance from references/stacks/{stack}.md. Set during forge-2-tech or manually (null until then). Examples: 'typescript', 'python', 'go', 'rust'."
|
|
34
44
|
},
|
|
35
45
|
"typeCheckCommand": {
|
|
36
|
-
"type": "string",
|
|
37
|
-
"description": "Command to verify type correctness or lint. Examples: 'bun run typecheck', 'mypy .', 'go vet ./...'. Used in acceptance criteria and verification."
|
|
46
|
+
"type": ["string", "null"],
|
|
47
|
+
"description": "Command to verify type correctness or lint. Null until set. Examples: 'bun run typecheck', 'mypy .', 'go vet ./...'. Used in acceptance criteria and verification."
|
|
38
48
|
},
|
|
39
49
|
"testCommand": {
|
|
40
|
-
"type": "string",
|
|
41
|
-
"description": "Command to run tests. Examples: 'bun test', 'pytest', 'go test ./...'. Used in acceptance criteria and verification."
|
|
50
|
+
"type": ["string", "null"],
|
|
51
|
+
"description": "Command to run tests. Null until set. Examples: 'bun test', 'pytest', 'go test ./...'. Used in acceptance criteria and verification."
|
|
42
52
|
},
|
|
43
53
|
"loopIterationMultiplier": {
|
|
44
54
|
"type": "number",
|
|
@@ -46,6 +56,22 @@
|
|
|
46
56
|
"minimum": 1,
|
|
47
57
|
"description": "Multiplier applied to pending backlog item count to calculate loop iterations. Higher values allow more retries. Default: 1.5 (e.g., 10 items = 15 iterations)."
|
|
48
58
|
},
|
|
59
|
+
"workspaces": {
|
|
60
|
+
"type": "array",
|
|
61
|
+
"description": "Monorepo members. Absent for single-package projects.",
|
|
62
|
+
"items": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"required": ["name", "path", "stack"],
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"properties": {
|
|
67
|
+
"name": {"type": "string"},
|
|
68
|
+
"path": {"type": "string", "description": "Repo-relative member dir"},
|
|
69
|
+
"stack": {"type": "string"},
|
|
70
|
+
"typeCheckCommand": {"type": ["string", "null"]},
|
|
71
|
+
"testCommand": {"type": ["string", "null"]}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
49
75
|
"loopRunner": {
|
|
50
76
|
"type": "object",
|
|
51
77
|
"description": "The autonomous loop runner feature-forge drives. Defaults to rauf when absent (forge-5 states 'defaulting to rauf loop runner'). Every command is a template — {bin}, {backlogDir}, {specsDir}, {iterations} are substituted at call time — so an alternative ralph-style runner conforming to rauf's SPEC-BACKLOG-TOOL-CONTRACT.md can be swapped in without editing any skill. See references/ralph-loop-contract.md.",
|
|
@@ -147,8 +173,8 @@
|
|
|
147
173
|
},
|
|
148
174
|
"installHint": {
|
|
149
175
|
"type": "string",
|
|
150
|
-
"default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.
|
|
151
|
-
"description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.
|
|
176
|
+
"default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.8.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.8.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
|
|
177
|
+
"description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.8.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
|
|
152
178
|
},
|
|
153
179
|
"schemaVersion": {
|
|
154
180
|
"type": "string",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"type": "string",
|
|
19
19
|
"description": "Back-pointer to the owning epic's name. Absent for standalone features. The epic-manifest.json is canonical on conflict (REQ-STATE-01)."
|
|
20
20
|
},
|
|
21
|
+
"branch": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Git branch this feature's pipeline work is intended to land on, recorded by the Branch Setup block (shared-conventions.md) at the entry stage. Absent when the project isn't a git repo or branchPerFeature is false. Downstream stages and forge-5-loop compare the current branch against this to detect drift back onto the default branch before committing."
|
|
24
|
+
},
|
|
21
25
|
"createdAt": {
|
|
22
26
|
"type": "string",
|
|
23
27
|
"format": "date-time"
|
|
@@ -2,12 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This document describes the end-to-end feature development pipeline managed by the feature-forge plugin. All forge skills reference this document to understand the overall flow and their position within it.
|
|
4
4
|
|
|
5
|
+
The pipeline compiles a fuzzy feature idea into a machine-executable `backlog.json`. Each stage narrows the idea down and adds structure, verification gates catch gaps before they reach later stages, and a swappable autonomous loop runner (rauf by default) implements the backlog in fresh per-item sessions.
|
|
6
|
+
|
|
5
7
|
## Pipeline Stages
|
|
6
8
|
|
|
7
9
|
```
|
|
8
|
-
forge-1-prd → forge-2-tech → forge-3-specs → forge-verify → forge-4-backlog → forge-verify → forge-5-loop → forge-verify → forge-6-docs
|
|
10
|
+
[forge-0-epic] → forge-1-prd → forge-2-tech → forge-3-specs → forge-verify → forge-4-backlog → forge-verify → forge-5-loop → forge-verify → forge-6-docs
|
|
11
|
+
(optional)
|
|
9
12
|
```
|
|
10
13
|
|
|
14
|
+
### Stage 0: Epic (`/feature-forge:forge-0-epic <epic>`), optional
|
|
15
|
+
**Input:** A change too large for one feature
|
|
16
|
+
**Output:** `{specsDir}/{epic}/epic-manifest.json` + `EPIC.md` + one member-feature dir per feature
|
|
17
|
+
**Method:** Decomposition interview splitting the change into member features with declared dependencies and `exposes`/`consumes` contracts. Purely additive: single-feature flows are unchanged. See [docs/architecture/epic-orchestration/README.md](../docs/architecture/epic-orchestration/README.md).
|
|
18
|
+
|
|
11
19
|
### Stage 1: PRD (`/feature-forge:forge-1-prd <feature>`)
|
|
12
20
|
**Input:** User's feature idea and domain knowledge
|
|
13
21
|
**Output:** `{specsDir}/{feature}/PRD.md`
|
|
@@ -35,13 +43,13 @@ After verification, fixes can be applied via:
|
|
|
35
43
|
|
|
36
44
|
### Stage 4: Backlog (`/feature-forge:forge-4-backlog <feature>`)
|
|
37
45
|
**Input:** Full spec suite
|
|
38
|
-
**Output:** `{specsDir}/{feature}/backlog.json` (or `{backlogDir}/backlog.json` if backlogDir is configured)
|
|
46
|
+
**Output:** `{specsDir}/{feature}/backlog.json` (or `{backlogDir}/{feature}/backlog.json` if backlogDir is configured)
|
|
39
47
|
**Method:** Generate structured backlog items with spec references, acceptance criteria, and dependencies. Backlog is collocated with feature specs by default.
|
|
40
48
|
|
|
41
49
|
### Stage 5: Rauf Loop (`/feature-forge:forge-5-loop <feature>`)
|
|
42
50
|
**Input:** `backlog.json` from Stage 4
|
|
43
51
|
**Output:** Implemented source code (committed per-item by rauf)
|
|
44
|
-
**Method:** Execute the
|
|
52
|
+
**Method:** Execute the autonomous coding loop against the feature's backlog. Spawns a fresh session per backlog item with full spec context. rauf is the default runner but is swappable via the `loopRunner` block in `forge.config.json`; see [`references/ralph-loop-contract.md`](./ralph-loop-contract.md).
|
|
45
53
|
|
|
46
54
|
### Stage 6: Documentation (`/feature-forge:forge-6-docs <feature>`)
|
|
47
55
|
**Input:** Specs + implementation
|
|
@@ -71,7 +79,9 @@ Read `forge.config.json` from project root for path overrides. See `references/f
|
|
|
71
79
|
|
|
72
80
|
## Git Workflow
|
|
73
81
|
|
|
74
|
-
Recommended:
|
|
82
|
+
Recommended: forge work lives on an isolated `forge/{feature}` (or `forge/{epic}`) branch so all commits land together and review as one branch. The entry stages (`forge-1-prd`, `forge-0-epic`) detect whether you're on the default branch (main/master) and **strongly recommend** creating that branch when you are — still letting you decline and stay. The chosen branch is recorded in `.pipeline-state.json`, and `forge-5-loop` re-checks it before the autonomous loop starts committing per item. After implementation, merge to your development branch.
|
|
83
|
+
|
|
84
|
+
To customize: `branchPrefix` (default `forge/`) sets the branch name, and `branchPerFeature: false` disables the prompt entirely (forge then works on whatever branch is checked out). Branch Setup is gated only on the project using git — independent of `gitCommitAfterStage`.
|
|
75
85
|
|
|
76
86
|
If you prefer manual commit control, set `gitCommitAfterStage: false` in `forge.config.json`.
|
|
77
87
|
|
|
@@ -48,6 +48,8 @@ Extract these config values (use defaults if not present):
|
|
|
48
48
|
- `backlogDir` (default: null — backlog lives at `{specsDir}/{feature}/backlog.json`; when `backlogDir` is configured, forge-4 composes `{backlogDir}/{feature}/`)
|
|
49
49
|
- `gitCommitAfterStage` (default: true)
|
|
50
50
|
- `commitPrefix` (default: `forge`)
|
|
51
|
+
- `branchPerFeature` (default: true)
|
|
52
|
+
- `branchPrefix` (default: `forge/`)
|
|
51
53
|
- `loopIterationMultiplier` (default: `1.5`)
|
|
52
54
|
- `loopRunner` (optional object — the loop runner to drive; **defaults to rauf** when absent, with every command templated. See `references/forge-config-schema.json` and `references/ralph-loop-contract.md`.)
|
|
53
55
|
|
|
@@ -79,6 +81,27 @@ A directory counts as a **feature** only if it directly contains a `.pipeline-st
|
|
|
79
81
|
|
|
80
82
|
**Compatibility:** for a standalone feature the resolver returns its flat path with no epic logic engaged (REQ-COMPAT-01/02) — standalone-feature behavior is unchanged. A pre-existing latent name collision is reported for manual cleanup by the navigator / forge-verify epic mode (CHECK-E08), not by aborting an unrelated command whose name resolves to exactly one dir (tech-spec §3.4).
|
|
81
83
|
|
|
84
|
+
## Specs Directory Hygiene
|
|
85
|
+
|
|
86
|
+
Whenever a stage creates the specs tree for the first time (the first PRD or epic written under `{specsDir}/`), ensure a spec-directory agent-instruction file exists at the **specsDir root**. This tells coding agents in the project that the specs here are pre-implementation artifacts — not live contracts to enforce against the code. It is **idempotent: never overwrite an existing file** (the project may have edited it).
|
|
87
|
+
|
|
88
|
+
Run this after creating the feature/epic directory, before the stage's git commit:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
|
|
92
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
93
|
+
mkdir -p "<specsDir>"
|
|
94
|
+
[ -f "<specsDir>/AGENTS.md" ] || cp "$R/references/templates/specs-hygiene/AGENTS.md" "<specsDir>/AGENTS.md"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If the host is Claude (the `AskUserQuestion` tool is available), also ensure the Claude-framed variant:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
[ -f "<specsDir>/CLAUDE.md" ] || cp "$R/references/templates/specs-hygiene/CLAUDE.md" "<specsDir>/CLAUDE.md"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Stage any file this writes (`{specsDir}/AGENTS.md`, and `{specsDir}/CLAUDE.md` when written) as part of the stage's existing git commit.
|
|
104
|
+
|
|
82
105
|
## Epic Context Injection
|
|
83
106
|
|
|
84
107
|
After resolving the feature directory, check the feature's `.pipeline-state.json` for an `epic` back-pointer. **If absent, skip this block entirely** (standalone feature — REQ-COMPAT-01; standalone-feature behavior is unchanged). **If present**, load exactly the following context, and nothing transitive (REQ-CTX-01):
|
|
@@ -110,6 +133,29 @@ When loading upstream artifacts as prerequisites, check `basedOnVersions` in the
|
|
|
110
133
|
|
|
111
134
|
> "This stage was built against {upstream} v{old}, but {upstream} is now at v{new}. The current artifacts may be outdated. Consider re-running this stage, or use --force to proceed with potentially stale inputs."
|
|
112
135
|
|
|
136
|
+
## Branch Setup
|
|
137
|
+
|
|
138
|
+
Invoke this block at the **very start** of a pipeline entry point — `forge-1-prd` (standalone feature) and `forge-0-epic` (epic) — **before** any directory resolution or interview, so the rest of the run lands on the intended branch. `{label}` is the feature name (forge-1-prd) or epic name (forge-0-epic); `{scope}` is `feature` or `epic` correspondingly.
|
|
139
|
+
|
|
140
|
+
**Gate.** Run this block only when the project uses git (a `.git` directory resolves) **and** `branchPerFeature` is true. It is **independent of `gitCommitAfterStage`** — branch isolation matters whether or not forge auto-commits. If `branchPerFeature` is false, skip silently.
|
|
141
|
+
|
|
142
|
+
**Epic-member inheritance.** In `forge-1-prd`, if the feature has an `epic` back-pointer (an `epic` field resolves via Epic Context Injection, or the directory is nested under an epic), the epic already established the branch in `forge-0-epic`. Skip the prompt — inherit the current branch.
|
|
143
|
+
|
|
144
|
+
**Detection, then a branch-aware prompt:**
|
|
145
|
+
|
|
146
|
+
1. Read the current branch: `git rev-parse --abbrev-ref HEAD`.
|
|
147
|
+
2. Determine the default branch: `git symbolic-ref --quiet refs/remotes/origin/HEAD` (strip to the last path segment); if that fails, fall back to `main`, else `master` — whichever the repo has.
|
|
148
|
+
3. **If the current branch is NOT the default branch** (the user is already on a topic/`{branchPrefix}*` branch) → record it (see below) and proceed silently. Do not prompt.
|
|
149
|
+
4. **If the current branch IS the default branch** → use `AskUserQuestion` with a **strong recommendation** (still optional):
|
|
150
|
+
|
|
151
|
+
> "You're on `{defaultBranch}`. Strongly recommended: create `{branchPrefix}{label}` so this {scope}'s work stays isolated and reviewable as one branch. Create it?"
|
|
152
|
+
> Options: **Create `{branchPrefix}{label}` (recommended)** · **Stay on `{defaultBranch}`**
|
|
153
|
+
|
|
154
|
+
- **Create** → `git switch -c {branchPrefix}{label}` (or `git checkout -b` if `switch` is unavailable). If the branch already exists, `git switch {branchPrefix}{label}`.
|
|
155
|
+
- **Stay** → proceed on the default branch; note that subsequent commits (and any `forge-5-loop` run) will land directly on `{defaultBranch}`.
|
|
156
|
+
|
|
157
|
+
**Record the branch.** After this block resolves, write the resulting branch name to the feature's `.pipeline-state.json` top-level `branch` field (create/update it when the state file is first written for this stage). Downstream stages and `forge-5-loop` read it to detect drift back onto the default branch.
|
|
158
|
+
|
|
113
159
|
## Git Commit Protocol
|
|
114
160
|
|
|
115
161
|
When `gitCommitAfterStage` is true, follow this exact order to avoid state inconsistency:
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Agent Instructions — `specs/` (feature-forge)
|
|
2
|
+
|
|
3
|
+
This directory holds **pre-implementation design artifacts** produced by the
|
|
4
|
+
feature-forge pipeline (PRDs, technical specs, numbered implementation specs,
|
|
5
|
+
traceability matrices, and per-feature `backlog.json` files).
|
|
6
|
+
|
|
7
|
+
## How to treat these specs
|
|
8
|
+
|
|
9
|
+
- **Specs are not live contracts.** They exist to plan the work and establish the
|
|
10
|
+
backlog. They are intentionally **not kept in sync** with the implementation as
|
|
11
|
+
the code evolves.
|
|
12
|
+
- **Do not flag spec↔code divergence.** Once a spec is finalized and its backlog has
|
|
13
|
+
been implemented, the code is the source of truth for behavior. Do not "fix" the
|
|
14
|
+
implementation to match a spec, or the spec to match the code, unless a human
|
|
15
|
+
explicitly asks for it.
|
|
16
|
+
- **Read freely; reference deliberately.** It is fine — encouraged, even — for
|
|
17
|
+
pipeline artifacts here (specs, `backlog.json`) to cite each other for provenance
|
|
18
|
+
and context. But implementation artifacts shipped into the project (source code,
|
|
19
|
+
generated skills/agents, configs, docs) should be self-contained and should **not**
|
|
20
|
+
reference files under `specs/`, which may be archived or deleted after a feature
|
|
21
|
+
ships.
|
|
22
|
+
|
|
23
|
+
This file was generated by feature-forge. Edit or remove it to suit your project.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Claude Instructions — `specs/` (feature-forge)
|
|
2
|
+
|
|
3
|
+
This directory holds **pre-implementation design artifacts** produced by the
|
|
4
|
+
feature-forge pipeline (PRDs, technical specs, numbered implementation specs,
|
|
5
|
+
traceability matrices, and per-feature `backlog.json` files).
|
|
6
|
+
|
|
7
|
+
## How to treat these specs
|
|
8
|
+
|
|
9
|
+
- **Specs are not live contracts.** They exist to plan the work and establish the
|
|
10
|
+
backlog. They are intentionally **not kept in sync** with the implementation as
|
|
11
|
+
the code evolves.
|
|
12
|
+
- **Do not flag spec↔code divergence.** Once a spec is finalized and its backlog has
|
|
13
|
+
been implemented, the code is the source of truth for behavior. Don't "fix" the
|
|
14
|
+
implementation to match a spec, or the spec to match the code, unless I explicitly
|
|
15
|
+
ask you to.
|
|
16
|
+
- **Read freely; reference deliberately.** It's fine — encouraged, even — for pipeline
|
|
17
|
+
artifacts here (specs, `backlog.json`) to cite each other for provenance and context.
|
|
18
|
+
But implementation artifacts shipped into the project (source code, generated
|
|
19
|
+
skills/agents, configs, docs) should be self-contained and should **not** reference
|
|
20
|
+
files under `specs/`, which may be archived or deleted after a feature ships.
|
|
21
|
+
|
|
22
|
+
This file was generated by feature-forge. Edit or remove it to suit your project.
|
|
@@ -87,11 +87,13 @@ python3 "$R/scripts/epic-manifest.py" check-name "{epic}" --specs-dir "{specsDir
|
|
|
87
87
|
|
|
88
88
|
## Creation Branch
|
|
89
89
|
|
|
90
|
-
### Step 1 — Branch Setup
|
|
90
|
+
### Step 1 — Branch Setup
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
Invoke the **Branch Setup** block in `references/shared-conventions.md` with `{label}` = `{epic}` and
|
|
93
|
+
`{scope}` = `epic`. It self-gates (skips when not a git repo or when `branchPerFeature` is false),
|
|
94
|
+
detects whether you're on the default branch, and strongly recommends — still optionally — creating
|
|
95
|
+
`{branchPrefix}{epic}` when you are. Each member feature's `forge-1-prd` inherits this branch rather
|
|
96
|
+
than prompting again.
|
|
95
97
|
|
|
96
98
|
### Step C1 — Epic Framing Interview
|
|
97
99
|
|
|
@@ -176,7 +178,7 @@ Compose the full `epic-manifest.json` per the 00 §2 schema, setting:
|
|
|
176
178
|
|
|
177
179
|
Write the composed JSON to `{specsDir}/{epic}/epic-manifest.json` (creating the epic dir first).
|
|
178
180
|
For the *initial* creation write the skill writes the file directly — atomic guarantees are only
|
|
179
|
-
required for in-place mutation, which is the helper mutators' job. Then validate:
|
|
181
|
+
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:
|
|
180
182
|
|
|
181
183
|
```bash
|
|
182
184
|
R="$(for d in "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/*/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done)"
|
|
@@ -16,7 +16,7 @@ Read and follow `references/shared-conventions.md` for feature name validation,
|
|
|
16
16
|
## Step 1: Read Configuration and Check State
|
|
17
17
|
|
|
18
18
|
### Branch Setup (if using git)
|
|
19
|
-
|
|
19
|
+
Invoke the **Branch Setup** block in `references/shared-conventions.md` with `{label}` = `{feature}` and `{scope}` = `feature`. It self-gates (skips when not a git repo, when `branchPerFeature` is false, or for an epic member that inherits the epic's branch), detects whether you're on the default branch, and strongly recommends — still optionally — creating `{branchPrefix}{feature}` when you are. Do this before directory resolution.
|
|
20
20
|
|
|
21
21
|
Set the working directory by invoking the **Feature Directory Resolution** block in `references/shared-conventions.md`, which yields `{resolvedFeatureDir}`. Note one PRD-specific caveat: at PRD time a brand-new standalone feature may have NO directory yet, so resolution is expected to fail `not-found` for a never-started standalone feature — in that case forge-1 creates `{specsDir}/{feature}/` as today. For an epic member the directory already exists (created empty by forge-0-epic with an `epic` back-pointer), so resolution succeeds and yields the nested path.
|
|
22
22
|
|
|
@@ -87,6 +87,8 @@ Once the interview is thorough, write `{resolvedFeatureDir}/PRD.md` following th
|
|
|
87
87
|
|
|
88
88
|
Every requirement MUST have a unique ID (e.g., REQ-AUTH-01, REQ-PERF-01). These IDs are referenced by all downstream documents.
|
|
89
89
|
|
|
90
|
+
After writing the PRD (this is the point where `{specsDir}/{feature}/` is first created for a standalone feature), invoke the **Specs Directory Hygiene** block in `references/shared-conventions.md` to ensure `{specsDir}/AGENTS.md` (and `{specsDir}/CLAUDE.md` on the Claude host) exists. It is idempotent — it never overwrites an existing file.
|
|
91
|
+
|
|
90
92
|
## Step 5: Review with User
|
|
91
93
|
|
|
92
94
|
Present the complete PRD to the user. Ask:
|
|
@@ -110,7 +112,7 @@ Write pipeline state conforming to `references/pipeline-state-schema.json`.
|
|
|
110
112
|
- Check downstream stages (`forge-2-tech`, `forge-3-specs`, `forge-4-backlog`, `forge-5-loop`, `forge-6-docs`). If any have `basedOnVersions` referencing an older version of `forge-1-prd`, set their status to `stale`.
|
|
111
113
|
2. Use `AskUserQuestion` to ask: "Anything you want to note before we wrap? (preserved across sessions)"
|
|
112
114
|
- If yes, store in the `notes` field
|
|
113
|
-
3. If `gitCommitAfterStage` is true, follow the Git Commit Protocol in `references/shared-conventions.md`: stage files, attempt commit with message `"{commitPrefix}({feature}): complete PRD v{n}"`, then set `stages.forge-1-prd.status` to `complete` with commit hash only on success. If commit fails, leave status as `in-progress`.
|
|
115
|
+
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}"`, then set `stages.forge-1-prd.status` to `complete` with commit hash only on success. If commit fails, leave status as `in-progress`.
|
|
114
116
|
5. Tell the user: "PRD complete. Next steps:\n - `/feature-forge:forge-verify {feature}` to verify the PRD\n - `/feature-forge:forge-2-tech {feature}` to start the tech spec\n - `/feature-forge:forge {feature}` to see full pipeline status"
|
|
115
117
|
|
|
116
118
|
## Gotchas
|
|
@@ -101,13 +101,8 @@ For the version-too-old case, phrase it concretely, e.g.: "Your rauf is {reporte
|
|
|
101
101
|
|
|
102
102
|
Check that `loopRunner.preconditionFile` (default `.rauf.json`) exists in the project root. If not:
|
|
103
103
|
|
|
104
|
-
- **If `loopRunner.name == "rauf"` and a legacy `.ralph.json` (or `.ralph/` directory) exists**, this is an un-migrated Ralph project. STOP
|
|
105
|
-
|
|
106
|
-
"This project is still on the legacy **Ralph** layout. Run `rauf migrate .` first (the loop runner only understands `.rauf/` and `RAUF_*` signals), then re-run `/feature-forge:forge-5-loop {feature}`."
|
|
107
|
-
|
|
108
|
-
- **Otherwise**, STOP and show `loopRunner.setupHint` (default: "Run `rauf install .` …"), e.g.:
|
|
109
|
-
|
|
110
|
-
"The loop runner isn't set up in this project ({preconditionFile} is missing). {setupHint}"
|
|
104
|
+
- **If `loopRunner.name == "rauf"` and a legacy `.ralph.json` (or `.ralph/` directory) exists**, this is an un-migrated Ralph project. STOP: "This project is still on the legacy **Ralph** layout. Run `rauf migrate .` first (the loop runner only understands `.rauf/` and `RAUF_*` signals), then re-run `/feature-forge:forge-5-loop {feature}`."
|
|
105
|
+
- **Otherwise**, STOP and show `loopRunner.setupHint` (default: "Run `rauf install .` …"), e.g. "The loop runner isn't set up in this project ({preconditionFile} is missing). {setupHint}"
|
|
111
106
|
|
|
112
107
|
### 1e. Backlog File Check
|
|
113
108
|
|
|
@@ -117,6 +112,10 @@ Resolve the backlog file path (matching forge-4-backlog's composition rule, item
|
|
|
117
112
|
|
|
118
113
|
Verify the file exists on disk. If not, STOP and tell the user: "No backlog.json found at {path}. Run `/feature-forge:forge-4-backlog {feature}` to generate it."
|
|
119
114
|
|
|
115
|
+
### 1f. Branch Pre-flight (if using git)
|
|
116
|
+
|
|
117
|
+
The runner commits each completed item straight onto the current branch, so guard against committing onto the default branch. Skip if not a git repo or `branchPerFeature` is false. Read the current branch (`git rev-parse --abbrev-ref HEAD`) and default branch (`git symbolic-ref --quiet refs/remotes/origin/HEAD`, else `main`/`master`). If `.pipeline-state.json` records a `branch` that differs from the current one, warn via `AskUserQuestion` (offer **switch back** or **proceed here**). Otherwise, if the current branch **is** the default, strongly recommend via `AskUserQuestion` creating/switching to `{branchPrefix}{feature}` (`git switch -c`, then record it to the state `branch` field) before the loop commits — still allowing **proceed on `{defaultBranch}`**. Never hard-stop.
|
|
118
|
+
|
|
120
119
|
## Step 2: Construct the Loop Command
|
|
121
120
|
|
|
122
121
|
### 2a. Analyze Backlog
|
|
@@ -180,6 +179,7 @@ For the full loop-runner contract — event-stream vs. log-fallback launch, the
|
|
|
180
179
|
- **(b) Agent question.** Add an **"agent"** question to the same `AskUserQuestion` surface: **one option per advertised row** labelled `"{displayName} ({id}) — available/not found"`, **plus an explicit `"default (claude-cli)"` choice mapping to `run_selection = None`**. Resolve the pick (run > project, empty/whitespace unset, an explicit runner-default pick collapses to the default path) into `{resolved.agent, resolved.source}`. Precedence: `item.provider > --agent > project defaultAgent > runner default` (forge never reads a backlog item's provider).
|
|
181
180
|
- **(c) Availability listing.** From the **same** parsed `agents[]` (no second probe), list `id` / `displayName` / available (`yes`/`no`, `detail` on unavailable rows).
|
|
182
181
|
- **(d) Verdict** — only for a **non-default** resolved agent (default path `None`/`claude-cli` → no probe, byte-identical to today). Classify by **membership** then `available` (never by exit code): **UNKNOWN** (`∉` set) → **hard-reject BEFORE any loop side-effect**, error lists the **sorted** valid ids, **NO proceed-anyway**; **UNAVAILABLE** (member, `available False`) → warn with `detail`, `AskUserQuestion` offering **proceed-anyway OR choose-another** (re-presents the same `agents[]`), never silent; **AVAILABLE** → proceed, the validated id fills `{agent}`; **probe failure** (non-zero exit / unparseable / missing or empty `agents[]` / row lacking `id`) → surface it, offer **choose-another OR abort**, **never launch the non-default agent unvalidated** and never silently fall back to the default.
|
|
182
|
+
- **(d-model) Claude-only model-alias guard.** Runs **only** when the resolved agent is **non-default** (not the default / `claude-cli` path). Read the backlog.json (Step 1e path); collect items whose `model` is a **Claude-specific alias** (tier `opus`/`sonnet`/`haiku` or a `claude-*` id). **If none, skip silently.** Otherwise warn before launch via `AskUserQuestion` (NOT prose): `item.model` outranks `--agent`, so the alias is forwarded verbatim to `{agent}`, which will likely reject it (e.g. codex 400 *"The 'sonnet' model is not supported…"*) — every spawn exits 1 and rauf circuit-breaks (*"3 consecutive infra failures — halting"*) with no hint of the cause. Offer: **(1) Strip `model` for this run (recommended)** — rewrite backlog.json removing the `model` key from each affected item (persistent edit; re-run forge-4-backlog to restore), then proceed; **(2) Proceed as-is** — only safe if `{agent}` understands the pinned ids. forge touches only `model`, never `provider`. Full rationale: `references/runner-contract.md`.
|
|
183
183
|
- **(e) Optional-flags line.** Replace the confirmation's optional-flags line with one that lists `--agent <id>` first plus the agent precedence pointer (`item.provider > --agent > project defaultAgent > runner default`) alongside the model precedence.
|
|
184
184
|
- **(f) Resolved-agent line.** Add to the confirmation block: `Agent: {resolved.agent or claude-cli} (source: {sourceLabel})` — `sourceLabel`: `RUN` → `"per-run selection"`, `PROJECT` → `"project default (loopRunner.defaultAgent)"`, `DEFAULT` → `"runner default — claude-cli"`.
|
|
185
185
|
|
|
@@ -193,11 +193,11 @@ Before launching, update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
|
193
193
|
- Set `currentStage` to `forge-5-loop`
|
|
194
194
|
- Update `updatedAt`
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
Then commit this state write before launching (mandatory). The runner refuses to run with uncommitted changes (*"…pass --force"*), and this marker is itself one — so an otherwise-clean repo fails its first launch unless committed. Commit it via the shared-conventions **Git Commit Protocol** (epic members: stage `{specsDir}/{epic}/`): `{commitPrefix}({feature}): forge-5-loop in-progress` — a launch precondition, required regardless of `gitCommitAfterStage`. Unrelated leftover changes still trip the refusal; surface it, never auto-pass `--force`. See `references/runner-contract.md`.
|
|
197
197
|
|
|
198
|
-
|
|
198
|
+
### 3b. Launch Background Process
|
|
199
199
|
|
|
200
|
-
Loop runs can take significant time (minutes to hours depending on backlog size).
|
|
200
|
+
Launch the loop **backgrounded** (`run_in_background: true`) so it survives session end and does not block the session, and prefer the machine-readable event stream (`loopRunner.eventStreamCommand`, default for rauf) redirected to a stable `events.ndjson` so the session can supervise it live; fall back to the plain `runCommand` (tailing the human log) when no `eventStreamCommand` is configured. The background task's exit notification is the single authoritative terminal signal (Step 4). Loop runs can take significant time (minutes to hours depending on backlog size). For the exact launch commands (incl. the `mkdir -p` state-dir guard) and the event-stream vs. log-fallback detail, read `references/runner-contract.md`.
|
|
201
201
|
|
|
202
202
|
### 3c. Inform User
|
|
203
203
|
|
|
@@ -246,7 +246,7 @@ Run the **status-json command** (`loopRunner.statusJsonCommand`) and read
|
|
|
246
246
|
`backlogSummary` for the authoritative counts — it separates the three non-done
|
|
247
247
|
outcomes: genuine `blocked`, `needsHuman`, and runner-`deferred` ("false blocks").
|
|
248
248
|
Fall back to the **list command** (`loopRunner.listCommand`) if `statusJsonCommand`
|
|
249
|
-
is not configured. You will already have most of this from the live tally in 3e.
|
|
249
|
+
is not configured. You will already have most of this from the live tally in 3e. If the run used a review flag (e.g. rauf's `--review`), also read any `review_completed` event (event stream, or `{loopRunner.stateDir}/events.ndjson`) for its `itemsCreated`/`summary` to surface in 4b — see `references/result-reporting.md`.
|
|
250
250
|
|
|
251
251
|
### 4b. Report Results
|
|
252
252
|
|
|
@@ -267,13 +267,15 @@ Update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
|
267
267
|
2. If all items complete: set `currentStage` to `"forge-6-docs"`
|
|
268
268
|
3. Update `updatedAt`
|
|
269
269
|
|
|
270
|
-
**No git commit is needed** — the loop runner commits atomically per completed item during the run.
|
|
270
|
+
**No git commit is needed** — the loop runner commits implementation code atomically per completed item during the run. (Step 6's commit, epic members only, is of pipeline state / manifest — a distinct artifact.)
|
|
271
|
+
|
|
272
|
+
## Step 5b: Offer Impl-Verify (standalone path)
|
|
271
273
|
|
|
272
|
-
|
|
274
|
+
**Gate:** run only if (a) the feature's `.pipeline-state.json` has **no** `epic` key **and** (b) Step 5 set `stages.forge-5-loop.status` to `complete`. Otherwise **skip** — partial runs end as today, and epic members get the equivalent offer in Step 6.1 (do **not** prompt twice). This standalone counterpart to Step 6.1 nudges verification interactively rather than via the easily-missed "Next steps" text. Use `AskUserQuestion` (NOT inline prose) to offer: *"{feature}'s loop is complete. Recommended: run `/feature-forge:forge-verify {feature} impl` to audit the implementation before generating docs. Run it now, or skip to forge-6-docs?"* On **run**, hand off to `/feature-forge:forge-verify {feature} impl`. On **skip**, record `stages.forge-verify-impl.status` as `"skipped"` (mirrors `forge-4-backlog`'s skip handling) and point the user at `/feature-forge:forge-6-docs {feature}` — the forge-6-docs backstop re-surfaces the skip.
|
|
273
275
|
|
|
274
276
|
## Step 6: Epic Handoff
|
|
275
277
|
|
|
276
|
-
**Gate:** only run this step if (a) the resolved feature's `.pipeline-state.json` has an `epic` key **and** (b) Step 5 set `stages.forge-5-loop.status` to `complete` (all backlog items done). If either is false, **skip** — standalone features and partial runs end
|
|
278
|
+
**Gate:** only run this step if (a) the resolved feature's `.pipeline-state.json` has an `epic` key **and** (b) Step 5 set `stages.forge-5-loop.status` to `complete` (all backlog items done). If either is false, **skip** — standalone completed features are handled by Step 5b, and partial runs end as today (REQ-COMPAT-01).
|
|
277
279
|
|
|
278
280
|
1. **Offer impl-verify first (recommended, skippable).** Per the completion rule (`00-core-definitions.md §7`), a feature whose `forge-verify-impl.status == findings-reported` does **not** unblock dependents. Use `AskUserQuestion` (NOT inline prose) to offer:
|
|
279
281
|
|
|
@@ -297,7 +299,7 @@ Update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
|
297
299
|
- 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
300
|
- 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.
|
|
299
301
|
- If the session disconnects during a long-running loop, the runner process continues independently. The user can check results later with the status / list commands.
|
|
300
|
-
- Never run the run command in the foreground (without `run_in_background`) — it blocks and will hit the Bash tool timeout for any non-trivial backlog. "Don't block the foreground" is NOT "stay silent": supervise via the `Monitor` tool (3d),
|
|
301
|
-
- The `Monitor` must use `persistent: true` (not a bounded `timeout_ms`), watch the **structured** surface (`events.ndjson`), and never filter on raw `RAUF_*` tokens — they appear in agent prose and false-match. A `needs_human`/`blocked`/`review` signal does **not** pause the loop — the runner sets the item aside and keeps going; surface it live but don't tell the user the loop is waiting. See `references/runner-contract.md` for the full monitoring rules.
|
|
302
|
+
- Never run the run command in the foreground (without `run_in_background`) — it blocks and will hit the Bash tool timeout for any non-trivial backlog. "Don't block the foreground" is NOT "stay silent": supervise via the `Monitor` tool (3d), never `sleep`/poll in the foreground. The `Monitor` must use `persistent: true` (not a bounded `timeout_ms`), watch the **structured** surface (`events.ndjson`), and never filter on raw `RAUF_*` tokens — they appear in agent prose and false-match. A `needs_human`/`blocked`/`review` signal does **not** pause the loop — the runner sets the item aside and keeps going; surface it live but don't tell the user the loop is waiting. See `references/runner-contract.md` for the full monitoring rules.
|
|
302
303
|
- If a previous loop run left a stale lock, the user may need to pass `--force` to clear it. rauf will report this error clearly.
|
|
303
304
|
- The version gate (1c) uses the `--json` form on purpose; never parse `rauf version`'s human output.
|
|
305
|
+
- **Implementation artifacts must not cite specs.** The loop should **read** the specs and `backlog.json` freely — they are the source of truth for what to build, and the backlog rightly references specs for provenance. But the artifacts the loop **writes into the target repo** (source code, generated `SKILL.md`/agent files, configs, code comments) must be **self-contained**: they must NOT reference feature-forge spec files (no `See specs/{feature}/NN-*.md`, no "source spec" provenance notes in shipped output). Specs are pre-implementation inputs that may be archived or deleted once the feature ships; the implementation must stand on its own. This applies only to shipped implementation output — never to the backlog or spec documents, which should keep citing specs.
|
|
@@ -13,6 +13,19 @@ Next steps:
|
|
|
13
13
|
- /feature-forge:forge-6-docs {feature} Generate architecture docs
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
**Runner review pass.** A review flag (e.g. rauf's `--review`) makes the runner run
|
|
17
|
+
a post-loop review that **auto-creates and implements fix items** rather than handing
|
|
18
|
+
findings to the user — distinct from `forge-verify impl` (a clean-context audit that
|
|
19
|
+
writes a findings doc). When Step 4a captured a `review_completed` event, add a line
|
|
20
|
+
**above** "Next steps" so the pass's effect is visible and not mistaken for "nothing
|
|
21
|
+
happened":
|
|
22
|
+
```
|
|
23
|
+
Runner review pass: {itemsCreated} fix item(s) created and implemented.
|
|
24
|
+
{summary}
|
|
25
|
+
```
|
|
26
|
+
Omit this line when no `review_completed` event was emitted (no review flag passed).
|
|
27
|
+
The created items are already counted in the totals above.
|
|
28
|
+
|
|
16
29
|
**Some items need a human:**
|
|
17
30
|
```
|
|
18
31
|
Loop completed for {feature}.
|
|
@@ -70,6 +70,38 @@ The default / `claude-cli` path runs **no** probe (zero extra cost). See
|
|
|
70
70
|
`04-availability-precheck.md` for the full pre-check, classification, and allow-list,
|
|
71
71
|
and `02-config-schema-and-gating.md` for the capability gate.
|
|
72
72
|
|
|
73
|
+
> **Probe false-negative for Claude Code installs (advisory).** `rauf agents` may
|
|
74
|
+
> report `claude-cli` **unavailable** (e.g. *"credentials file not found:
|
|
75
|
+
> ~/.config/claude-code/credentials.json"*) even when a working `claude` CLI
|
|
76
|
+
> authenticates elsewhere — the probe's credential heuristic doesn't cover every
|
|
77
|
+
> install. This is a rauf probe concern, not something forge-5-loop fixes. The
|
|
78
|
+
> **default-agent path skips the probe entirely**, so an ordinary default run is
|
|
79
|
+
> unaffected; only an **explicit** `--agent claude-cli` would be flagged UNAVAILABLE,
|
|
80
|
+
> and the existing **proceed-anyway** path (above) covers it. Do not attempt to
|
|
81
|
+
> patch rauf's probe from here.
|
|
82
|
+
|
|
83
|
+
### Claude-only model-alias guard (Step 2d, sub-step d-model)
|
|
84
|
+
|
|
85
|
+
When the resolved agent is **non-default** (not the default / `claude-cli` path),
|
|
86
|
+
forge must guard against a backlog whose items pin **Claude-specific** model aliases.
|
|
87
|
+
forge-4-backlog (via the rauf author-backlog skill) writes Claude tier aliases
|
|
88
|
+
(`opus` / `sonnet`) into each item's `model`. Because rauf's precedence puts
|
|
89
|
+
`item.model` **above** `--agent`, the alias is forwarded verbatim to the selected
|
|
90
|
+
agent; a non-Claude agent (e.g. codex) then 400s — *"The 'sonnet' model is not
|
|
91
|
+
supported when using Codex with a ChatGPT account."* — so **every** spawn exits 1 and
|
|
92
|
+
rauf reports *"Circuit breaker: 3 consecutive infra failures — halting"* with no hint
|
|
93
|
+
of the real cause. forge-5-loop therefore detects Claude-specific `model` aliases in
|
|
94
|
+
the backlog (tier aliases `opus`/`sonnet`/`haiku` or `claude-*` ids) and, before
|
|
95
|
+
launch, **warns** and offers (via `AskUserQuestion`) to **strip `model` for this run**
|
|
96
|
+
(remove the key from each affected item so each spawn uses the agent's own default) or
|
|
97
|
+
**proceed as-is**. forge only ever touches the `model` field — never `provider`. The
|
|
98
|
+
default / `claude-cli` path skips this guard (the aliases are valid there).
|
|
99
|
+
|
|
100
|
+
> **Follow-up (out of scope here — rauf repo).** The durable fix would be for the
|
|
101
|
+
> rauf `author-backlog` skill to keep `model` **provider-neutral** by default (or to
|
|
102
|
+
> document that writing a tier alias binds the backlog to Claude agents). That lives
|
|
103
|
+
> in the separate rauf plugin/repo, not feature-forge; tracked as a follow-up.
|
|
104
|
+
|
|
73
105
|
## Optional flags catalog (Step 2d, rauf)
|
|
74
106
|
|
|
75
107
|
These are the optional flags the user may add to the rendered run command. If the
|
|
@@ -92,6 +124,14 @@ Launch the loop **backgrounded** so it survives session end and does not block t
|
|
|
92
124
|
session, and prefer the machine-readable event stream so the session can supervise
|
|
93
125
|
it live.
|
|
94
126
|
|
|
127
|
+
> **Clean-tree precondition.** rauf refuses to run with uncommitted changes
|
|
128
|
+
> (*"Refusing to run the loop with uncommitted changes… pass --force"*). Step 3a's
|
|
129
|
+
> in-progress `.pipeline-state.json` write is itself an uncommitted change, so it
|
|
130
|
+
> **must be committed before launch** (Step 3a) — otherwise the first launch on an
|
|
131
|
+
> otherwise-clean repo always fails. If the tree still has unrelated uncommitted
|
|
132
|
+
> changes after that commit, surface it and let the user commit/stash or pass
|
|
133
|
+
> `--force`; never auto-pass `--force`.
|
|
134
|
+
|
|
95
135
|
- **If `loopRunner.eventStreamCommand` is configured (default for rauf):** render it
|
|
96
136
|
(it appends `--ndjson` to the run) and launch via the Bash tool with
|
|
97
137
|
`run_in_background: true`, redirecting stdout to a stable events file:
|