@garygentry/feature-forge 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/claude/.feature-forge-bundle.json +1 -1
- package/adapters/claude/agents/forge-verifier.md +3 -1
- package/adapters/claude/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/claude/references/epic-state-schema.json +50 -0
- package/adapters/claude/references/forge-config-schema.json +18 -0
- package/adapters/claude/references/forge-decisions-schema.json +33 -0
- package/adapters/claude/references/pipeline-state-schema.json +34 -2
- package/adapters/claude/references/ralph-loop-contract.md +6 -3
- package/adapters/claude/references/shared-conventions.md +15 -4
- package/adapters/claude/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/scripts/epic-manifest.py +82 -4
- package/adapters/claude/scripts/fix-sweep.py +1180 -0
- package/adapters/claude/scripts/forge-session.py +1124 -26
- package/adapters/claude/skills/forge/SKILL.md +5 -5
- package/adapters/claude/skills/forge/references/pipeline-state-schema.json +34 -2
- package/adapters/claude/skills/forge/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-0-epic/references/edit-mode.md +5 -1
- package/adapters/claude/skills/forge-0-epic/references/epic-manifest-subcommands.md +5 -0
- package/adapters/claude/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
- package/adapters/claude/skills/forge-0-epic/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-0-epic/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-1-prd/SKILL.md +3 -1
- package/adapters/claude/skills/forge-1-prd/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-1-prd/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-2-tech/SKILL.md +5 -1
- package/adapters/claude/skills/forge-2-tech/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-2-tech/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-3-specs/SKILL.md +5 -1
- package/adapters/claude/skills/forge-3-specs/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-3-specs/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-4-backlog/SKILL.md +41 -3
- package/adapters/claude/skills/forge-4-backlog/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-4-backlog/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-5-loop/SKILL.md +36 -36
- package/adapters/claude/skills/forge-5-loop/references/agent-selection.md +16 -0
- package/adapters/claude/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
- package/adapters/claude/skills/forge-5-loop/references/recovery-procedure.md +349 -0
- package/adapters/claude/skills/forge-5-loop/references/result-reporting.md +40 -11
- package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +22 -4
- package/adapters/claude/skills/forge-5-loop/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-5-loop/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-6-docs/SKILL.md +29 -6
- package/adapters/claude/skills/forge-6-docs/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-6-docs/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-fix/SKILL.md +34 -0
- package/adapters/claude/skills/forge-fix/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-fix/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-guide/references/forge-config-schema.json +18 -0
- package/adapters/claude/skills/forge-guide/references/ralph-loop-contract.md +6 -3
- package/adapters/claude/skills/forge-guide/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-verify/SKILL.md +10 -11
- package/adapters/claude/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/claude/skills/forge-verify/references/findings-template.md +30 -0
- package/adapters/claude/skills/forge-verify/references/shared-conventions.md +15 -4
- package/adapters/claude/skills/forge-verify/references/stage-exit-protocol.md +55 -11
- package/adapters/claude/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
- package/adapters/claude/skills/forge-verify/references/verification-checklists/impl.md +85 -0
- package/adapters/claude/skills/forge-verify/references/verification-checklists/specs.md +43 -1
- package/adapters/codex/.feature-forge-bundle.json +1 -1
- package/adapters/codex/agents/forge-verifier.toml +3 -1
- package/adapters/codex/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/codex/references/epic-state-schema.json +50 -0
- package/adapters/codex/references/forge-config-schema.json +18 -0
- package/adapters/codex/references/forge-decisions-schema.json +33 -0
- package/adapters/codex/references/pipeline-state-schema.json +34 -2
- package/adapters/codex/references/process-overview.md +2 -2
- package/adapters/codex/references/ralph-loop-contract.md +6 -3
- package/adapters/codex/references/shared-conventions.md +44 -33
- package/adapters/codex/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/scripts/epic-manifest.py +82 -4
- package/adapters/codex/scripts/fix-sweep.py +1180 -0
- package/adapters/codex/scripts/forge-session.py +1124 -26
- package/adapters/codex/skills/forge/SKILL.md +8 -8
- package/adapters/codex/skills/forge/references/pipeline-state-schema.json +34 -2
- package/adapters/codex/skills/forge/references/process-overview.md +2 -2
- package/adapters/codex/skills/forge/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-0-epic/references/edit-mode.md +14 -10
- package/adapters/codex/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
- package/adapters/codex/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
- package/adapters/codex/skills/forge-0-epic/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-0-epic/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-1-prd/SKILL.md +3 -1
- package/adapters/codex/skills/forge-1-prd/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-1-prd/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-2-tech/SKILL.md +5 -1
- package/adapters/codex/skills/forge-2-tech/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-2-tech/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-3-specs/SKILL.md +5 -1
- package/adapters/codex/skills/forge-3-specs/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-3-specs/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-4-backlog/SKILL.md +41 -3
- package/adapters/codex/skills/forge-4-backlog/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-4-backlog/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-5-loop/SKILL.md +36 -36
- package/adapters/codex/skills/forge-5-loop/references/agent-selection.md +17 -1
- package/adapters/codex/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
- package/adapters/codex/skills/forge-5-loop/references/recovery-procedure.md +349 -0
- package/adapters/codex/skills/forge-5-loop/references/result-reporting.md +40 -11
- package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +26 -8
- package/adapters/codex/skills/forge-5-loop/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-5-loop/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-6-docs/SKILL.md +29 -6
- package/adapters/codex/skills/forge-6-docs/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-6-docs/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-fix/SKILL.md +34 -0
- package/adapters/codex/skills/forge-fix/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-fix/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-guide/SKILL.md +1 -1
- package/adapters/codex/skills/forge-guide/references/forge-config-schema.json +18 -0
- package/adapters/codex/skills/forge-guide/references/process-overview.md +2 -2
- package/adapters/codex/skills/forge-guide/references/ralph-loop-contract.md +6 -3
- package/adapters/codex/skills/forge-guide/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-init/SKILL.md +1 -1
- package/adapters/codex/skills/forge-verify/SKILL.md +11 -12
- package/adapters/codex/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/codex/skills/forge-verify/references/findings-template.md +32 -2
- package/adapters/codex/skills/forge-verify/references/shared-conventions.md +44 -33
- package/adapters/codex/skills/forge-verify/references/stage-exit-protocol.md +64 -20
- package/adapters/codex/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
- package/adapters/codex/skills/forge-verify/references/verification-checklists/epic.md +1 -1
- package/adapters/codex/skills/forge-verify/references/verification-checklists/impl.md +85 -0
- package/adapters/codex/skills/forge-verify/references/verification-checklists/specs.md +43 -1
- package/adapters/copilot/.feature-forge-bundle.json +1 -1
- package/adapters/copilot/agents/forge-verifier.md +3 -1
- package/adapters/copilot/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/copilot/references/epic-state-schema.json +50 -0
- package/adapters/copilot/references/forge-config-schema.json +18 -0
- package/adapters/copilot/references/forge-decisions-schema.json +33 -0
- package/adapters/copilot/references/pipeline-state-schema.json +34 -2
- package/adapters/copilot/references/process-overview.md +2 -2
- package/adapters/copilot/references/ralph-loop-contract.md +6 -3
- package/adapters/copilot/references/shared-conventions.md +44 -33
- package/adapters/copilot/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/scripts/epic-manifest.py +82 -4
- package/adapters/copilot/scripts/fix-sweep.py +1180 -0
- package/adapters/copilot/scripts/forge-session.py +1124 -26
- package/adapters/copilot/skills/forge/forge.md +8 -8
- package/adapters/copilot/skills/forge/references/pipeline-state-schema.json +34 -2
- package/adapters/copilot/skills/forge/references/process-overview.md +2 -2
- package/adapters/copilot/skills/forge/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-0-epic/references/edit-mode.md +14 -10
- package/adapters/copilot/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
- package/adapters/copilot/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
- package/adapters/copilot/skills/forge-0-epic/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-0-epic/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +3 -1
- package/adapters/copilot/skills/forge-1-prd/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-1-prd/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +5 -1
- package/adapters/copilot/skills/forge-2-tech/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-2-tech/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +5 -1
- package/adapters/copilot/skills/forge-3-specs/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-3-specs/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +41 -3
- package/adapters/copilot/skills/forge-4-backlog/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-4-backlog/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +36 -36
- package/adapters/copilot/skills/forge-5-loop/references/agent-selection.md +17 -1
- package/adapters/copilot/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
- package/adapters/copilot/skills/forge-5-loop/references/recovery-procedure.md +349 -0
- package/adapters/copilot/skills/forge-5-loop/references/result-reporting.md +40 -11
- package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +26 -8
- package/adapters/copilot/skills/forge-5-loop/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-5-loop/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +29 -6
- package/adapters/copilot/skills/forge-6-docs/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-6-docs/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-fix/forge-fix.md +34 -0
- package/adapters/copilot/skills/forge-fix/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-fix/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-guide/forge-guide.md +1 -1
- package/adapters/copilot/skills/forge-guide/references/forge-config-schema.json +18 -0
- package/adapters/copilot/skills/forge-guide/references/process-overview.md +2 -2
- package/adapters/copilot/skills/forge-guide/references/ralph-loop-contract.md +6 -3
- package/adapters/copilot/skills/forge-guide/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-init/forge-init.md +1 -1
- package/adapters/copilot/skills/forge-verify/forge-verify.md +11 -12
- package/adapters/copilot/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/copilot/skills/forge-verify/references/findings-template.md +32 -2
- package/adapters/copilot/skills/forge-verify/references/shared-conventions.md +44 -33
- package/adapters/copilot/skills/forge-verify/references/stage-exit-protocol.md +64 -20
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/epic.md +1 -1
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/impl.md +85 -0
- package/adapters/copilot/skills/forge-verify/references/verification-checklists/specs.md +43 -1
- package/adapters/cursor/.feature-forge-bundle.json +1 -1
- package/adapters/cursor/agents/forge-verifier.mdc +3 -1
- package/adapters/cursor/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/cursor/references/epic-state-schema.json +50 -0
- package/adapters/cursor/references/forge-config-schema.json +18 -0
- package/adapters/cursor/references/forge-decisions-schema.json +33 -0
- package/adapters/cursor/references/pipeline-state-schema.json +34 -2
- package/adapters/cursor/references/process-overview.md +2 -2
- package/adapters/cursor/references/ralph-loop-contract.md +6 -3
- package/adapters/cursor/references/shared-conventions.md +44 -33
- package/adapters/cursor/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/scripts/epic-manifest.py +82 -4
- package/adapters/cursor/scripts/fix-sweep.py +1180 -0
- package/adapters/cursor/scripts/forge-session.py +1124 -26
- package/adapters/cursor/skills/forge/forge.mdc +8 -8
- package/adapters/cursor/skills/forge/references/pipeline-state-schema.json +34 -2
- package/adapters/cursor/skills/forge/references/process-overview.md +2 -2
- package/adapters/cursor/skills/forge/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-0-epic/references/edit-mode.md +14 -10
- package/adapters/cursor/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
- package/adapters/cursor/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
- package/adapters/cursor/skills/forge-0-epic/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-0-epic/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +3 -1
- package/adapters/cursor/skills/forge-1-prd/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-1-prd/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +5 -1
- package/adapters/cursor/skills/forge-2-tech/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-2-tech/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +5 -1
- package/adapters/cursor/skills/forge-3-specs/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-3-specs/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +41 -3
- package/adapters/cursor/skills/forge-4-backlog/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-4-backlog/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +36 -36
- package/adapters/cursor/skills/forge-5-loop/references/agent-selection.md +17 -1
- package/adapters/cursor/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
- package/adapters/cursor/skills/forge-5-loop/references/recovery-procedure.md +349 -0
- package/adapters/cursor/skills/forge-5-loop/references/result-reporting.md +40 -11
- package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +26 -8
- package/adapters/cursor/skills/forge-5-loop/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-5-loop/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +29 -6
- package/adapters/cursor/skills/forge-6-docs/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-6-docs/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-fix/forge-fix.mdc +34 -0
- package/adapters/cursor/skills/forge-fix/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-fix/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-guide/forge-guide.mdc +1 -1
- package/adapters/cursor/skills/forge-guide/references/forge-config-schema.json +18 -0
- package/adapters/cursor/skills/forge-guide/references/process-overview.md +2 -2
- package/adapters/cursor/skills/forge-guide/references/ralph-loop-contract.md +6 -3
- package/adapters/cursor/skills/forge-guide/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-init/forge-init.mdc +1 -1
- package/adapters/cursor/skills/forge-verify/forge-verify.mdc +11 -12
- package/adapters/cursor/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/cursor/skills/forge-verify/references/findings-template.md +32 -2
- package/adapters/cursor/skills/forge-verify/references/shared-conventions.md +44 -33
- package/adapters/cursor/skills/forge-verify/references/stage-exit-protocol.md +64 -20
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/epic.md +1 -1
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/impl.md +85 -0
- package/adapters/cursor/skills/forge-verify/references/verification-checklists/specs.md +43 -1
- package/adapters/gemini/.feature-forge-bundle.json +1 -1
- package/adapters/gemini/agents/forge-verifier.md +3 -1
- package/adapters/gemini/gemini-extension.json +1 -1
- package/adapters/gemini/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/gemini/references/epic-state-schema.json +50 -0
- package/adapters/gemini/references/forge-config-schema.json +18 -0
- package/adapters/gemini/references/forge-decisions-schema.json +33 -0
- package/adapters/gemini/references/pipeline-state-schema.json +34 -2
- package/adapters/gemini/references/process-overview.md +2 -2
- package/adapters/gemini/references/ralph-loop-contract.md +6 -3
- package/adapters/gemini/references/shared-conventions.md +44 -33
- package/adapters/gemini/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/scripts/epic-manifest.py +82 -4
- package/adapters/gemini/scripts/fix-sweep.py +1180 -0
- package/adapters/gemini/scripts/forge-session.py +1124 -26
- package/adapters/gemini/skills/forge/forge.md +8 -8
- package/adapters/gemini/skills/forge/references/pipeline-state-schema.json +34 -2
- package/adapters/gemini/skills/forge/references/process-overview.md +2 -2
- package/adapters/gemini/skills/forge/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-0-epic/references/edit-mode.md +14 -10
- package/adapters/gemini/skills/forge-0-epic/references/epic-manifest-subcommands.md +8 -3
- package/adapters/gemini/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
- package/adapters/gemini/skills/forge-0-epic/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-0-epic/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +3 -1
- package/adapters/gemini/skills/forge-1-prd/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-1-prd/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +5 -1
- package/adapters/gemini/skills/forge-2-tech/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-2-tech/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +5 -1
- package/adapters/gemini/skills/forge-3-specs/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-3-specs/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +41 -3
- package/adapters/gemini/skills/forge-4-backlog/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-4-backlog/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +36 -36
- package/adapters/gemini/skills/forge-5-loop/references/agent-selection.md +17 -1
- package/adapters/gemini/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
- package/adapters/gemini/skills/forge-5-loop/references/recovery-procedure.md +349 -0
- package/adapters/gemini/skills/forge-5-loop/references/result-reporting.md +40 -11
- package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +26 -8
- package/adapters/gemini/skills/forge-5-loop/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-5-loop/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +29 -6
- package/adapters/gemini/skills/forge-6-docs/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-6-docs/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-fix/forge-fix.md +34 -0
- package/adapters/gemini/skills/forge-fix/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-fix/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-guide/forge-guide.md +1 -1
- package/adapters/gemini/skills/forge-guide/references/forge-config-schema.json +18 -0
- package/adapters/gemini/skills/forge-guide/references/process-overview.md +2 -2
- package/adapters/gemini/skills/forge-guide/references/ralph-loop-contract.md +6 -3
- package/adapters/gemini/skills/forge-guide/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-init/forge-init.md +1 -1
- package/adapters/gemini/skills/forge-verify/forge-verify.md +11 -12
- package/adapters/gemini/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/gemini/skills/forge-verify/references/findings-template.md +32 -2
- package/adapters/gemini/skills/forge-verify/references/shared-conventions.md +44 -33
- package/adapters/gemini/skills/forge-verify/references/stage-exit-protocol.md +64 -20
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/epic.md +1 -1
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/impl.md +85 -0
- package/adapters/gemini/skills/forge-verify/references/verification-checklists/specs.md +43 -1
- package/adapters/pi/.feature-forge-bundle.json +1 -1
- package/adapters/pi/agents/forge-verifier.md +3 -1
- package/adapters/pi/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/pi/references/epic-state-schema.json +50 -0
- package/adapters/pi/references/forge-config-schema.json +18 -0
- package/adapters/pi/references/forge-decisions-schema.json +33 -0
- package/adapters/pi/references/pipeline-state-schema.json +34 -2
- package/adapters/pi/references/process-overview.md +2 -2
- package/adapters/pi/references/ralph-loop-contract.md +6 -3
- package/adapters/pi/references/shared-conventions.md +33 -22
- package/adapters/pi/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/scripts/epic-manifest.py +82 -4
- package/adapters/pi/scripts/fix-sweep.py +1180 -0
- package/adapters/pi/scripts/forge-session.py +1124 -26
- package/adapters/pi/skills/forge/SKILL.md +5 -5
- package/adapters/pi/skills/forge/references/pipeline-state-schema.json +34 -2
- package/adapters/pi/skills/forge/references/process-overview.md +2 -2
- package/adapters/pi/skills/forge/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-0-epic/references/edit-mode.md +8 -4
- package/adapters/pi/skills/forge-0-epic/references/epic-manifest-subcommands.md +6 -1
- package/adapters/pi/skills/forge-0-epic/references/pipeline-state-schema.json +34 -2
- package/adapters/pi/skills/forge-0-epic/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-0-epic/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-1-prd/SKILL.md +3 -1
- package/adapters/pi/skills/forge-1-prd/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-1-prd/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-2-tech/SKILL.md +5 -1
- package/adapters/pi/skills/forge-2-tech/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-2-tech/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-3-specs/SKILL.md +5 -1
- package/adapters/pi/skills/forge-3-specs/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-3-specs/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-4-backlog/SKILL.md +41 -3
- package/adapters/pi/skills/forge-4-backlog/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-4-backlog/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-5-loop/SKILL.md +36 -36
- package/adapters/pi/skills/forge-5-loop/references/agent-selection.md +16 -0
- package/adapters/pi/skills/forge-5-loop/references/ralph-loop-contract.md +6 -3
- package/adapters/pi/skills/forge-5-loop/references/recovery-procedure.md +349 -0
- package/adapters/pi/skills/forge-5-loop/references/result-reporting.md +40 -11
- package/adapters/pi/skills/forge-5-loop/references/runner-contract.md +25 -7
- package/adapters/pi/skills/forge-5-loop/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-5-loop/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-6-docs/SKILL.md +29 -6
- package/adapters/pi/skills/forge-6-docs/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-6-docs/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-fix/SKILL.md +34 -0
- package/adapters/pi/skills/forge-fix/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-fix/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-guide/references/forge-config-schema.json +18 -0
- package/adapters/pi/skills/forge-guide/references/process-overview.md +2 -2
- package/adapters/pi/skills/forge-guide/references/ralph-loop-contract.md +6 -3
- package/adapters/pi/skills/forge-guide/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-verify/SKILL.md +10 -11
- package/adapters/pi/skills/forge-verify/references/decisions/single-writer-threat-model.md +53 -0
- package/adapters/pi/skills/forge-verify/references/findings-template.md +31 -1
- package/adapters/pi/skills/forge-verify/references/shared-conventions.md +33 -22
- package/adapters/pi/skills/forge-verify/references/stage-exit-protocol.md +63 -19
- package/adapters/pi/skills/forge-verify/references/verification-checklists/backlog.md +73 -0
- package/adapters/pi/skills/forge-verify/references/verification-checklists/epic.md +1 -1
- package/adapters/pi/skills/forge-verify/references/verification-checklists/impl.md +85 -0
- package/adapters/pi/skills/forge-verify/references/verification-checklists/specs.md +43 -1
- package/package.json +1 -1
|
@@ -64,28 +64,57 @@ Loop completed for {feature}.
|
|
|
64
64
|
Deferred: {deferred} items (no signal after retries — likely just need another pass)
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
**Some items still pending
|
|
67
|
+
**Some items still pending** — the parenthetical cause is chosen, never hardcoded:
|
|
68
68
|
```
|
|
69
69
|
Loop completed for {feature}.
|
|
70
70
|
Completed: {done}/{total}
|
|
71
|
-
Pending: {pending} items (
|
|
71
|
+
Pending: {pending} items ({cause})
|
|
72
72
|
Blocked: {blocked} items
|
|
73
73
|
```
|
|
74
|
+
Render `{cause}` as "iteration limit reached" **only** when `iteration == maxIterations`
|
|
75
|
+
AND `selectable > 0` — cite the `iteration`/`maxIterations` counters from
|
|
76
|
+
`{loopRunner.stateDir}/state.json` and `selectable` from `backlog-topology --items-stdin
|
|
77
|
+
--json` run over the same authoritative item JSON as the counts above. Otherwise —
|
|
78
|
+
`selectable == 0` with items still pending while `iteration < maxIterations` — the
|
|
79
|
+
iteration limit was NOT the constraint: drop the parenthetical and render this
|
|
80
|
+
dependency-starvation report instead, naming each blocking root and its gated-subtree
|
|
81
|
+
size from `backlog-topology`'s `starvation.blockingRoots[].{id, gatedCount}` and
|
|
82
|
+
`itemCount`, then close the stage with `--cause dependency-starvation` in Step 7:
|
|
83
|
+
```
|
|
84
|
+
Loop stopped for {feature} with {pending} item(s) still pending, but the iteration
|
|
85
|
+
limit was NOT the constraint ({iteration}/{maxIterations} iterations used).
|
|
86
|
+
No pending item was selectable — every one is gated behind unblocked roots:
|
|
87
|
+
- {rootId}: {rootTitle} — gates {gatedCount}/{itemCount} items
|
|
88
|
+
Unblock these roots (their subtrees free up on the next run), then run the loop again.
|
|
89
|
+
```
|
|
90
|
+
Both branches cite their authoritative source: the iteration-limit branch the
|
|
91
|
+
`state.json` iteration counters, the starvation branch the backlog summary counts plus
|
|
92
|
+
the `backlog-topology` output (`selectable`, `blockingRoots`, `gatedCount`,
|
|
93
|
+
`itemCount`). A cause any of those counters contradicts — e.g. "iteration limit
|
|
94
|
+
reached" while `iteration < maxIterations` — is a reportable defect.
|
|
74
95
|
|
|
75
96
|
## Selecting the one `LoopOutcome` (Step 7)
|
|
76
97
|
|
|
77
98
|
After Step 5's `state-complete`, select exactly **one** `LoopOutcome` from Step 4a's
|
|
78
99
|
authoritative final counts. Walk this ladder in order and stop at the first match:
|
|
79
100
|
|
|
80
|
-
1. **`
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
101
|
+
1. **`resolved`** — the Post-Run Recovery Procedure
|
|
102
|
+
(`references/recovery-procedure.md`) ran this session with a **non-empty**
|
|
103
|
+
affected-item set and its gate passed: every affected needs-human item has an
|
|
104
|
+
applied decision record, the working tree is clean, and each affected item left
|
|
105
|
+
`blocked`/`needsHuman` per the per-item re-read. This outranks `needs-human` so a
|
|
106
|
+
stop the recovery just cleared is not re-reported as still needing a human. (Step
|
|
107
|
+
4c runs the procedure on every close, so an empty affected set is the common case —
|
|
108
|
+
it never selects `resolved`; fall through.)
|
|
109
|
+
2. **`needs-human`** — otherwise, `needsHuman > 0`. This wins even when blocked
|
|
110
|
+
items also exist: a decision only a human can make outranks work that merely
|
|
111
|
+
could not proceed.
|
|
112
|
+
3. **`blocked`** — otherwise, genuine `blocked > 0`.
|
|
113
|
+
4. **`deferred`** — otherwise, runner-deferred items exist (the "false blocks" the
|
|
85
114
|
runner gave up on after retries).
|
|
86
|
-
|
|
115
|
+
5. **`partial`** — otherwise, `pending`/`in_progress` items remain because the
|
|
87
116
|
iteration limit was reached.
|
|
88
|
-
|
|
117
|
+
6. **`complete`** — otherwise, and **only** when every item is `done`.
|
|
89
118
|
|
|
90
119
|
This is a priority order, not a set. A run reporting both a needs-human and a blocked
|
|
91
120
|
count renders both reports above and still exits `needs-human`.
|
|
@@ -95,8 +124,8 @@ reported only that its process finished; the final backlog state decides. A clea
|
|
|
95
124
|
exit 0 that still leaves pending items is `partial`, never `complete` — and
|
|
96
125
|
`complete` is legitimate only when the counts show every item `done`.
|
|
97
126
|
|
|
98
|
-
**Retrying the non-complete outcomes.** `partial` and `
|
|
99
|
-
resume; `blocked` and `needs-human` fence the navigator. Whichever you land on, the
|
|
127
|
+
**Retrying the non-complete outcomes.** `partial`, `deferred`, and `resolved` fence
|
|
128
|
+
the loop resume; `blocked` and `needs-human` fence the navigator. Whichever you land on, the
|
|
100
129
|
runner's own retry flags still apply to the next run — e.g. rauf's `--retry-blocked`
|
|
101
130
|
picks the set-aside blocked and deferred items back up at Step 2d. Mention that as
|
|
102
131
|
plain prose in the report if it helps; never as a second command block.
|
|
@@ -31,7 +31,7 @@ pass after all iterations complete (an extra agent session that re-examines the
|
|
|
31
31
|
finished work and can file follow-up backlog items). feature-forge treats **running
|
|
32
32
|
with review as the recommended default** — a review pass is cheap relative to the
|
|
33
33
|
loop it audits, and catches gaps before the pipeline moves on to docs. So Step 2d
|
|
34
|
-
adds a **"Run mode"** question
|
|
34
|
+
adds a **"Run mode"** question, via the host's question mechanism, to the confirmation surface with a
|
|
35
35
|
**fixed, non-improvised option order** (determinism is the point — the option set
|
|
36
36
|
must not vary run-to-run):
|
|
37
37
|
|
|
@@ -47,12 +47,25 @@ Run mode:
|
|
|
47
47
|
review pass and also unblocks/retries the previously blocked items.
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
**`loopRunner.reviewMode` gate (`"prompt"` default | `"always"` | `"never"`).**
|
|
51
|
+
The Run-mode question above is presented only when the effective
|
|
52
|
+
`loopRunner.reviewMode` is `"prompt"` — the default, byte-identical to today.
|
|
53
|
+
`"always"` **skips the question** and appends `--review` unconditionally; the
|
|
54
|
+
confirmation's rendered command line still shows `--review`, so the choice is
|
|
55
|
+
never hidden. `"never"` **skips the question** and launches the bare rendered
|
|
56
|
+
command. Under `"always"`/`"never"`, when — and only when — the Step 2a tally has
|
|
57
|
+
`blocked > 0`, present a **narrower situational question** in the question's
|
|
58
|
+
place offering only the retry-blocked choice (on yes, additionally append
|
|
59
|
+
`--retry-blocked`; the `--review` decision is already fixed by the mode and is
|
|
60
|
+
**not** re-asked); with no blocked items, the Run-mode surface asks nothing. An
|
|
61
|
+
unrecognized value behaves as `"prompt"`.
|
|
62
|
+
|
|
50
63
|
Notes:
|
|
51
64
|
|
|
52
65
|
- **Option 1 is the default** and the confirmation's rendered command line shows
|
|
53
66
|
`--review` appended. On any pick, append the option's flags to the rendered run
|
|
54
67
|
command before Step 3 (launch).
|
|
55
|
-
-
|
|
68
|
+
- **the host's question mechanism's built-in "Other"** already lets the user type ad-hoc flags
|
|
56
69
|
(`--model <model>`, `--timeout <min>`, or any combination) — do **not** add a
|
|
57
70
|
separate open-ended option for that.
|
|
58
71
|
- **Option 3 is conditional.** Include it only when the Step 2a tally has `blocked
|
|
@@ -103,7 +116,7 @@ a descriptor on the file the runner immediately rotates away, so the redirected
|
|
|
103
116
|
rotation timing. So:
|
|
104
117
|
|
|
105
118
|
- **Self-persisting runner (default — rauf writes `{stateDir}/events.ndjson`):**
|
|
106
|
-
launch the **plain `runCommand`** with
|
|
119
|
+
launch the **plain `runCommand`** with the host's background-execution mechanism and **no
|
|
107
120
|
redirect** — the Bash tool already captures the run's stdout/stderr to the
|
|
108
121
|
background task's output file (use it to diagnose a launch refusal). Supervise by
|
|
109
122
|
arming the Monitor on the runner's **native** `{backlogDir}/{stateDir}/events.ndjson`
|
|
@@ -129,8 +142,8 @@ backlog size).
|
|
|
129
142
|
|
|
130
143
|
## Arm a Monitor on the event stream (Step 3d)
|
|
131
144
|
|
|
132
|
-
Arm the
|
|
133
|
-
this session as they happen. Use **`persistent: true`** — runs can exceed
|
|
145
|
+
Arm the **host's monitoring mechanism** on the structured event stream so events flow back into
|
|
146
|
+
this session as they happen. Use **`persistent: true`** — runs can exceed the host's monitoring mechanism's
|
|
134
147
|
maximum `timeout_ms` (1 hour), and a bounded timeout would silently stop watching a
|
|
135
148
|
still-running loop.
|
|
136
149
|
|
|
@@ -179,12 +192,17 @@ high and the noise low:
|
|
|
179
192
|
immediately** and send a **`PushNotification`** (an hours-long run means the user has
|
|
180
193
|
likely stepped away). **Important — the loop is NOT paused:** the runner has set that
|
|
181
194
|
item aside and kept working other items. So report *what* needs a human and *which*
|
|
182
|
-
item, then either (a) collect the user's answer via
|
|
183
|
-
|
|
184
|
-
|
|
195
|
+
item, then either (a) collect the user's answer via the host's question mechanism and **record it via
|
|
196
|
+
`decision-record` now** — SKILL Step 4c's unconditional **Post-Run Recovery Procedure**
|
|
197
|
+
pass (`references/recovery-procedure.md`) applies it after the run ends — or (b) offer
|
|
198
|
+
to **cancel the run early** (also recorded via `decision-record` — a deferral) if the
|
|
199
|
+
answer changes the whole plan. Do not tell the user the loop is waiting on their reply
|
|
200
|
+
— it isn't.
|
|
185
201
|
- **`item_blocked`** → surface the blocked item + reason now (visibility) and
|
|
186
202
|
accumulate for the final summary. Use `{rendered statusJsonCommand}` to distinguish a
|
|
187
203
|
genuine `blocked` from a runner-`deferred` "false block" (`backlogSummary.deferred`).
|
|
204
|
+
No action is needed now: Step 4c's recovery pass offers the unblock after the run
|
|
205
|
+
ends — a blocked-only run (no `needs_human` event) still enters it.
|
|
188
206
|
- **`loop_error`** → a real failure (this is also what a circuit-breaker halt — too many
|
|
189
207
|
consecutive infra failures — emits). Surface now and `PushNotification`. Offer
|
|
190
208
|
inspection / `--force` / re-run as appropriate.
|
|
@@ -15,11 +15,11 @@ If no feature name is provided:
|
|
|
15
15
|
|
|
16
16
|
## User Input Protocol
|
|
17
17
|
|
|
18
|
-
### CRITICAL GUARDRAIL: Use
|
|
18
|
+
### CRITICAL GUARDRAIL: Use the host's question mechanism for All Questions
|
|
19
19
|
|
|
20
|
-
You MUST use the
|
|
20
|
+
You MUST use the host's question mechanism whenever you need the user's input before proceeding. This includes yes/no confirmations, choices between options, interview questions, and feedback on artifacts. NEVER output questions as inline prose text — the user may not be prompted and the session will stall.
|
|
21
21
|
|
|
22
|
-
**Required turn structure:** Output your analysis, findings, or context as regular text. Then call
|
|
22
|
+
**Required turn structure:** Output your analysis, findings, or context as regular text. Then call the host's question mechanism with your questions. Do NOT mix questions into your text output.
|
|
23
23
|
|
|
24
24
|
**WRONG — questions as inline prose (causes stalling):**
|
|
25
25
|
```
|
|
@@ -31,14 +31,14 @@ I found that the codebase uses React and TanStack Router. Here are my questions:
|
|
|
31
31
|
**RIGHT — context as text, questions via tool:**
|
|
32
32
|
```
|
|
33
33
|
I found that the codebase uses React and TanStack Router.
|
|
34
|
-
[then call
|
|
34
|
+
[then call the host's question mechanism with: "1. Where should this component live? 2. Should we use server-side rendering?"]
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
### Decision Support: Help the User Choose
|
|
38
38
|
|
|
39
|
-
When
|
|
39
|
+
When a question posed through the host's question mechanism carries substantive options (a real choice — not a trivial yes/no confirmation), do not just list them. The interview stages have already done codebase research and integration analysis; surfacing that synthesis at the decision moment is the whole point. For every such question:
|
|
40
40
|
|
|
41
|
-
- **Lead with a recommended option.** Place it first and label it `(recommended)` (matching the
|
|
41
|
+
- **Lead with a recommended option.** Place it first and label it `(recommended)` (matching the host's question mechanism "(Recommended)" convention).
|
|
42
42
|
- **Put the trade-off in each option's `description`.** Say why you'd pick it and what you give up versus the alternatives — the cost, not just the benefit.
|
|
43
43
|
- **State a one-line rationale** in the text before the question for *why* the recommendation wins.
|
|
44
44
|
|
|
@@ -49,10 +49,21 @@ Two modes, and make clear which one you're in:
|
|
|
49
49
|
|
|
50
50
|
**The only thing to avoid is false confidence** — recommending as if evidence-backed when it's really preference. Never respond to the absence of a clear winner by going silent: a defaulted recommendation with honest trade-offs always beats a neutral option dump.
|
|
51
51
|
|
|
52
|
-
For genuinely comparable artifacts (competing module structures, two code snippets, layout variants), use the
|
|
52
|
+
For genuinely comparable artifacts (competing module structures, two code snippets, layout variants), use the host's question mechanism `preview` field to show them side-by-side.
|
|
53
53
|
|
|
54
54
|
The **Branch Setup** block below is the reference pattern: a strong recommendation as the first option, rationale inline, the alternative still available, never a hard-stop.
|
|
55
55
|
|
|
56
|
+
## Stage Review Gate
|
|
57
|
+
|
|
58
|
+
Every authoring stage ends its "Review with User" step in exactly one of two shapes. Which shape a stage uses is declared **here, once** — each stage's review step points at this block by title, and the shape is never re-derived from the surrounding prose or inferred from how sibling stages behave (three stages block and one does not; majority-shape inference is precisely the failure this block exists to prevent):
|
|
59
|
+
|
|
60
|
+
- **Blocking review (gate).** The stage presents the artifact and collects feedback through the host's question mechanism; it does **not** proceed until the user answers, iterating until they confirm. Stages: **forge-1-prd** (Step 5), **forge-2-tech** (Step 6), **forge-3-specs** (Step 6).
|
|
61
|
+
- **Non-blocking review (invitation).** The stage states the artifact is ready and invites adjustments **as a statement, not a question** — and then **proceeds to the next step in the same turn unless the user asks for changes**. The invitation obliges the agent to *continue*: emitting the invitation sentence and stopping treats the non-gate as a gate and strands the stage `in-progress` with its completion step unrun — a defect, not caution. Stage: **forge-4-backlog** (Step 6).
|
|
62
|
+
|
|
63
|
+
**Why the shapes differ.** A blocking review guards an artifact whose content was just authored from open-ended interview or synthesis — the user is the only authority on "complete", so the stage must wait. forge-4's backlog is *derived* from specs the user already approved, was planned interactively in its Step 3, and is machine-validated in its Step 5; a second hard gate would re-ask a settled question, and the loop never launches without forge-5-loop's own Step 2d confirmation anyway. The invitation is a courtesy checkpoint, not an approval gate (removed deliberately in #78's consistency sweep).
|
|
64
|
+
|
|
65
|
+
A stage that changes shape changes it **in this block first**; the per-stage pointer stays a pointer.
|
|
66
|
+
|
|
56
67
|
## Configuration Reading
|
|
57
68
|
|
|
58
69
|
Read `forge.config.json` from the project root. If it doesn't exist, use defaults.
|
|
@@ -68,10 +79,10 @@ Extract these config values (use defaults if not present):
|
|
|
68
79
|
- `branchPerFeature` (default: true)
|
|
69
80
|
- `branchPrefix` (default: `forge/`)
|
|
70
81
|
- `loopIterationMultiplier` (default: `1.5`)
|
|
71
|
-
- `autoInvokeNextStage` (default: `true` — the `/feature-forge:forge` navigator auto-invokes the next stage via the
|
|
82
|
+
- `autoInvokeNextStage` (default: `true` — the `/feature-forge:forge` navigator auto-invokes the next stage via the host's skill-invocation mechanism after the user confirms; `false` keeps copy-paste behavior. Navigator-only.)
|
|
72
83
|
- `contextWindowTokens` (default: `null` — context window used by the navigator's context-usage check; `null` infers from the session model and falls back to 200000. Set to the model's window, e.g. `1000000` on a 1M model. Navigator-only.)
|
|
73
84
|
- `contextWarnThreshold` (default: `0.7` — fraction of the window past which the navigator recommends a clean session. Navigator-only.)
|
|
74
|
-
- `autoVerify` (default: `false` — when `true`, `forge-verify` runs automatically after a stage completes, no prompt. **In-stage-primary:** the just-completed authoring stage runs it itself, in-session, before the exit block (honoring the verify-before-clear principle). The navigator runs it only as a **catch-up** when verify is still pending (a host that could not dispatch a clean-room subagent, or a stage run before this behavior landed). Either way it runs in a fresh clean-room subagent, so it never needs a
|
|
85
|
+
- `autoVerify` (default: `false` — when `true`, `forge-verify` runs automatically after a stage completes, no prompt. **In-stage-primary:** the just-completed authoring stage runs it itself, in-session, before the exit block (honoring the verify-before-clear principle). The navigator runs it only as a **catch-up** when verify is still pending (a host that could not dispatch a clean-room subagent, or a stage run before this behavior landed). Either way it runs in a fresh clean-room subagent, so it never needs a session clear and costs only a compact digest.)
|
|
75
86
|
- `autoVerifyStages` (default: `{}` — per-stage overrides for `autoVerify`, e.g. `{"forge-1-prd": false}`. Effective value = `autoVerifyStages[stage]` if present, else `autoVerify`. Keys are constrained to the five verify-capable stages; a typo is a config error surfaced as `invalidAutoVerifyKeys`. Both the in-stage run and the navigator catch-up read this same effective value.)
|
|
76
87
|
- `autoFix` (default: `false` — when `true`, `forge-fix` is chained after an auto-verify that finds issues — by the in-stage run (primary) or the navigator catch-up — but only when auto-verify is on for that stage AND preconditions hold (zero unresolved decisions, clean tree, passing re-verify); otherwise a digest is surfaced and the gate is presented.)
|
|
77
88
|
- `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`.)
|
|
@@ -81,7 +92,7 @@ Extract these config values (use defaults if not present):
|
|
|
81
92
|
Before any file I/O against a feature's artifacts, resolve its directory through the deterministic helper rather than hardcoding `{specsDir}/{feature}/`. This makes flat (`{specsDir}/{feature}/`) and nested (`{specsDir}/{epic}/{feature}/`) layouts both resolve from a bare feature name (REQ-DIR-03), with standalone features behaving exactly as today.
|
|
82
93
|
|
|
83
94
|
```bash
|
|
84
|
-
R="$(bash -c 'for d in "${
|
|
95
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
85
96
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
86
97
|
resolvedFeatureDir=$(python3 "$R/scripts/epic-manifest.py" \
|
|
87
98
|
resolve "<feature>" --specs-dir "<specsDir>")
|
|
@@ -96,12 +107,12 @@ In both failure cases, do not fall back to a guessed path.
|
|
|
96
107
|
**On `not-found`, check other branches before stopping.** With `branchPerFeature`, the feature's directory (and its `.pipeline-state.json`) may exist only on its topic branch — invisible from the default branch of a fresh clone. Before concluding the pipeline does not exist, run the read-only cross-branch discovery:
|
|
97
108
|
|
|
98
109
|
```bash
|
|
99
|
-
R="$(bash -c 'for d in "${
|
|
110
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
100
111
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
101
112
|
python3 "$R/scripts/forge-session.py" discover-feature "<feature>" --specs-dir "<specsDir>" --json
|
|
102
113
|
```
|
|
103
114
|
|
|
104
|
-
- **Candidates found** (`candidates` and/or `remoteCandidates` non-empty): summarize them as text (branch, recorded stage, whether the state's own `branch` field matches), then use
|
|
115
|
+
- **Candidates found** (`candidates` and/or `remoteCandidates` non-empty): summarize them as text (branch, recorded stage, whether the state's own `branch` field matches), then use the host's question mechanism: **Switch to `{branch}` (recommended)** — run the candidate's `switchCommand` · **Fetch + switch** — for a `needsFetch` remote candidate, run its `fetchCommand` then `switchCommand` (note its contents were matched by name only, not inspected) · **Treat `{feature}` as new on this branch** · **Stop**. A checkout is a mutation inside an otherwise read-only flow: perform it ONLY on the user's explicit accept AND with a clean working tree (`git status --porcelain` prints nothing) — never auto-switch, never with uncommitted changes. After a successful switch, re-run this Feature Directory Resolution block from the top.
|
|
105
116
|
- **Nothing found** (both lists empty): the pipeline genuinely does not exist anywhere discoverable — STOP and surface the original `not-found` stderr line verbatim (or, where the caller offers to start a new pipeline, offer that).
|
|
106
117
|
|
|
107
118
|
**Anti-fabrication guard.** Never describe pipeline state that resolution or discovery did not return: if both come back empty, the pipeline does not exist — say exactly that, and never reconstruct stages, backlogs, or history from conversational memory.
|
|
@@ -124,16 +135,16 @@ Whenever a stage creates the specs tree for the first time (the first PRD or epi
|
|
|
124
135
|
Run this after creating the feature/epic directory, before the stage's git commit:
|
|
125
136
|
|
|
126
137
|
```bash
|
|
127
|
-
R="$(bash -c 'for d in "${
|
|
138
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
128
139
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
129
140
|
mkdir -p "<specsDir>"
|
|
130
141
|
[ -f "<specsDir>/AGENTS.md" ] || cp "$R/references/templates/specs-hygiene/AGENTS.md" "<specsDir>/AGENTS.md"
|
|
131
142
|
```
|
|
132
143
|
|
|
133
|
-
If the host is Claude (the
|
|
144
|
+
If the host is Claude (the Claude-native question tool is available), also ensure the Claude-framed variant:
|
|
134
145
|
|
|
135
146
|
```bash
|
|
136
|
-
R="$(bash -c 'for d in "${
|
|
147
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-forge "$HOME"/.claude/plugins/cache/*/feature-forge/* "$HOME"/.claude/plugins/*/feature-forge "$HOME"/.agents/skills/feature-forge ./.agents/skills/feature-forge; do [ -x "$d/scripts/forge-root.sh" ] && exec "$d/scripts/forge-root.sh"; done')"
|
|
137
148
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
138
149
|
[ -f "<specsDir>/CLAUDE.md" ] || cp "$R/references/templates/specs-hygiene/CLAUDE.md" "<specsDir>/CLAUDE.md"
|
|
139
150
|
```
|
|
@@ -153,7 +164,7 @@ After resolving the feature directory, check the feature's `.pipeline-state.json
|
|
|
153
164
|
To obtain the manifest contracts and the live completion status of each dependency in one deterministic call, run `render-status` and read the per-feature `status` and the `consumes`/`exposes` arrays rather than re-deriving them:
|
|
154
165
|
|
|
155
166
|
```bash
|
|
156
|
-
R="$(bash -c 'for d in "${
|
|
167
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
157
168
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
158
169
|
python3 "$R/scripts/epic-manifest.py" \
|
|
159
170
|
render-status "<epic>" --specs-dir "<specsDir>" --json
|
|
@@ -168,7 +179,7 @@ If `render-status` fails, proceed with **only** EPIC.md + charter (a corrupt man
|
|
|
168
179
|
Defense-in-depth for the split-brain-epic failure (Issue #125). Invoke this block in the authoring stages (`forge-1-prd`..`forge-4-backlog`) once the feature has resolved — right after **Epic Context Injection** for the stages that run it (`forge-1-prd`..`forge-3-specs`), and right after **Feature Directory Resolution** for `forge-4-backlog`. It confirms that a **resolved nested epic member** actually sits on a branch that contains the epic's manifest. Without this, a member reached from a branch cut *before* the epic-manifest commit (or that otherwise lacks it) would author specs against an epic decomposition that is not present — the exact drift that produces a disjoint, split-brain member. **Skip if not a git repo or `branchPerFeature` is false.**
|
|
169
180
|
|
|
170
181
|
```bash
|
|
171
|
-
R="$(bash -c 'for d in "${
|
|
182
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
172
183
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
173
184
|
python3 "$R/scripts/forge-session.py" check-epic-base --feature "{feature}" --specs-dir "{specsDir}" --json
|
|
174
185
|
```
|
|
@@ -191,7 +202,7 @@ Pipeline state is written by the `state-*` verbs of `scripts/forge-session.py`
|
|
|
191
202
|
|
|
192
203
|
If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbatim, do **not** proceed to the next step of the surrounding protocol, and do **not** hand-author the JSON as a workaround. The stage remains resumable because the entry stamp is already on disk — re-run the verb once the cause is fixed.
|
|
193
204
|
|
|
194
|
-
**The
|
|
205
|
+
**The nine `state-*` verbs.** `state-enter` (Stage-Entry Guard), `state-artifact` (incremental artifact tracking), `state-complete` (Git Commit Protocol), `state-skip` (the deliberate forge-6-docs documentation skip — scoped to that one stage; writes `status: "skipped"` + `skippedAt`, refuses to erase a record of docs that exist, and is the only sanctioned writer of a skipped docs stage), `state-branch` (Branch Setup and Branch Reconciliation), `state-note` (the Immediate Downstream Note below, and the optional completion note at stage closure), `state-decision` (deferred decisions), `state-ecr` (epic change requests), and `state-verify` (one `forge-verify-*` verification transition — below). The `--epic` member requirement and the exit-2 failure protocol above apply to **every** one of them, `state-verify` included; no verify entry is ever hand-authored.
|
|
195
206
|
|
|
196
207
|
### `state-verify` — verification results and provenance
|
|
197
208
|
|
|
@@ -200,7 +211,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
|
|
|
200
211
|
**`auto-verify-pending` is not a skill-facing status.** It is written by `stage-exit`'s scheduling boundary, which records the debt automatically when auto-verify is effective for a stage. The value is accepted on this CLI so the entry stays inspectable and repairable, not so a skill can hand-schedule verification: no skill body and no reference passes it, and none should. Every other status in the list is the recorded *result* of a verification that ran (or was explicitly skipped); this one records that one was *owed*.
|
|
201
212
|
|
|
202
213
|
```bash
|
|
203
|
-
R="$(bash -c 'for d in "${
|
|
214
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
204
215
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
205
216
|
python3 "$R/scripts/forge-session.py" state-verify \
|
|
206
217
|
--feature "{feature}" --stage "{served-production-stage}" --status "<status>" \
|
|
@@ -210,7 +221,7 @@ python3 "$R/scripts/forge-session.py" state-verify \
|
|
|
210
221
|
Provenance follows the same two-commit sequence as `state-complete`: the result transition above writes `commitHash: null`, Commit 1 records the findings document and the state, and a second `state-verify` call records the full 40-hex hash of Commit 1 and touches nothing else (never `--amend`; an abbreviated hash is refused rather than expanded). Add `--epic "{epic}"` for an epic member — required, per the member rule above:
|
|
211
222
|
|
|
212
223
|
```bash
|
|
213
|
-
R="$(bash -c 'for d in "${
|
|
224
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
214
225
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
215
226
|
python3 "$R/scripts/forge-session.py" state-verify \
|
|
216
227
|
--feature "{feature}" --stage "{served-production-stage}" \
|
|
@@ -220,7 +231,7 @@ python3 "$R/scripts/forge-session.py" state-verify \
|
|
|
220
231
|
Epic-scoped verification is the single exception to the member rule: with `--stage forge-0-epic`, `--feature` names the **epic** and `--epic` must be absent or exactly equal to it. That call writes `{specsDir}/{epic}/.epic-state.json` and never a member's `.pipeline-state.json`, and its freshness version is the epic manifest's `revision`, never a member's stage version:
|
|
221
232
|
|
|
222
233
|
```bash
|
|
223
|
-
R="$(bash -c 'for d in "${
|
|
234
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
224
235
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
225
236
|
python3 "$R/scripts/forge-session.py" state-verify \
|
|
226
237
|
--feature "{epic}" --stage forge-0-epic --status "<status>" \
|
|
@@ -242,7 +253,7 @@ Frame the choice with its cost: re-running re-derives this stage from the curren
|
|
|
242
253
|
When an interview raises a concern that belongs to a *later stage of this same feature*, acknowledge it and persist it **immediately, at the moment it is raised** — not at stage closure — by running `state-note` with a concise one-line statement of the concern. Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol above; omitting it for a member is an error and must never be allowed to fall back to a same-named flat feature.
|
|
243
254
|
|
|
244
255
|
```bash
|
|
245
|
-
R="$(bash -c 'for d in "${
|
|
256
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
246
257
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
247
258
|
python3 "$R/scripts/forge-session.py" state-note \
|
|
248
259
|
--feature "{feature}" --note "<concise downstream concern>" \
|
|
@@ -275,7 +286,7 @@ Invoke this block at the **very start** of a pipeline entry point — `forge-1-p
|
|
|
275
286
|
1. Read the current branch: `git rev-parse --abbrev-ref HEAD`.
|
|
276
287
|
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.
|
|
277
288
|
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.
|
|
278
|
-
4. **If the current branch IS the default branch** → use
|
|
289
|
+
4. **If the current branch IS the default branch** → use the host's question mechanism with a **strong recommendation** (still optional):
|
|
279
290
|
|
|
280
291
|
> "You're on `{defaultBranch}`. Strongly recommended: create `{branchPrefix}{label}` so this {scope}'s work stays isolated and reviewable as one branch. Create it?"
|
|
281
292
|
> Options: **Create `{branchPrefix}{label}` (recommended)** · **Stay on `{defaultBranch}`**
|
|
@@ -286,7 +297,7 @@ Invoke this block at the **very start** of a pipeline entry point — `forge-1-p
|
|
|
286
297
|
**Record the branch.** After this block resolves, record the resulting branch name in the feature's top-level `branch` field by running `state-branch` (create/update it when the state file is first written for this stage). Emit the call **once the feature directory exists** — i.e. after Feature Directory Resolution and the Entry Stamp, **not** at this block: Branch Setup runs at the very start of the entry point, before any directory resolution, and a brand-new standalone feature may have no directory yet. Add `--epic "{epic}"` to the call when this feature is an epic member — required, per the Pipeline State Protocol.
|
|
287
298
|
|
|
288
299
|
```bash
|
|
289
|
-
R="$(bash -c 'for d in "${
|
|
300
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
290
301
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
291
302
|
python3 "$R/scripts/forge-session.py" state-branch \
|
|
292
303
|
--feature "{feature}" --branch "<name>" --specs-dir "{specsDir}"
|
|
@@ -299,20 +310,20 @@ Downstream stages and `forge-5-loop` read it to detect drift back onto the defau
|
|
|
299
310
|
The recorded `branch` is a **self-healing hint, not gospel.** A hosted environment (Claude.ai remote, cloud agents) can impose an arbitrary session branch (e.g. `claude/<slug>`) that Branch Setup silently records; the user may then move the work to the intended topic branch, leaving the recorded field stale. Every branch-aware mechanism (the `forge-5-loop` guard, `discover-feature`) keys off that field, so a stale value actively misleads — the loop would offer to switch you *back* to the imposed branch. Invoke this block from `forge-5-loop`'s pre-flight (and any stage that acts on the recorded branch) to reconcile deterministically. Skip if not a git repo or `branchPerFeature` is false.
|
|
300
311
|
|
|
301
312
|
```bash
|
|
302
|
-
R="$(bash -c 'for d in "${
|
|
313
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
303
314
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
304
315
|
python3 "$R/scripts/forge-session.py" reconcile-branch --feature "{feature}" --specs-dir "{specsDir}" --json
|
|
305
316
|
```
|
|
306
317
|
|
|
307
318
|
Act on the emitted `action` (source of truth is where the state actually resolves, not the recorded field):
|
|
308
319
|
- **`adopt-current`** — you are on a non-default topic branch where the state resolves, and the recorded `branch` differs (a stale/imposed value). Run `state-branch` (below) to write `newBranch` into the state `branch` field, with a **visible one-line note** ("recorded branch was `{stateBranch}`; work is on `{currentBranch}` — updating to match") — never silently, and **never push the user back** to the recorded branch (offer that only as a plain alternative).
|
|
309
|
-
- **`warn-drift`** — you are on the **default** branch and the state records a topic branch. Via
|
|
320
|
+
- **`warn-drift`** — you are on the **default** branch and the state records a topic branch. Via the host's question mechanism, strongly recommend creating/switching to `{branchPrefix}{feature}` (then record it), still allowing **proceed on the default branch**. Never hard-stop.
|
|
310
321
|
- **`none`** / **`not-resolved`** — nothing to do; proceed.
|
|
311
322
|
|
|
312
323
|
The `adopt-current` write, with the portable plugin-root prelude. Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol:
|
|
313
324
|
|
|
314
325
|
```bash
|
|
315
|
-
R="$(bash -c 'for d in "${
|
|
326
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
316
327
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
317
328
|
python3 "$R/scripts/forge-session.py" state-branch \
|
|
318
329
|
--feature "{feature}" --branch "{newBranch}" --specs-dir "{specsDir}"
|
|
@@ -338,7 +349,7 @@ When `gitCommitAfterStage` is true, follow this exact order to avoid state incon
|
|
|
338
349
|
The two `state-complete` calls, with the portable plugin-root prelude. Add `--epic "{epic}"` to each when this feature is an epic member — required, per the Pipeline State Protocol:
|
|
339
350
|
|
|
340
351
|
```bash
|
|
341
|
-
R="$(bash -c 'for d in "${
|
|
352
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
342
353
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
343
354
|
# Commit 1 — before `git commit`
|
|
344
355
|
python3 "$R/scripts/forge-session.py" state-complete \
|
|
@@ -360,15 +371,15 @@ Invoke this block at the **start of an authoring stage** (`forge-1-prd`..`forge-
|
|
|
360
371
|
|
|
361
372
|
2. **Interrupted** (`status: "in-progress"`) — a previous run of THIS stage was interrupted before it committed (the exit commit is what flips it to `complete`, so `in-progress` on entry always means a crash/abandon). Do **not** silently re-author. Instead:
|
|
362
373
|
- **Inventory on-disk artifacts:** list the files this stage produces that already exist in `{resolvedFeatureDir}/` (e.g. `PRD.md`; `tech-spec.md`; the `##-*.md` suite + `TRACEABILITY.md`; `backlog.json`), and cross-check against the `stages.{stage}.artifacts` array (written incrementally during the previous run).
|
|
363
|
-
- **Gate via
|
|
374
|
+
- **Gate via the host's question mechanism** (Decision Support protocol): present the inventory as text, then ask "This {stage} run was interrupted — {N} artifact(s) from the previous run are on disk: {list}. Resume the in-progress draft, or start a new version from scratch?" Options: **Resume (recommended)** — continue from the first artifact not yet written/complete, reusing the existing files; do **not** re-stamp or bump the version. · **Start a new version** — treat it as a fresh authoring pass (proceed to the Entry Stamp; the version increments at exit).
|
|
364
375
|
- Skip artifact regeneration for files that already exist and are complete (non-empty, properly structured); continue from the next unwritten artifact.
|
|
365
376
|
|
|
366
|
-
3. **Re-authoring** (`status: "complete"` or `"stale"`) — a finished draft exists. Warn via
|
|
377
|
+
3. **Re-authoring** (`status: "complete"` or `"stale"`) — a finished draft exists. Warn via the host's question mechanism before overwriting: "A completed {stage} artifact already exists for '{feature}' (v{n}{, marked stale}). Continuing will create a new version. Proceed?" On confirm, proceed to the Entry Stamp and author a new version (the version increments at exit, per that stage's Update-Pipeline-State step).
|
|
367
378
|
|
|
368
379
|
**Entry Stamp** (fresh, restart, and re-author paths — NOT the resume path). Before authoring, record the entry stamp by running `state-enter` — one atomic write that sets `stages.{stage}.status` → `"in-progress"`, `stages.{stage}.startedAt` → current ISO-8601 UTC timestamp, top-level `currentStage` → `"{stage}"` (where the pipeline IS, per O1), and refreshes `updatedAt`. Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol:
|
|
369
380
|
|
|
370
381
|
```bash
|
|
371
|
-
R="$(bash -c 'for d in "${
|
|
382
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
372
383
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
373
384
|
python3 "$R/scripts/forge-session.py" state-enter \
|
|
374
385
|
--feature "{feature}" --stage "{stage}" --specs-dir "{specsDir}"
|
|
@@ -381,7 +392,7 @@ This write is **left uncommitted**: it is staged and committed as part of this s
|
|
|
381
392
|
**Incremental artifact tracking:** When a stage writes multiple files (e.g. forge-3-specs writing a suite of spec documents), run `state-artifact --feature {feature} --stage {stage} --path <file>` after writing each file — not just at stage completion. This is what makes the Interrupted inventory above precise about which files were successfully written. Add `--epic "{epic}"` when this feature is an epic member — required, per the Pipeline State Protocol.
|
|
382
393
|
|
|
383
394
|
```bash
|
|
384
|
-
R="$(bash -c 'for d in "${
|
|
395
|
+
R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$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')"
|
|
385
396
|
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
386
397
|
python3 "$R/scripts/forge-session.py" state-artifact \
|
|
387
398
|
--feature "{feature}" --stage "{stage}" --path "<file>" --specs-dir "{specsDir}"
|
|
@@ -395,7 +406,7 @@ Invoke this block **at the head of any post-entry step that writes a stage artif
|
|
|
395
406
|
|
|
396
407
|
1. **Proceed** when `stages.{stage}.status` is `"in-progress"` (this session's Entry Stamp — you are finishing the run you started) or absent/`pending`. Run the write / exit normally.
|
|
397
408
|
|
|
398
|
-
2. **Detect-and-refuse** when ALL of these hold: `stages.{stage}.status ∈ {"complete", "stale"}` **AND** the stage's artifacts (incl. `TRACEABILITY.md` for forge-3-specs) exist on disk **AND** a `commitHash` is recorded for the stage **AND** you did **not** author this stage earlier in the current session. This is a stale/replayed continuation of an already-finished, committed stage. Do **not** overwrite the artifact or re-run the exit. Route instead to the **Stage-Entry Guard**'s *Re-authoring* path: surface the same
|
|
409
|
+
2. **Detect-and-refuse** when ALL of these hold: `stages.{stage}.status ∈ {"complete", "stale"}` **AND** the stage's artifacts (incl. `TRACEABILITY.md` for forge-3-specs) exist on disk **AND** a `commitHash` is recorded for the stage **AND** you did **not** author this stage earlier in the current session. This is a stale/replayed continuation of an already-finished, committed stage. Do **not** overwrite the artifact or re-run the exit. Route instead to the **Stage-Entry Guard**'s *Re-authoring* path: surface the same warning via the host's question mechanism ("A completed {stage} artifact already exists for '{feature}' (v{n}{, marked stale}). Continuing will create a new version. Proceed?"). Only on explicit confirmation re-enter from the Entry Stamp (the version bumps at exit); otherwise **stop** and report that the stage is already complete — cite the recorded `commitHash` and offer `/feature-forge:forge {feature}` to see true state.
|
|
399
410
|
|
|
400
411
|
When you cannot confirm you authored the current run, treat it as a replay and refuse: a false refuse costs one confirmation click; a false proceed overwrites a committed artifact and re-churns a stage version. `--force` follows Force Mode (skip the gate, treat as a deliberate re-author).
|
|
401
412
|
|