@garygentry/feature-forge 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/adapters/GENERATION-REPORT.md +128 -0
- package/adapters/claude/agents/forge-researcher.md +137 -0
- package/adapters/claude/agents/forge-spec-writer.md +115 -0
- package/adapters/claude/agents/forge-verifier.md +121 -0
- package/adapters/claude/references/epic-manifest-schema.json +120 -0
- package/adapters/claude/references/forge-config-schema.json +166 -0
- package/adapters/claude/references/pipeline-state-schema.json +110 -0
- package/adapters/claude/references/portable-root.md +56 -0
- package/adapters/claude/references/process-overview.md +123 -0
- package/adapters/claude/references/ralph-loop-contract.md +221 -0
- package/adapters/claude/references/shared-conventions.md +144 -0
- package/adapters/claude/references/skill-frontmatter.schema.json +17 -0
- package/adapters/claude/references/stack-resolution.md +51 -0
- package/adapters/claude/references/stacks/_generic.md +90 -0
- package/adapters/claude/references/stacks/go.md +138 -0
- package/adapters/claude/references/stacks/python.md +163 -0
- package/adapters/claude/references/stacks/rust.md +151 -0
- package/adapters/claude/references/stacks/typescript.md +111 -0
- package/adapters/claude/references/vendor-construct-inventory.md +49 -0
- package/adapters/claude/scripts/forge-root.sh +50 -0
- package/adapters/claude/skills/forge/SKILL.md +165 -0
- package/adapters/claude/skills/forge-0-epic/SKILL.md +303 -0
- package/adapters/claude/skills/forge-0-epic/references/edit-mode.md +222 -0
- package/adapters/claude/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
- package/adapters/claude/skills/forge-1-prd/SKILL.md +121 -0
- package/adapters/claude/skills/forge-1-prd/references/prd-template.md +106 -0
- package/adapters/claude/skills/forge-2-tech/SKILL.md +198 -0
- package/adapters/claude/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
- package/adapters/claude/skills/forge-3-specs/SKILL.md +154 -0
- package/adapters/claude/skills/forge-3-specs/references/spec-archetypes.md +106 -0
- package/adapters/claude/skills/forge-3-specs/references/spec-examples.md +71 -0
- package/adapters/claude/skills/forge-4-backlog/SKILL.md +146 -0
- package/adapters/claude/skills/forge-5-loop/SKILL.md +303 -0
- package/adapters/claude/skills/forge-5-loop/references/result-reporting.md +63 -0
- package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +214 -0
- package/adapters/claude/skills/forge-6-docs/SKILL.md +179 -0
- package/adapters/claude/skills/forge-6-docs/references/doc-conventions.md +126 -0
- package/adapters/claude/skills/forge-fix/SKILL.md +65 -0
- package/adapters/claude/skills/forge-init/SKILL.md +29 -0
- package/adapters/claude/skills/forge-verify/SKILL.md +219 -0
- package/adapters/claude/skills/forge-verify/references/verification-checklists.md +379 -0
- package/adapters/codex/agents/forge-researcher.md +133 -0
- package/adapters/codex/agents/forge-spec-writer.md +112 -0
- package/adapters/codex/agents/forge-verifier.md +115 -0
- package/adapters/codex/agents/openai.yaml +10 -0
- package/adapters/codex/references/epic-manifest-schema.json +120 -0
- package/adapters/codex/references/forge-config-schema.json +166 -0
- package/adapters/codex/references/pipeline-state-schema.json +110 -0
- package/adapters/codex/references/portable-root.md +56 -0
- package/adapters/codex/references/process-overview.md +123 -0
- package/adapters/codex/references/ralph-loop-contract.md +221 -0
- package/adapters/codex/references/shared-conventions.md +144 -0
- package/adapters/codex/references/skill-frontmatter.schema.json +17 -0
- package/adapters/codex/references/stack-resolution.md +51 -0
- package/adapters/codex/references/stacks/_generic.md +90 -0
- package/adapters/codex/references/stacks/go.md +138 -0
- package/adapters/codex/references/stacks/python.md +163 -0
- package/adapters/codex/references/stacks/rust.md +151 -0
- package/adapters/codex/references/stacks/typescript.md +111 -0
- package/adapters/codex/references/vendor-construct-inventory.md +49 -0
- package/adapters/codex/scripts/forge-root.sh +50 -0
- package/adapters/codex/skills/forge/forge.md +164 -0
- package/adapters/codex/skills/forge-0-epic/forge-0-epic.md +302 -0
- package/adapters/codex/skills/forge-0-epic/references/edit-mode.md +222 -0
- package/adapters/codex/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
- package/adapters/codex/skills/forge-1-prd/forge-1-prd.md +120 -0
- package/adapters/codex/skills/forge-1-prd/references/prd-template.md +106 -0
- package/adapters/codex/skills/forge-2-tech/forge-2-tech.md +197 -0
- package/adapters/codex/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
- package/adapters/codex/skills/forge-3-specs/forge-3-specs.md +153 -0
- package/adapters/codex/skills/forge-3-specs/references/spec-archetypes.md +106 -0
- package/adapters/codex/skills/forge-3-specs/references/spec-examples.md +71 -0
- package/adapters/codex/skills/forge-4-backlog/forge-4-backlog.md +145 -0
- package/adapters/codex/skills/forge-5-loop/forge-5-loop.md +302 -0
- package/adapters/codex/skills/forge-5-loop/references/result-reporting.md +63 -0
- package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +214 -0
- package/adapters/codex/skills/forge-6-docs/forge-6-docs.md +178 -0
- package/adapters/codex/skills/forge-6-docs/references/doc-conventions.md +126 -0
- package/adapters/codex/skills/forge-fix/forge-fix.md +64 -0
- package/adapters/codex/skills/forge-init/forge-init.md +29 -0
- package/adapters/codex/skills/forge-verify/forge-verify.md +218 -0
- package/adapters/codex/skills/forge-verify/references/verification-checklists.md +379 -0
- package/adapters/copilot/agents/forge-researcher.md +133 -0
- package/adapters/copilot/agents/forge-spec-writer.md +112 -0
- package/adapters/copilot/agents/forge-verifier.md +115 -0
- package/adapters/copilot/references/epic-manifest-schema.json +120 -0
- package/adapters/copilot/references/forge-config-schema.json +166 -0
- package/adapters/copilot/references/pipeline-state-schema.json +110 -0
- package/adapters/copilot/references/portable-root.md +56 -0
- package/adapters/copilot/references/process-overview.md +123 -0
- package/adapters/copilot/references/ralph-loop-contract.md +221 -0
- package/adapters/copilot/references/shared-conventions.md +144 -0
- package/adapters/copilot/references/skill-frontmatter.schema.json +17 -0
- package/adapters/copilot/references/stack-resolution.md +51 -0
- package/adapters/copilot/references/stacks/_generic.md +90 -0
- package/adapters/copilot/references/stacks/go.md +138 -0
- package/adapters/copilot/references/stacks/python.md +163 -0
- package/adapters/copilot/references/stacks/rust.md +151 -0
- package/adapters/copilot/references/stacks/typescript.md +111 -0
- package/adapters/copilot/references/vendor-construct-inventory.md +49 -0
- package/adapters/copilot/scripts/forge-root.sh +50 -0
- package/adapters/copilot/skills/forge/forge.md +164 -0
- package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +302 -0
- package/adapters/copilot/skills/forge-0-epic/references/edit-mode.md +222 -0
- package/adapters/copilot/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
- package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +120 -0
- package/adapters/copilot/skills/forge-1-prd/references/prd-template.md +106 -0
- package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +197 -0
- package/adapters/copilot/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
- package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +153 -0
- package/adapters/copilot/skills/forge-3-specs/references/spec-archetypes.md +106 -0
- package/adapters/copilot/skills/forge-3-specs/references/spec-examples.md +71 -0
- package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +145 -0
- package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +302 -0
- package/adapters/copilot/skills/forge-5-loop/references/result-reporting.md +63 -0
- package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +214 -0
- package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +178 -0
- package/adapters/copilot/skills/forge-6-docs/references/doc-conventions.md +126 -0
- package/adapters/copilot/skills/forge-fix/forge-fix.md +64 -0
- package/adapters/copilot/skills/forge-init/forge-init.md +29 -0
- package/adapters/copilot/skills/forge-verify/forge-verify.md +218 -0
- package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +379 -0
- package/adapters/cursor/agents/forge-researcher.mdc +134 -0
- package/adapters/cursor/agents/forge-spec-writer.mdc +113 -0
- package/adapters/cursor/agents/forge-verifier.mdc +116 -0
- package/adapters/cursor/references/epic-manifest-schema.json +120 -0
- package/adapters/cursor/references/forge-config-schema.json +166 -0
- package/adapters/cursor/references/pipeline-state-schema.json +110 -0
- package/adapters/cursor/references/portable-root.md +56 -0
- package/adapters/cursor/references/process-overview.md +123 -0
- package/adapters/cursor/references/ralph-loop-contract.md +221 -0
- package/adapters/cursor/references/shared-conventions.md +144 -0
- package/adapters/cursor/references/skill-frontmatter.schema.json +17 -0
- package/adapters/cursor/references/stack-resolution.md +51 -0
- package/adapters/cursor/references/stacks/_generic.md +90 -0
- package/adapters/cursor/references/stacks/go.md +138 -0
- package/adapters/cursor/references/stacks/python.md +163 -0
- package/adapters/cursor/references/stacks/rust.md +151 -0
- package/adapters/cursor/references/stacks/typescript.md +111 -0
- package/adapters/cursor/references/vendor-construct-inventory.md +49 -0
- package/adapters/cursor/scripts/forge-root.sh +50 -0
- package/adapters/cursor/skills/forge/forge.mdc +165 -0
- package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +303 -0
- package/adapters/cursor/skills/forge-0-epic/references/edit-mode.md +222 -0
- package/adapters/cursor/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
- package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +121 -0
- package/adapters/cursor/skills/forge-1-prd/references/prd-template.md +106 -0
- package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +198 -0
- package/adapters/cursor/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
- package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +154 -0
- package/adapters/cursor/skills/forge-3-specs/references/spec-archetypes.md +106 -0
- package/adapters/cursor/skills/forge-3-specs/references/spec-examples.md +71 -0
- package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +146 -0
- package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +303 -0
- package/adapters/cursor/skills/forge-5-loop/references/result-reporting.md +63 -0
- package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +214 -0
- package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +179 -0
- package/adapters/cursor/skills/forge-6-docs/references/doc-conventions.md +126 -0
- package/adapters/cursor/skills/forge-fix/forge-fix.mdc +65 -0
- package/adapters/cursor/skills/forge-init/forge-init.mdc +30 -0
- package/adapters/cursor/skills/forge-verify/forge-verify.mdc +219 -0
- package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +379 -0
- package/adapters/gemini/agents/forge-researcher.md +133 -0
- package/adapters/gemini/agents/forge-spec-writer.md +112 -0
- package/adapters/gemini/agents/forge-verifier.md +115 -0
- package/adapters/gemini/gemini-extension.json +54 -0
- package/adapters/gemini/references/epic-manifest-schema.json +120 -0
- package/adapters/gemini/references/forge-config-schema.json +166 -0
- package/adapters/gemini/references/pipeline-state-schema.json +110 -0
- package/adapters/gemini/references/portable-root.md +56 -0
- package/adapters/gemini/references/process-overview.md +123 -0
- package/adapters/gemini/references/ralph-loop-contract.md +221 -0
- package/adapters/gemini/references/shared-conventions.md +144 -0
- package/adapters/gemini/references/skill-frontmatter.schema.json +17 -0
- package/adapters/gemini/references/stack-resolution.md +51 -0
- package/adapters/gemini/references/stacks/_generic.md +90 -0
- package/adapters/gemini/references/stacks/go.md +138 -0
- package/adapters/gemini/references/stacks/python.md +163 -0
- package/adapters/gemini/references/stacks/rust.md +151 -0
- package/adapters/gemini/references/stacks/typescript.md +111 -0
- package/adapters/gemini/references/vendor-construct-inventory.md +49 -0
- package/adapters/gemini/scripts/forge-root.sh +50 -0
- package/adapters/gemini/skills/forge/forge.md +164 -0
- package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +302 -0
- package/adapters/gemini/skills/forge-0-epic/references/edit-mode.md +222 -0
- package/adapters/gemini/skills/forge-0-epic/references/epic-manifest-subcommands.md +64 -0
- package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +120 -0
- package/adapters/gemini/skills/forge-1-prd/references/prd-template.md +106 -0
- package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +197 -0
- package/adapters/gemini/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
- package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +153 -0
- package/adapters/gemini/skills/forge-3-specs/references/spec-archetypes.md +106 -0
- package/adapters/gemini/skills/forge-3-specs/references/spec-examples.md +71 -0
- package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +145 -0
- package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +302 -0
- package/adapters/gemini/skills/forge-5-loop/references/result-reporting.md +63 -0
- package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +214 -0
- package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +178 -0
- package/adapters/gemini/skills/forge-6-docs/references/doc-conventions.md +126 -0
- package/adapters/gemini/skills/forge-fix/forge-fix.md +64 -0
- package/adapters/gemini/skills/forge-init/forge-init.md +29 -0
- package/adapters/gemini/skills/forge-verify/forge-verify.md +218 -0
- package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +379 -0
- package/dist/agent-targets.d.ts +70 -0
- package/dist/agent-targets.js +111 -0
- package/dist/apply.d.ts +49 -0
- package/dist/apply.js +246 -0
- package/dist/cli.d.ts +94 -0
- package/dist/cli.js +508 -0
- package/dist/detect.d.ts +45 -0
- package/dist/detect.js +72 -0
- package/dist/fsutil.d.ts +56 -0
- package/dist/fsutil.js +175 -0
- package/dist/hash.d.ts +50 -0
- package/dist/hash.js +107 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +9 -0
- package/dist/manifest.d.ts +72 -0
- package/dist/manifest.js +222 -0
- package/dist/plan.d.ts +66 -0
- package/dist/plan.js +166 -0
- package/dist/rauf.d.ts +83 -0
- package/dist/rauf.js +118 -0
- package/dist/report.d.ts +35 -0
- package/dist/report.js +110 -0
- package/dist/source.d.ts +69 -0
- package/dist/source.js +164 -0
- package/dist/types.d.ts +264 -0
- package/dist/types.js +57 -0
- package/package.json +42 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
# GENERATED — DO NOT EDIT. Source: skills/forge-4-backlog/SKILL.md. Regenerate: python3 scripts/build-adapters.py
|
|
3
|
+
name: forge-4-backlog
|
|
4
|
+
description: Generate a structured backlog.json from forge implementation specs, then validate it via the loop runner. Use when user runs /feature-forge:forge-4-backlog or asks to create a backlog for a forge feature after specs are complete. This is the canonical backlog generator for the forge pipeline. Do NOT trigger for standalone backlog creation outside the forge pipeline context.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# forge-4-backlog — Backlog Generator (pipeline orchestrator)
|
|
8
|
+
|
|
9
|
+
Generate a complete, validated `backlog.json` from the implementation spec
|
|
10
|
+
suite, ready for the loop runner.
|
|
11
|
+
|
|
12
|
+
This skill is a **thin orchestrator**: it owns the *pipeline* concerns
|
|
13
|
+
(prerequisite checks, spec loading, plan review, validation, pipeline-state and
|
|
14
|
+
commit). The actual **authoring craft** — granularity, acceptance criteria,
|
|
15
|
+
`agentDelegation`, the schema, examples — lives in the rauf plugin's
|
|
16
|
+
**`author-backlog`** skill, which this skill delegates to. That keeps a single
|
|
17
|
+
home for backlog-authoring knowledge, shared with the repo-wide ad-hoc flow.
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
Read and follow `references/shared-conventions.md` for feature name validation, configuration reading, and force mode handling before proceeding. Resolve the feature directory `{resolvedFeatureDir}` via the **Feature Directory Resolution** block in `references/shared-conventions.md` — do not hardcode `{specsDir}/{feature}/` (see Step 1).
|
|
22
|
+
|
|
23
|
+
Resolve the **backlog directory** `{backlogDir}`:
|
|
24
|
+
- **`backlogDir` unset (default):** the backlog lives at the resolved feature directory — `{resolvedFeatureDir}/backlog.json` — for both flat and nested features, exactly as today.
|
|
25
|
+
- **`backlogDir` configured:** compose a **per-feature subpath** — `{backlogDir}/{feature}/` — so each epic member's backlog stays independent (the authored file lands at `{backlogDir}/{feature}/backlog.json`). A bare shared `backlogDir` would collide across a multi-feature epic and violate REQ-COMPAT-03; the `{feature}` segment prevents that. Standalone features under a configured `backlogDir` likewise resolve to `{backlogDir}/{feature}/`, which is backward-compatible because each standalone feature name is already unique.
|
|
26
|
+
|
|
27
|
+
This is the **single** place this rule is implemented. forge-5-loop's backlog-file check must read the same composed `{backlogDir}/{feature}/backlog.json` (that matching forge-5-loop edit lands in item 016), and forge-verify's backlog-mode load uses the same path. rauf itself is unchanged: backlogs remain per-feature and rauf is still launched against a single per-feature backlog path — only the *path composition* changes (REQ-COMPAT-03).
|
|
28
|
+
|
|
29
|
+
**Let `{resolvedBacklogDir}` denote the composed target of this rule** — i.e. `{backlogDir}/{feature}` when a `backlogDir` is configured, else `{resolvedFeatureDir}`. Every downstream step below (authoring, validation) uses `{resolvedBacklogDir}`, never the bare config value, so the per-feature `{feature}` segment is never dropped.
|
|
30
|
+
|
|
31
|
+
Resolve the **loop runner** from the `loopRunner` block in `forge.config.json`, filling missing fields from the defaults in `references/forge-config-schema.json` (defaults to rauf). You need its `bin`, `validateCommand`, `versionCommand`, `minRunnerVersion`, and `installHint`.
|
|
32
|
+
|
|
33
|
+
**Turn structure reminder:** Output analysis/context as text, then route ALL questions through `AskUserQuestion`. Never embed questions in text output — the user will not be prompted and the session will stall.
|
|
34
|
+
|
|
35
|
+
## Step 1: Validate Prerequisites
|
|
36
|
+
|
|
37
|
+
**Resolve the feature directory first.** Invoke the **Feature Directory Resolution** block in `references/shared-conventions.md` to turn the bare feature name into `{resolvedFeatureDir}` (exit 0 → stdout is the absolute dir; exit ≥ 1 → STOP and surface the finding verbatim). Read state and specs from `{resolvedFeatureDir}/` everywhere this skill previously wrote `{specsDir}/{feature}/`. Standalone features resolve to their flat path exactly as today.
|
|
38
|
+
|
|
39
|
+
**Prerequisite check:** Read `{resolvedFeatureDir}/.pipeline-state.json`. If not in force mode, stages `forge-1-prd`, `forge-2-tech`, and `forge-3-specs` must all be `complete`. If not, STOP and tell the user which prerequisites are missing.
|
|
40
|
+
|
|
41
|
+
**Strongly recommended:** Check if specs have been verified. If not, use `AskUserQuestion` to warn: "Specs haven't been verified yet. It's recommended to run `/feature-forge:forge-verify {feature}` first. Continue anyway?"
|
|
42
|
+
|
|
43
|
+
## Step 2: Load All Specs
|
|
44
|
+
|
|
45
|
+
Read all spec documents into context:
|
|
46
|
+
- `{resolvedFeatureDir}/PRD.md`
|
|
47
|
+
- `{resolvedFeatureDir}/tech-spec.md`
|
|
48
|
+
- `{resolvedFeatureDir}/##-*.md` (all implementation specs)
|
|
49
|
+
|
|
50
|
+
If the spec suite is large (8+ documents), focus on loading the architecture layout (01-*), shared types (00-*), and testing strategy documents first. Load individual subsystem specs as needed when writing the corresponding backlog items, rather than loading all specs simultaneously.
|
|
51
|
+
|
|
52
|
+
## Step 3: Plan the Backlog
|
|
53
|
+
|
|
54
|
+
Before writing any JSON, walk the specs and create a backlog plan: discrete work items, ordered by dependency (foundation first), with priorities, each scoped for a single loop iteration.
|
|
55
|
+
|
|
56
|
+
Present the plan as a numbered list:
|
|
57
|
+
```
|
|
58
|
+
Proposed backlog for {feature} ({N} items):
|
|
59
|
+
|
|
60
|
+
001 [P1] Scaffold module with project manifest, build config, and entry points
|
|
61
|
+
Depends on: (none)
|
|
62
|
+
Specs: 00-core-definitions.md, 01-architecture-layout.md
|
|
63
|
+
|
|
64
|
+
002 [P1] Implement shared types and error hierarchy
|
|
65
|
+
Depends on: 001
|
|
66
|
+
Specs: 00-core-definitions.md
|
|
67
|
+
...
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
After presenting the plan as text, use `AskUserQuestion` to ask: "Does this breakdown look right? Any items to split, merge, or reorder?" Do NOT include this question in your text output. Wait for the user's response before generating the JSON.
|
|
71
|
+
|
|
72
|
+
## Step 4: Author backlog.json — delegate to `author-backlog`
|
|
73
|
+
|
|
74
|
+
**Invoke the rauf plugin's `author-backlog` skill** (via the Skill tool) to write
|
|
75
|
+
`{resolvedBacklogDir}/backlog.json`. Pass it:
|
|
76
|
+
|
|
77
|
+
- the target backlog directory `{resolvedBacklogDir}`,
|
|
78
|
+
- the approved plan from Step 3,
|
|
79
|
+
- the spec context loaded in Step 2,
|
|
80
|
+
- the project's `typeCheckCommand` / `testCommand` (from `forge.config.json`) so acceptance criteria are concrete and runnable.
|
|
81
|
+
|
|
82
|
+
`author-backlog` owns all item-quality rules (granularity hard limits, self-contained descriptions, acceptance criteria, `agentDelegation`, the correct `type`/`status` enums, `dependsOn`, `specReferences`, the schema source). Do not re-encode them here — follow whatever it produces.
|
|
83
|
+
|
|
84
|
+
> **If the rauf plugin / `author-backlog` skill is not available:** fall back to
|
|
85
|
+
> authoring inline using the schema source rule (prefer the project's installed
|
|
86
|
+
> `{stateDir}/backlog.schema.json`, else the published `$id`
|
|
87
|
+
> `https://raw.githubusercontent.com/garygentry/rauf/main/schemas/backlog.schema.json`),
|
|
88
|
+
> and tell the user the rauf plugin provides richer authoring guidance.
|
|
89
|
+
|
|
90
|
+
**Forge-specific item requirements** layered on top of `author-backlog`'s output:
|
|
91
|
+
- `specReferences` must be paths **relative to the project root** (e.g. `specs/auth/00-core-definitions.md`), NOT relative to the backlog file. The validator resolves them from the project root (not from `--specs-dir`, which only gates the check).
|
|
92
|
+
|
|
93
|
+
> **Backlog schema & rauf contract are unchanged (REQ-COMPAT-03).** Epic membership adds **no** fields to backlog items — dependency edges live in the epic manifest, never in any backlog item. The JSON written here is byte-for-byte the same shape as a pre-epic standalone feature's backlog, and rauf is still launched against a single per-feature backlog path. Only the *path composition* changes (the `{feature}` segment in the backlog-directory rule above), not the schema or rauf's CLI surface.
|
|
94
|
+
|
|
95
|
+
## Step 5: Validate via the loop runner
|
|
96
|
+
|
|
97
|
+
Validate the generated backlog by running the runner's **validate command**
|
|
98
|
+
(`loopRunner.validateCommand`), rendered with `{resolvedBacklogDir}` and `{specsDir}`
|
|
99
|
+
substituted — the rauf default:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
rauf backlog validate . --backlog {resolvedBacklogDir} --specs-dir {specsDir} --json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Interpret the result:
|
|
106
|
+
- **exit 0** → valid (warnings allowed). Proceed.
|
|
107
|
+
- **exit 1** → validation findings. Parse `{ valid, findings[] }`, fix the items, re-run. Do NOT present the backlog to the user until it validates.
|
|
108
|
+
- **exit 2** → usage/IO error (unreadable file, bad JSON). Fix and re-run.
|
|
109
|
+
|
|
110
|
+
> **forge-4 runs before forge-5's install gate**, so the runner may not be set
|
|
111
|
+
> up yet. Degrade gracefully rather than hard-failing:
|
|
112
|
+
> 1. First run `loopRunner.versionCommand` (`rauf version --json`). If the
|
|
113
|
+
> binary is **missing**, or its version is **< `minRunnerVersion`**
|
|
114
|
+
> (semver-compare), do NOT block authoring: keep the authored backlog, emit a
|
|
115
|
+
> loud warning with `loopRunner.installHint`, mark validation as skipped, and
|
|
116
|
+
> continue to Step 6. forge-5 will enforce the gate before running.
|
|
117
|
+
> 2. If the binary is present and new enough but the project isn't set up
|
|
118
|
+
> (`validate` reports the project marker missing), likewise warn and continue
|
|
119
|
+
> — validation will run cleanly once `rauf install .` has been done.
|
|
120
|
+
|
|
121
|
+
## Step 6: Review with User
|
|
122
|
+
|
|
123
|
+
Present a summary: total items N, dependency-chain depth, estimated loop iterations (`ceil(pendingItems * loopIterationMultiplier)`). Note whether validation passed or was skipped (runner not yet available).
|
|
124
|
+
|
|
125
|
+
Use `AskUserQuestion` to ask: "Ready to proceed, or any adjustments needed?"
|
|
126
|
+
|
|
127
|
+
## Step 7: Update Pipeline State and Commit
|
|
128
|
+
|
|
129
|
+
Write pipeline state conforming to `references/pipeline-state-schema.json`. Follow the Git Commit Protocol in `references/shared-conventions.md`.
|
|
130
|
+
|
|
131
|
+
1. Update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
132
|
+
- Record `artifacts` (path to backlog.json)
|
|
133
|
+
- Set `stages.forge-4-backlog.basedOnVersions` to `{"forge-1-prd": <current version>, "forge-2-tech": <current version>, "forge-3-specs": <current version>}`
|
|
134
|
+
- Set `currentStage` to `forge-5-loop`
|
|
135
|
+
- Check downstream stages (`forge-5-loop`, `forge-6-docs`). If any have `basedOnVersions` referencing an older version of `forge-4-backlog`, set their status to `stale`.
|
|
136
|
+
2. Use `AskUserQuestion` to ask about notes to persist
|
|
137
|
+
3. If `gitCommitAfterStage` is true, follow the Git Commit Protocol: stage files, attempt commit, then set status to `complete` with commit hash only on success. If commit fails, leave status as `in-progress`.
|
|
138
|
+
4. If verification was available but the user chose to skip it, record `stages.forge-verify-backlog.status` as `"skipped"` in pipeline state.
|
|
139
|
+
5. Tell user: "Backlog complete with {N} items. Next steps:\n - `/feature-forge:forge-verify {feature}` to verify the backlog\n - `/feature-forge:forge-5-loop {feature}` to run the loop\n - `/feature-forge:forge {feature}` to see full pipeline status"
|
|
140
|
+
|
|
141
|
+
## Gotchas
|
|
142
|
+
|
|
143
|
+
- The loop runs each item in a FRESH context. Every item description must be self-contained — `author-backlog` enforces this, but double-check Step-3 plan items aren't "same as above."
|
|
144
|
+
- Spec references must be project-root-relative paths that actually exist — the validate command enforces this when `--specs-dir` is passed (resolving them from the project root).
|
|
145
|
+
- Don't present a backlog to the user before it validates (or before you've explicitly recorded that validation was skipped because the runner isn't installed yet).
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
---
|
|
2
|
+
# GENERATED — DO NOT EDIT. Source: skills/forge-5-loop/SKILL.md. Regenerate: python3 scripts/build-adapters.py
|
|
3
|
+
name: forge-5-loop
|
|
4
|
+
description: Execute the autonomous coding loop (rauf by default) against a forge feature's backlog. Use when user runs /feature-forge:forge-5-loop or /feature-forge:forge-5-rauf-loop, or asks to run rauf / run the loop / implement a forge feature after the backlog is created and verified. Do NOT trigger for general rauf usage, standalone loop runs, or implementation tasks outside the forge pipeline.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# forge-5-loop — Autonomous Loop Executor
|
|
8
|
+
|
|
9
|
+
Execute the autonomous coding loop against a forge feature's backlog. The loop
|
|
10
|
+
spawns a fresh agent session per backlog item, implementing each task with full
|
|
11
|
+
verification.
|
|
12
|
+
|
|
13
|
+
The loop **runner** is configured, not hardcoded. feature-forge talks to it
|
|
14
|
+
through the `loopRunner` block in `forge.config.json`; rauf is the default and
|
|
15
|
+
reference implementation (see `references/ralph-loop-contract.md`). Every command
|
|
16
|
+
below is rendered from `loopRunner` with token substitution — there are no
|
|
17
|
+
hardcoded `rauf …` commands in this skill, and even the human log filename is
|
|
18
|
+
tokenized as `{loopRunner.logFile}`.
|
|
19
|
+
|
|
20
|
+
## Resolve the loop runner
|
|
21
|
+
|
|
22
|
+
Read `forge.config.json`. Build the effective `loopRunner` by taking its
|
|
23
|
+
`loopRunner` block (if present) and filling any missing field from the defaults
|
|
24
|
+
in `references/forge-config-schema.json`. **If `forge.config.json` has no
|
|
25
|
+
`loopRunner` block at all, state plainly: "No loopRunner configured — defaulting
|
|
26
|
+
to the rauf loop runner."** then proceed with the full default block.
|
|
27
|
+
|
|
28
|
+
Token substitution applies to every `*Command` string. Substitute:
|
|
29
|
+
|
|
30
|
+
- `{bin}` → `loopRunner.bin` (default `rauf`)
|
|
31
|
+
- `{backlogDir}` → the resolved backlog directory (Step 1d / 2b), relative to project root
|
|
32
|
+
- `{specsDir}` → `specsDir` from config
|
|
33
|
+
- `{iterations}` → the computed iteration count (Step 2a)
|
|
34
|
+
|
|
35
|
+
Whenever this skill says "run the **run command**" / "**status command**" /
|
|
36
|
+
etc., it means the corresponding substituted `loopRunner.*Command`.
|
|
37
|
+
|
|
38
|
+
**Turn structure reminder:** Output analysis/context as text, then route ALL questions through `AskUserQuestion`. Never embed questions in text output — the user will not be prompted and the session will stall.
|
|
39
|
+
|
|
40
|
+
## Step 1: Validate Prerequisites
|
|
41
|
+
|
|
42
|
+
Read and follow `references/shared-conventions.md` for feature name validation, configuration reading, and force mode handling.
|
|
43
|
+
|
|
44
|
+
### 1a. Pipeline State Check
|
|
45
|
+
|
|
46
|
+
**Resolve the feature directory first.** Invoke the **Feature Directory Resolution** block in `references/shared-conventions.md` to turn the bare feature name into `{resolvedFeatureDir}` (exit 0 → stdout is the absolute dir; exit ≥ 1 → STOP and surface the finding verbatim). Read state from `{resolvedFeatureDir}/` everywhere this skill previously wrote `{specsDir}/{feature}/` (the 1e backlog path and the Step 3a / Step 5 state writes). Standalone features resolve to their flat path exactly as today.
|
|
47
|
+
|
|
48
|
+
Read `{resolvedFeatureDir}/.pipeline-state.json`. If not in force mode, `stages.forge-4-backlog` must be `complete`. If not, STOP and tell the user: "Backlog hasn't been created yet. Run `/feature-forge:forge-4-backlog {feature}` first."
|
|
49
|
+
|
|
50
|
+
### 1b. Verification Check
|
|
51
|
+
|
|
52
|
+
Check if `stages.forge-verify-backlog` exists and has status `passed` or `findings-applied`. If not, use `AskUserQuestion` to warn:
|
|
53
|
+
|
|
54
|
+
"Backlog hasn't been verified yet. It's recommended to run `/feature-forge:forge-verify {feature}` first to catch issues before implementation. Continue anyway?"
|
|
55
|
+
|
|
56
|
+
### 1b-epic. Epic Dependency Gate
|
|
57
|
+
|
|
58
|
+
Read the resolved feature's `.pipeline-state.json`. **If it has no `epic` key, skip this sub-step entirely** (standalone feature — REQ-COMPAT-01; standalone runs are unchanged). Otherwise:
|
|
59
|
+
|
|
60
|
+
1. Run `render-status "{epic}" --specs-dir "{specsDir}" --json` via the helper:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
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)"
|
|
64
|
+
[ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
|
|
65
|
+
python3 "$R/scripts/epic-manifest.py" \
|
|
66
|
+
render-status "{epic}" --specs-dir "{specsDir}" --json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
2. Find this feature's entry; read its `unmetDeps` (the direct `dependsOn` not yet complete-for-orchestration per `00-core-definitions.md §7`).
|
|
70
|
+
3. **If `unmetDeps` is empty**, proceed to 1c with no prompt.
|
|
71
|
+
4. **If `unmetDeps` is non-empty**, use `AskUserQuestion` (do NOT inline the question as prose) to warn that the feature depends on the unmet dependencies, which are not yet complete, and that running the loop now means implementing against contracts that may still change:
|
|
72
|
+
|
|
73
|
+
> "{feature} depends on {unmetDeps joined}, which are not yet complete. Running the loop now means implementing against contracts that may still change. Proceed anyway, or stop and finish the dependencies first?"
|
|
74
|
+
|
|
75
|
+
Require an **explicit "Proceed anyway"** choice to continue (REQ-ORCH-04). "Stop" aborts before any runner setup. `--force` (shared-conventions Force Mode) also bypasses this gate with the standard force warning.
|
|
76
|
+
5. If `render-status` fails, **STOP** — do not silently run a loop whose dependency state is unverifiable (REQ-ROBUST-02). Surface per the exit-1/exit-2 split in the **Feature Directory Resolution** block of `references/shared-conventions.md` (exit 1 → parse `{findings[]}` from stdout; exit 2 → surface the plain `Error:` stderr line verbatim — no findings JSON to parse).
|
|
77
|
+
|
|
78
|
+
This gate runs **before** the runner version/setup gates (1c/1d) so a blocked feature stops early, before any runner side-effects.
|
|
79
|
+
|
|
80
|
+
### 1c. Runner Version Gate
|
|
81
|
+
|
|
82
|
+
Enforce `loopRunner.minRunnerVersion` **before** doing anything else with the runner. This is what turns "the runner is missing or too old" into a clear, actionable stop instead of a cryptic mid-run failure.
|
|
83
|
+
|
|
84
|
+
1. Run the **version command** (`loopRunner.versionCommand`, default `rauf version --json`) via Bash.
|
|
85
|
+
2. Parse `{ "version": "<semver>" }` from stdout. Do NOT use plain `rauf version` (its human output is `rauf v0.6.0` with a `v` prefix) — always the `--json` form.
|
|
86
|
+
3. **Semver-compare** (NOT string-compare) the reported version against `loopRunner.minRunnerVersion` (default `0.6.0`), numerically by major, then minor, then patch.
|
|
87
|
+
|
|
88
|
+
**Any of the following is a HARD GATE FAILURE — do NOT proceed to run the loop.** STOP, show `loopRunner.installHint`, and include the raw command output for diagnosis:
|
|
89
|
+
|
|
90
|
+
- The version command is not found or exits non-zero (the binary isn't installed).
|
|
91
|
+
- Its stdout is not valid JSON, has no `version` field, or `version` is not a valid semver string.
|
|
92
|
+
- The reported version is **< `minRunnerVersion`**.
|
|
93
|
+
|
|
94
|
+
For the version-too-old case, phrase it concretely, e.g.: "Your rauf is {reported}, but feature-forge needs ≥ {minRunnerVersion} — 0.6.0 is the floor that ships the agent-selection surface (`--agent` / `rauf agents`) the loop relies on. {installHint}". When the gate fails because the output couldn't be parsed, say so and show what the command printed before the `installHint`.
|
|
95
|
+
|
|
96
|
+
> `installHint` points at the runner **CLI** install/upgrade — distinct from
|
|
97
|
+
> `setupHint` (1d), which installs the runner's per-project artifacts.
|
|
98
|
+
|
|
99
|
+
### 1d. Runner Setup Check (precondition file)
|
|
100
|
+
|
|
101
|
+
Check that `loopRunner.preconditionFile` (default `.rauf.json`) exists in the project root. If not:
|
|
102
|
+
|
|
103
|
+
- **If `loopRunner.name == "rauf"` and a legacy `.ralph.json` (or `.ralph/` directory) exists**, this is an un-migrated Ralph project. STOP and tell the user:
|
|
104
|
+
|
|
105
|
+
"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}`."
|
|
106
|
+
|
|
107
|
+
- **Otherwise**, STOP and show `loopRunner.setupHint` (default: "Run `rauf install .` …"), e.g.:
|
|
108
|
+
|
|
109
|
+
"The loop runner isn't set up in this project ({preconditionFile} is missing). {setupHint}"
|
|
110
|
+
|
|
111
|
+
### 1e. Backlog File Check
|
|
112
|
+
|
|
113
|
+
Resolve the backlog file path (matching forge-4-backlog's composition rule, item 015 / §6.2):
|
|
114
|
+
- If `backlogDir` is set in `forge.config.json`: use `{backlogDir}/{feature}/backlog.json` (the per-feature subpath, so each epic member's backlog stays independent — the `{feature}` segment prevents collisions across a multi-feature epic)
|
|
115
|
+
- Otherwise: use `{resolvedFeatureDir}/backlog.json`
|
|
116
|
+
|
|
117
|
+
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."
|
|
118
|
+
|
|
119
|
+
## Step 2: Construct the Loop Command
|
|
120
|
+
|
|
121
|
+
### 2a. Analyze Backlog
|
|
122
|
+
|
|
123
|
+
Run the **list command** (`loopRunner.listCommand`, default `rauf backlog list . --backlog {backlogDir} --json`) and count items by status: `pending`, `in_progress`, `done`, `blocked`.
|
|
124
|
+
|
|
125
|
+
Calculate the iteration count: `ceil((pending + in_progress) * loopIterationMultiplier)` where `loopIterationMultiplier` comes from `forge.config.json` (default: 1.5). This headroom allows retries without exhausting iterations.
|
|
126
|
+
|
|
127
|
+
If there are no pending or in_progress items, STOP and tell the user: "All backlog items are already done or blocked. Nothing to run."
|
|
128
|
+
|
|
129
|
+
If there are `blocked` items, note them — the user may want `--retry-blocked`.
|
|
130
|
+
|
|
131
|
+
### 2b. Resolve Backlog Directory
|
|
132
|
+
|
|
133
|
+
`{backlogDir}` is a **directory path** (not a file path), relative to the project root.
|
|
134
|
+
|
|
135
|
+
- If `backlogDir` is set in config: use the per-feature subpath `{backlogDir}/{feature}` (matching the 1e composition rule and forge-4-backlog §6.2).
|
|
136
|
+
- Otherwise: use `{resolvedFeatureDir}` (the directory containing `backlog.json`).
|
|
137
|
+
|
|
138
|
+
**Example:** If `specsDir` is `./specs` and feature is `auth`, `{backlogDir}` is `specs/auth`.
|
|
139
|
+
|
|
140
|
+
### 2c. Build Command
|
|
141
|
+
|
|
142
|
+
Render the **run command** (`loopRunner.runCommand`) with token substitution, e.g. the rauf default becomes:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
rauf loop run . --backlog specs/auth --iterations 15
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 2d. Confirm with User
|
|
149
|
+
|
|
150
|
+
Use `AskUserQuestion` to present the rendered run command and options. The following block is the content for `AskUserQuestion` — do NOT output it as text:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
Ready to run the loop for {feature}:
|
|
154
|
+
|
|
155
|
+
{rendered runCommand}
|
|
156
|
+
|
|
157
|
+
Backlog summary:
|
|
158
|
+
- Pending: {pending}
|
|
159
|
+
- In progress: {in_progress}
|
|
160
|
+
- Done: {done}
|
|
161
|
+
- Blocked: {blocked}
|
|
162
|
+
- Iterations: {iterationCount} ({activeItems} items x {loopIterationMultiplier} multiplier)
|
|
163
|
+
|
|
164
|
+
Optional flags you can add (rauf): --review, --model <model>, --timeout <min>,
|
|
165
|
+
--retry-blocked. For the full optional-flags catalog and the model-selection
|
|
166
|
+
precedence (item.model > --model/options > project default > provider default),
|
|
167
|
+
read references/runner-contract.md.
|
|
168
|
+
|
|
169
|
+
Proceed with this command, or would you like to adjust?
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
For the full loop-runner contract — event-stream vs. log-fallback launch, the live-supervision/monitor rules, and the model-selection precedence — read `references/runner-contract.md`. If the user requests additional flags, append them to the rendered run command.
|
|
173
|
+
|
|
174
|
+
#### Agent selection (gated on `loopRunner.agentArgument`)
|
|
175
|
+
|
|
176
|
+
**Capability gate.** Everything below applies **only when** the effective `loopRunner.agentArgument` is present and non-empty. **When it is absent or empty, Step 2d is exactly the confirmation above — no probe, no agent question, no availability listing, no `Agent:` line — byte-identical to today** (REQ-PLUG-02, REQ-COMPAT-01). The full algorithm, precedence, and verbatim message shapes are in `## Agent selection` of `references/runner-contract.md`; read it. When the gate is on, augment Step 2d in order:
|
|
177
|
+
|
|
178
|
+
- **(a) Probe once.** Before confirming, run `loopRunner.agentsProbeCommand` (default `{bin} agents --json`) **exactly once** (no retries, no second probe); it exits 0 with `{ agents: [...] }`. Parse `agents[]`; build the advertised set `{ row.id }` — this one parsed array drives (b)–(d).
|
|
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).
|
|
180
|
+
- **(c) Availability listing.** From the **same** parsed `agents[]` (no second probe), list `id` / `displayName` / available (`yes`/`no`, `detail` on unavailable rows).
|
|
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
|
+
- **(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.
|
|
183
|
+
- **(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"`.
|
|
184
|
+
|
|
185
|
+
## Step 3: Execute the Loop
|
|
186
|
+
|
|
187
|
+
### 3a. Update Pipeline State
|
|
188
|
+
|
|
189
|
+
Before launching, update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
190
|
+
- Set `stages.forge-5-loop.status` to `in-progress`
|
|
191
|
+
- Set `stages.forge-5-loop.startedAt` to current ISO timestamp
|
|
192
|
+
- Set `currentStage` to `forge-5-loop`
|
|
193
|
+
- Update `updatedAt`
|
|
194
|
+
|
|
195
|
+
### 3b. Launch Background Process
|
|
196
|
+
|
|
197
|
+
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). 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`.
|
|
198
|
+
|
|
199
|
+
Loop runs can take significant time (minutes to hours depending on backlog size).
|
|
200
|
+
|
|
201
|
+
### 3c. Inform User
|
|
202
|
+
|
|
203
|
+
Tell the user the run has started and that **this session is now actively
|
|
204
|
+
supervising it** — they don't need to babysit a terminal — and surface the rendered
|
|
205
|
+
`loopRunner` monitoring commands (`statusCommand` / `followCommand` / `logCommand` /
|
|
206
|
+
`listCommand`) and the state-file locations under
|
|
207
|
+
`{backlogDir}/{loopRunner.stateDir}/` so they can watch directly if they like. The
|
|
208
|
+
verbatim "Loop started…" inform-user output template is in
|
|
209
|
+
`references/runner-contract.md`.
|
|
210
|
+
|
|
211
|
+
### 3d. Arm a Monitor on the event stream, and react to events
|
|
212
|
+
|
|
213
|
+
Arm the **`Monitor` tool** on the structured event stream (the NDJSON file, or the
|
|
214
|
+
human log as fallback) so events flow back into this session as they happen. Use
|
|
215
|
+
**`persistent: true`** — runs can exceed `Monitor`'s maximum `timeout_ms` (1 hour),
|
|
216
|
+
and a bounded timeout would silently stop watching a still-running loop. The filter
|
|
217
|
+
MUST match every terminal and exception state, not just the happy path (silence is
|
|
218
|
+
not success). Monitor the **structured** surface, never raw `RAUF_*` tokens.
|
|
219
|
+
|
|
220
|
+
Each Monitor event arrives as a message; react per type — surface `needs_human` /
|
|
221
|
+
`loop_error` immediately with a `PushNotification`, coalesce `item_completed` into
|
|
222
|
+
milestones, and treat `llm_stuck_warning` as a hang warning. A `needs_human` /
|
|
223
|
+
`blocked` signal does **not** pause the loop — the runner sets the item aside and
|
|
224
|
+
keeps going.
|
|
225
|
+
|
|
226
|
+
For the exact Monitor commands (NDJSON `jq` filter and the log-fallback `grep`
|
|
227
|
+
prefixes), the coverage-complete filter event list, and the full per-event reaction
|
|
228
|
+
rules, read `references/runner-contract.md`.
|
|
229
|
+
|
|
230
|
+
### 3f. Reach completion
|
|
231
|
+
|
|
232
|
+
Step 4 is reached when the backgrounded process exits (its completion notification is
|
|
233
|
+
authoritative); the `loop_completed` / `loop_error` / `loop_cancelled` event is the live
|
|
234
|
+
heads-up that it's imminent. Stop the Monitor (it ends on its own when `tail` sees the
|
|
235
|
+
process-ended log, or via `TaskStop`) and proceed to Step 4. Do NOT foreground-sleep
|
|
236
|
+
or poll — the harness drives both the Monitor events and the completion notification.
|
|
237
|
+
|
|
238
|
+
## Step 4: Check Results
|
|
239
|
+
|
|
240
|
+
When the background process completes (its exit notification):
|
|
241
|
+
|
|
242
|
+
### 4a. Get Final Backlog State
|
|
243
|
+
|
|
244
|
+
Run the **status-json command** (`loopRunner.statusJsonCommand`) and read
|
|
245
|
+
`backlogSummary` for the authoritative counts — it separates the three non-done
|
|
246
|
+
outcomes: genuine `blocked`, `needsHuman`, and runner-`deferred` ("false blocks").
|
|
247
|
+
Fall back to the **list command** (`loopRunner.listCommand`) if `statusJsonCommand`
|
|
248
|
+
is not configured. You will already have most of this from the live tally in 3e.
|
|
249
|
+
|
|
250
|
+
### 4b. Report Results
|
|
251
|
+
|
|
252
|
+
Present a summary to the user. Pick **every** branch that applies (a run can be both
|
|
253
|
+
blocked and needs-human) and render its report. The five verbatim result-report
|
|
254
|
+
output templates — **all-done**, **needs-human**, **blocked**, **deferred**, and
|
|
255
|
+
**pending** (iteration limit reached) — are in `references/result-reporting.md`.
|
|
256
|
+
|
|
257
|
+
## Step 5: Update Pipeline State
|
|
258
|
+
|
|
259
|
+
Update `{resolvedFeatureDir}/.pipeline-state.json`:
|
|
260
|
+
|
|
261
|
+
1. Set `stages.forge-5-loop`:
|
|
262
|
+
- `status`: `"complete"` if all backlog items are `done`, otherwise `"in-progress"`
|
|
263
|
+
- `completedAt`: current ISO timestamp (only if complete)
|
|
264
|
+
- `basedOnVersions`: `{"forge-4-backlog": <current version from pipeline state>}`
|
|
265
|
+
- `artifacts`: `["{backlogDir}/{loopRunner.stateDir}/state.json"]`
|
|
266
|
+
2. If all items complete: set `currentStage` to `"forge-6-docs"`
|
|
267
|
+
3. Update `updatedAt`
|
|
268
|
+
|
|
269
|
+
**No git commit is needed** — the loop runner commits atomically per completed item during the run. The implementation code is already committed.
|
|
270
|
+
|
|
271
|
+
> **Note:** Step 5's "no git commit needed" remark refers to *implementation code*, which the runner commits per-item. The epic handoff's commit in Step 6 below is of *pipeline state / manifest* — a distinct artifact — and applies only to epic members.
|
|
272
|
+
|
|
273
|
+
## Step 6: Epic Handoff
|
|
274
|
+
|
|
275
|
+
**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 exactly as today (REQ-COMPAT-01).
|
|
276
|
+
|
|
277
|
+
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:
|
|
278
|
+
|
|
279
|
+
> "{feature}'s loop is done. Recommended: run `/feature-forge:forge-verify {feature} impl` before unblocking dependents. Run it now, or skip and continue the handoff?"
|
|
280
|
+
|
|
281
|
+
The user may skip (then completion is judged on the §7 rule with impl-verify absent).
|
|
282
|
+
2. **Recompute and announce.** Run `render-status "{epic}" --specs-dir "{specsDir}" --json`. Announce the feature's completion and the epic rollup (e.g. "2/4 features complete") — derived live from disk, never re-computed in prose.
|
|
283
|
+
3. **Identify the next actionable feature(s).** Read `render-status`'s `actionable` set (features whose every dependency is now complete and that are not themselves complete) and `nextCommand`.
|
|
284
|
+
- **None actionable** (everything done, or remaining features still blocked): say so.
|
|
285
|
+
- If `rollup.total > 0` **AND** `rollup.complete == rollup.total`, suggest `/feature-forge:forge-6-docs {feature}` and note the epic-level documentation offer (§10). The `rollup.total > 0` guard prevents an **empty epic** (`0 == 0`) from being reported complete.
|
|
286
|
+
- Otherwise, list what is still blocked and on which dependencies. End — do not prompt to start a feature that cannot start.
|
|
287
|
+
- **One or more actionable:** use `AskUserQuestion` presenting **each actionable feature** as an option (plus "stop here"). Execution is **serial** — the user picks exactly one (REQ-ORCH-03). Do **not** autonomously chain into the next pipeline.
|
|
288
|
+
4. **Begin the chosen feature.** For the picked feature:
|
|
289
|
+
- **PRD absent** (no `PRD.md`, or `stages.forge-1-prd` not complete): offer to author it now — "Start `/feature-forge:forge-1-prd {chosen}`?" (REQ-ORCH-02). On yes, hand off to forge-1-prd (which injects epic context per §5.1).
|
|
290
|
+
- **PRD present:** point the user at the chosen feature's `nextCommand` from render-status.
|
|
291
|
+
5. **Commit (REQ-OBS-01).** When `gitCommitAfterStage` is true, commit the Step 5 completion write (and any manifest `updatedAt` bump) via the shared-conventions **Git Commit Protocol**, staging the epic subtree so the member state change commits atomically: `git add {specsDir}/{epic}/` then `{commitPrefix}({feature}): complete loop`. If `gitCommitAfterStage` is false, skip the commit.
|
|
292
|
+
|
|
293
|
+
## Gotchas
|
|
294
|
+
|
|
295
|
+
- `{backlogDir}` is a **directory path**, not a file path. Pass `specs/auth`, not `specs/auth/backlog.json`.
|
|
296
|
+
- 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.
|
|
297
|
+
- 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.
|
|
298
|
+
- 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.
|
|
299
|
+
- 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), which is harness-driven, not a sleep loop. Never `sleep`/poll in the foreground to wait for the loop.
|
|
300
|
+
- 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.
|
|
301
|
+
- 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.
|
|
302
|
+
- The version gate (1c) uses the `--json` form on purpose; never parse `rauf version`'s human output.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# forge-5-loop — Step 4b Result-Report Templates
|
|
2
|
+
|
|
3
|
+
These are the five verbatim result-report output templates for **Step 4b** of
|
|
4
|
+
`forge-5-loop/SKILL.md`. Pick **every** branch that applies (a run can be both
|
|
5
|
+
blocked and needs-human) and render its report.
|
|
6
|
+
|
|
7
|
+
**All items done:**
|
|
8
|
+
```
|
|
9
|
+
Loop completed for {feature}. All {N} items implemented successfully.
|
|
10
|
+
|
|
11
|
+
Next steps:
|
|
12
|
+
- /feature-forge:forge-verify {feature} impl Verify the implementation
|
|
13
|
+
- /feature-forge:forge-6-docs {feature} Generate architecture docs
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Some items need a human:**
|
|
17
|
+
```
|
|
18
|
+
Loop completed for {feature}.
|
|
19
|
+
Completed: {done}/{total}
|
|
20
|
+
Needs human: {needsHuman} items (set aside during the run)
|
|
21
|
+
|
|
22
|
+
These items asked a question the loop couldn't answer:
|
|
23
|
+
- {id}: {title} — {reason}
|
|
24
|
+
|
|
25
|
+
Resolve, then retry:
|
|
26
|
+
- Answer the question(s) above, then re-run `/feature-forge:forge-5-loop {feature}`
|
|
27
|
+
(add --retry-blocked to pick the set-aside items back up).
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Some items blocked:**
|
|
31
|
+
```
|
|
32
|
+
Loop completed for {feature}.
|
|
33
|
+
Completed: {done}/{total}
|
|
34
|
+
Blocked: {blocked} items
|
|
35
|
+
|
|
36
|
+
Blocked items:
|
|
37
|
+
- {id}: {title}
|
|
38
|
+
- {id}: {title}
|
|
39
|
+
|
|
40
|
+
Options:
|
|
41
|
+
- Re-run with --retry-blocked to retry blocked items
|
|
42
|
+
- Review blocked items manually: {bin} backlog show . {id} --backlog {backlogDir}
|
|
43
|
+
- Continue to docs if blocking items are non-critical
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Some items deferred (runner gave up after retries — "false blocks"):**
|
|
47
|
+
```
|
|
48
|
+
Loop completed for {feature}.
|
|
49
|
+
Completed: {done}/{total}
|
|
50
|
+
Deferred: {deferred} items (no signal after retries — likely just need another pass)
|
|
51
|
+
|
|
52
|
+
Re-run `/feature-forge:forge-5-loop {feature}` to retry deferred items.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Some items still pending (iteration limit reached):**
|
|
56
|
+
```
|
|
57
|
+
Loop completed for {feature}.
|
|
58
|
+
Completed: {done}/{total}
|
|
59
|
+
Pending: {pending} items (iteration limit reached)
|
|
60
|
+
Blocked: {blocked} items
|
|
61
|
+
|
|
62
|
+
Re-run `/feature-forge:forge-5-loop {feature}` to continue with remaining items.
|
|
63
|
+
```
|