@garygentry/feature-forge 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/README.md +1 -1
  2. package/adapters/claude/.feature-forge-bundle.json +1 -1
  3. package/adapters/claude/references/forge-config-schema.json +4 -4
  4. package/adapters/claude/references/ralph-loop-contract.md +12 -8
  5. package/adapters/claude/references/shared-conventions.md +1 -1
  6. package/adapters/claude/scripts/forge-session.py +30 -26
  7. package/adapters/claude/skills/forge/references/shared-conventions.md +1 -1
  8. package/adapters/claude/skills/forge-0-epic/references/shared-conventions.md +1 -1
  9. package/adapters/claude/skills/forge-1-prd/references/shared-conventions.md +1 -1
  10. package/adapters/claude/skills/forge-2-tech/references/shared-conventions.md +1 -1
  11. package/adapters/claude/skills/forge-3-specs/references/shared-conventions.md +1 -1
  12. package/adapters/claude/skills/forge-4-backlog/references/shared-conventions.md +1 -1
  13. package/adapters/claude/skills/forge-5-loop/SKILL.md +3 -3
  14. package/adapters/claude/skills/forge-5-loop/references/ralph-loop-contract.md +12 -8
  15. package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +2 -2
  16. package/adapters/claude/skills/forge-5-loop/references/shared-conventions.md +1 -1
  17. package/adapters/claude/skills/forge-6-docs/references/shared-conventions.md +1 -1
  18. package/adapters/claude/skills/forge-fix/references/shared-conventions.md +1 -1
  19. package/adapters/claude/skills/forge-guide/references/forge-config-schema.json +4 -4
  20. package/adapters/claude/skills/forge-guide/references/ralph-loop-contract.md +12 -8
  21. package/adapters/claude/skills/forge-guide/references/shared-conventions.md +1 -1
  22. package/adapters/claude/skills/forge-verify/SKILL.md +5 -3
  23. package/adapters/claude/skills/forge-verify/references/findings-template.md +6 -6
  24. package/adapters/claude/skills/forge-verify/references/shared-conventions.md +1 -1
  25. package/adapters/codex/.feature-forge-bundle.json +1 -1
  26. package/adapters/codex/references/forge-config-schema.json +4 -4
  27. package/adapters/codex/references/ralph-loop-contract.md +12 -8
  28. package/adapters/codex/references/shared-conventions.md +1 -1
  29. package/adapters/codex/scripts/forge-session.py +30 -26
  30. package/adapters/codex/skills/forge/references/shared-conventions.md +1 -1
  31. package/adapters/codex/skills/forge-0-epic/references/shared-conventions.md +1 -1
  32. package/adapters/codex/skills/forge-1-prd/references/shared-conventions.md +1 -1
  33. package/adapters/codex/skills/forge-2-tech/references/shared-conventions.md +1 -1
  34. package/adapters/codex/skills/forge-3-specs/references/shared-conventions.md +1 -1
  35. package/adapters/codex/skills/forge-4-backlog/references/shared-conventions.md +1 -1
  36. package/adapters/codex/skills/forge-5-loop/SKILL.md +3 -3
  37. package/adapters/codex/skills/forge-5-loop/references/ralph-loop-contract.md +12 -8
  38. package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +2 -2
  39. package/adapters/codex/skills/forge-5-loop/references/shared-conventions.md +1 -1
  40. package/adapters/codex/skills/forge-6-docs/references/shared-conventions.md +1 -1
  41. package/adapters/codex/skills/forge-fix/references/shared-conventions.md +1 -1
  42. package/adapters/codex/skills/forge-guide/references/forge-config-schema.json +4 -4
  43. package/adapters/codex/skills/forge-guide/references/ralph-loop-contract.md +12 -8
  44. package/adapters/codex/skills/forge-guide/references/shared-conventions.md +1 -1
  45. package/adapters/codex/skills/forge-verify/SKILL.md +5 -3
  46. package/adapters/codex/skills/forge-verify/references/findings-template.md +6 -6
  47. package/adapters/codex/skills/forge-verify/references/shared-conventions.md +1 -1
  48. package/adapters/copilot/.feature-forge-bundle.json +1 -1
  49. package/adapters/copilot/references/forge-config-schema.json +4 -4
  50. package/adapters/copilot/references/ralph-loop-contract.md +12 -8
  51. package/adapters/copilot/references/shared-conventions.md +1 -1
  52. package/adapters/copilot/scripts/forge-session.py +30 -26
  53. package/adapters/copilot/skills/forge/references/shared-conventions.md +1 -1
  54. package/adapters/copilot/skills/forge-0-epic/references/shared-conventions.md +1 -1
  55. package/adapters/copilot/skills/forge-1-prd/references/shared-conventions.md +1 -1
  56. package/adapters/copilot/skills/forge-2-tech/references/shared-conventions.md +1 -1
  57. package/adapters/copilot/skills/forge-3-specs/references/shared-conventions.md +1 -1
  58. package/adapters/copilot/skills/forge-4-backlog/references/shared-conventions.md +1 -1
  59. package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +3 -3
  60. package/adapters/copilot/skills/forge-5-loop/references/ralph-loop-contract.md +12 -8
  61. package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +2 -2
  62. package/adapters/copilot/skills/forge-5-loop/references/shared-conventions.md +1 -1
  63. package/adapters/copilot/skills/forge-6-docs/references/shared-conventions.md +1 -1
  64. package/adapters/copilot/skills/forge-fix/references/shared-conventions.md +1 -1
  65. package/adapters/copilot/skills/forge-guide/references/forge-config-schema.json +4 -4
  66. package/adapters/copilot/skills/forge-guide/references/ralph-loop-contract.md +12 -8
  67. package/adapters/copilot/skills/forge-guide/references/shared-conventions.md +1 -1
  68. package/adapters/copilot/skills/forge-verify/forge-verify.md +5 -3
  69. package/adapters/copilot/skills/forge-verify/references/findings-template.md +6 -6
  70. package/adapters/copilot/skills/forge-verify/references/shared-conventions.md +1 -1
  71. package/adapters/cursor/.feature-forge-bundle.json +1 -1
  72. package/adapters/cursor/references/forge-config-schema.json +4 -4
  73. package/adapters/cursor/references/ralph-loop-contract.md +12 -8
  74. package/adapters/cursor/references/shared-conventions.md +1 -1
  75. package/adapters/cursor/scripts/forge-session.py +30 -26
  76. package/adapters/cursor/skills/forge/references/shared-conventions.md +1 -1
  77. package/adapters/cursor/skills/forge-0-epic/references/shared-conventions.md +1 -1
  78. package/adapters/cursor/skills/forge-1-prd/references/shared-conventions.md +1 -1
  79. package/adapters/cursor/skills/forge-2-tech/references/shared-conventions.md +1 -1
  80. package/adapters/cursor/skills/forge-3-specs/references/shared-conventions.md +1 -1
  81. package/adapters/cursor/skills/forge-4-backlog/references/shared-conventions.md +1 -1
  82. package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +3 -3
  83. package/adapters/cursor/skills/forge-5-loop/references/ralph-loop-contract.md +12 -8
  84. package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +2 -2
  85. package/adapters/cursor/skills/forge-5-loop/references/shared-conventions.md +1 -1
  86. package/adapters/cursor/skills/forge-6-docs/references/shared-conventions.md +1 -1
  87. package/adapters/cursor/skills/forge-fix/references/shared-conventions.md +1 -1
  88. package/adapters/cursor/skills/forge-guide/references/forge-config-schema.json +4 -4
  89. package/adapters/cursor/skills/forge-guide/references/ralph-loop-contract.md +12 -8
  90. package/adapters/cursor/skills/forge-guide/references/shared-conventions.md +1 -1
  91. package/adapters/cursor/skills/forge-verify/forge-verify.mdc +5 -3
  92. package/adapters/cursor/skills/forge-verify/references/findings-template.md +6 -6
  93. package/adapters/cursor/skills/forge-verify/references/shared-conventions.md +1 -1
  94. package/adapters/gemini/.feature-forge-bundle.json +1 -1
  95. package/adapters/gemini/gemini-extension.json +1 -1
  96. package/adapters/gemini/references/forge-config-schema.json +4 -4
  97. package/adapters/gemini/references/ralph-loop-contract.md +12 -8
  98. package/adapters/gemini/references/shared-conventions.md +1 -1
  99. package/adapters/gemini/scripts/forge-session.py +30 -26
  100. package/adapters/gemini/skills/forge/references/shared-conventions.md +1 -1
  101. package/adapters/gemini/skills/forge-0-epic/references/shared-conventions.md +1 -1
  102. package/adapters/gemini/skills/forge-1-prd/references/shared-conventions.md +1 -1
  103. package/adapters/gemini/skills/forge-2-tech/references/shared-conventions.md +1 -1
  104. package/adapters/gemini/skills/forge-3-specs/references/shared-conventions.md +1 -1
  105. package/adapters/gemini/skills/forge-4-backlog/references/shared-conventions.md +1 -1
  106. package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +3 -3
  107. package/adapters/gemini/skills/forge-5-loop/references/ralph-loop-contract.md +12 -8
  108. package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +2 -2
  109. package/adapters/gemini/skills/forge-5-loop/references/shared-conventions.md +1 -1
  110. package/adapters/gemini/skills/forge-6-docs/references/shared-conventions.md +1 -1
  111. package/adapters/gemini/skills/forge-fix/references/shared-conventions.md +1 -1
  112. package/adapters/gemini/skills/forge-guide/references/forge-config-schema.json +4 -4
  113. package/adapters/gemini/skills/forge-guide/references/ralph-loop-contract.md +12 -8
  114. package/adapters/gemini/skills/forge-guide/references/shared-conventions.md +1 -1
  115. package/adapters/gemini/skills/forge-verify/forge-verify.md +5 -3
  116. package/adapters/gemini/skills/forge-verify/references/findings-template.md +6 -6
  117. package/adapters/gemini/skills/forge-verify/references/shared-conventions.md +1 -1
  118. package/adapters/pi/.feature-forge-bundle.json +1 -1
  119. package/adapters/pi/extensions/forge-loop-supervisor/events.ts +90 -0
  120. package/adapters/pi/extensions/forge-loop-supervisor/index.ts +114 -0
  121. package/adapters/pi/extensions/forge-loop-supervisor/registry.ts +137 -0
  122. package/adapters/pi/extensions/forge-loop-supervisor/supervisor.ts +185 -0
  123. package/adapters/pi/extensions/forge-loop-supervisor/tailer.ts +137 -0
  124. package/adapters/pi/extensions/forge-loop-supervisor/types.ts +87 -0
  125. package/adapters/pi/extensions/forge-loop-supervisor/wiring.ts +423 -0
  126. package/adapters/pi/package.json +2 -1
  127. package/adapters/pi/references/forge-config-schema.json +4 -4
  128. package/adapters/pi/references/ralph-loop-contract.md +12 -8
  129. package/adapters/pi/references/shared-conventions.md +1 -1
  130. package/adapters/pi/scripts/forge-session.py +30 -26
  131. package/adapters/pi/skills/forge/SKILL.md +4 -1
  132. package/adapters/pi/skills/forge/references/shared-conventions.md +1 -1
  133. package/adapters/pi/skills/forge-0-epic/SKILL.md +4 -1
  134. package/adapters/pi/skills/forge-0-epic/references/shared-conventions.md +1 -1
  135. package/adapters/pi/skills/forge-1-prd/SKILL.md +4 -1
  136. package/adapters/pi/skills/forge-1-prd/references/shared-conventions.md +1 -1
  137. package/adapters/pi/skills/forge-2-tech/SKILL.md +4 -1
  138. package/adapters/pi/skills/forge-2-tech/references/shared-conventions.md +1 -1
  139. package/adapters/pi/skills/forge-3-specs/SKILL.md +4 -1
  140. package/adapters/pi/skills/forge-3-specs/references/shared-conventions.md +1 -1
  141. package/adapters/pi/skills/forge-4-backlog/SKILL.md +4 -1
  142. package/adapters/pi/skills/forge-4-backlog/references/shared-conventions.md +1 -1
  143. package/adapters/pi/skills/forge-5-loop/SKILL.md +14 -8
  144. package/adapters/pi/skills/forge-5-loop/references/ralph-loop-contract.md +12 -8
  145. package/adapters/pi/skills/forge-5-loop/references/runner-contract.md +8 -5
  146. package/adapters/pi/skills/forge-5-loop/references/shared-conventions.md +1 -1
  147. package/adapters/pi/skills/forge-6-docs/SKILL.md +4 -1
  148. package/adapters/pi/skills/forge-6-docs/references/shared-conventions.md +1 -1
  149. package/adapters/pi/skills/forge-bootstrap/SKILL.md +4 -1
  150. package/adapters/pi/skills/forge-fix/SKILL.md +4 -1
  151. package/adapters/pi/skills/forge-fix/references/shared-conventions.md +1 -1
  152. package/adapters/pi/skills/forge-guide/SKILL.md +4 -1
  153. package/adapters/pi/skills/forge-guide/references/forge-config-schema.json +4 -4
  154. package/adapters/pi/skills/forge-guide/references/ralph-loop-contract.md +12 -8
  155. package/adapters/pi/skills/forge-guide/references/shared-conventions.md +1 -1
  156. package/adapters/pi/skills/forge-init/SKILL.md +4 -1
  157. package/adapters/pi/skills/forge-verify/SKILL.md +9 -4
  158. package/adapters/pi/skills/forge-verify/references/findings-template.md +6 -6
  159. package/adapters/pi/skills/forge-verify/references/shared-conventions.md +1 -1
  160. package/dist/manifest.d.ts +1 -1
  161. package/dist/rauf.d.ts +3 -3
  162. package/dist/rauf.js +2 -2
  163. package/dist/types.d.ts +1 -1
  164. package/package.json +8 -2
@@ -235,8 +235,8 @@
235
235
  },
236
236
  "installHint": {
237
237
  "type": "string",
238
- "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.14.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.14.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
239
- "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.14.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
238
+ "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.15.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.15.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
239
+ "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.15.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
240
240
  },
241
241
  "schemaVersion": {
242
242
  "type": "string",
@@ -245,8 +245,8 @@
245
245
  },
246
246
  "minRunnerVersion": {
247
247
  "type": "string",
248
- "default": "0.6.0",
249
- "description": "Minimum runner version (semver). 0.6.0 is the AGENT-SURFACE FLOOR: the rauf version that ships the coding-agent selection surface (the --agent flag, the `agents` availability probe, and the preset agent registry) that this config's agentArgument/agentsProbeCommand consume. Flooring here guarantees a successful gate implies those surfaces exist. (0.5.0 was the prior grammar/contract-flip floor — unified exit codes, `loop run --detached`, explicit `review` signal, versioned events.ndjson — which predates the agent surface and so could not guarantee it.) forge-5 enforces this via versionCommand before any loop side-effects."
248
+ "default": "0.14.0",
249
+ "description": "Minimum runner version (semver). 0.14.0 is the CAPABILITY FLOOR the shipped stage actually depends on — it is the version needed for full post-run needs-human recovery: rauf 0.14's `backlog answer` injects a recorded answer into the next iteration (RECOVERY_MIN_RUNNER_VERSION in forge-session.py). Below it, recovery silently degrades to `backlog unblock` (answer not injected) and large Codex prompts retain the pre-0.14 argv-size (E2BIG) failure mode. Earlier surfaces are subsumed: 0.6.0 first shipped the coding-agent selection surface (--agent flag, `agents` availability probe, preset registry consumed by agentArgument/agentsProbeCommand); 0.5.0 added unified exit codes, `loop run --detached`, the explicit `review` signal, and versioned events.ndjson. Flooring at 0.14.0 guarantees a successful gate implies the recovery + agent surfaces both exist. The floor is distinct from the installer's `RAUF_PIN` (installHint) — the pin may sit ahead of the floor when a newer rauf ships nothing this floor's dependents need; it only rises when rauf ships a surface a shipped stage actually depends on. forge-5 enforces the floor via versionCommand before any loop side-effects."
250
250
  }
251
251
  }
252
252
  }
@@ -156,11 +156,13 @@ to today. Degradation is **silent, not an error**, keeping alternate (non-rauf)
156
156
  runners first-class. The gate condition is owned by
157
157
  `02-config-schema-and-gating.md`.
158
158
 
159
- Independently, the **version gate** floors at the runner version that ships the
160
- agent surface. For rauf that is **0.6.0** (`loopRunner.minRunnerVersion`): the
161
- `--agent` flag, the `agents` probe, and the preset agent registry are present in
162
- rauf source at 0.6.0. A successful gate therefore guarantees those surfaces
163
- exist before any run. See `## Version gating` and
159
+ Independently, the **version gate** floors at the runner version the stage
160
+ depends on. For rauf that is **0.14.0** (`loopRunner.minRunnerVersion`): the
161
+ version the package pins and the floor for full needs-human recovery (0.14's
162
+ `backlog answer`). The agent surface — the `--agent` flag, the `agents` probe,
163
+ and the preset agent registry — has been present since rauf 0.6.0 and is
164
+ subsumed by the higher floor, so a successful gate guarantees both the recovery
165
+ and agent surfaces exist before any run. See `## Version gating` and
164
166
  `05-runner-discovery-version-gate.md`.
165
167
 
166
168
  **This document — the `## Agent selection` section, the `## Per-stage agent
@@ -210,9 +212,11 @@ belongs to execution only. If you find yourself adding `--agent` near a
210
212
 
211
213
  feature-forge requires a runner exposing `backlog validate` + backlog
212
214
  `schemaVersion`, and the unified exit-code/status contract it reads. The floor is
213
- now the **agent-surface floor**: the runner version that ships the `--agent`
214
- flag, the `agents` probe, and the preset agent registry. For rauf that is
215
- **0.6.0** (`loopRunner.minRunnerVersion`).
215
+ now the **capability floor** the stage actually depends on: the version the
216
+ package pins and the floor for full needs-human recovery (0.14's `backlog
217
+ answer`). It subsumes the older agent-surface floor (the `--agent` flag, the
218
+ `agents` probe, and the preset agent registry, present since 0.6.0). For rauf
219
+ that is **0.14.0** (`loopRunner.minRunnerVersion`).
216
220
  `forge-5-loop` runs `{bin} version --json`, semver-compares the reported version
217
221
  against `minRunnerVersion`, and on a missing-or-too-old runner stops with
218
222
  `loopRunner.installHint` (the CLI install/upgrade command) — **before** invoking
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -461,8 +461,12 @@ TOPOLOGY_DEPTH_WARN_RATIO: Final[float] = 0.5
461
461
  #: The forge-side capability threshold for the runner's `backlog answer` apply
462
462
  #: surface: at or above this rauf version the recovery procedure applies answers
463
463
  #: via `rauf backlog answer`; below it, it degrades to `rauf backlog unblock`.
464
- #: It never hard-fails recovery, and it is NOT ``loopRunner.minRunnerVersion``
465
- #: (the install floor in references/forge-config-schema.json, which stays 0.6.0).
464
+ #: It never hard-fails recovery. As of the 0.14.0 floor bump it now COINCIDES with
465
+ #: ``loopRunner.minRunnerVersion`` (the install floor in
466
+ #: references/forge-config-schema.json, also 0.14.0) — the launch gate was raised so
467
+ #: it no longer green-lights a runner too old to inject a recovered answer — but the
468
+ #: two remain conceptually distinct: this one selects the recovery apply surface and
469
+ #: only degrades, while the install floor hard-stops the launch.
466
470
  RECOVERY_MIN_RUNNER_VERSION: Final[str] = "0.14.0"
467
471
  #: The fixed final line of the NEXT-STEPS block. The stamp instructs the skill
468
472
  #: to print the block verbatim as its absolute last output — nothing after this.
@@ -5694,8 +5698,9 @@ def _verify_result_entry(
5694
5698
  the one status that carries prior state forward — the report metadata — and it
5695
5699
  deliberately writes no ``verifiedStageVersion``: fixes landed, nothing
5696
5700
  re-verified them, so freshness stays unresolved until a later ``passed``.
5697
- ``passed`` may record NEW attached-report metadata of its own (the
5698
- advisory-only and escalation-acceptance rules in ``cmd_state_verify``).
5701
+ ``passed`` may record NEW attached-report metadata of its own (a clean report,
5702
+ an advisory-only report, or the escalation-acceptance rules in
5703
+ ``cmd_state_verify``).
5699
5704
 
5700
5705
  Args:
5701
5706
  status: The validated result status.
@@ -5719,11 +5724,11 @@ def _verify_result_entry(
5719
5724
  if status == "passed":
5720
5725
  entry: dict = {"status": status}
5721
5726
  if findings_file is not None:
5722
- # An attached report — advisory-only, or residual findings the user
5723
- # explicitly accepted at the escalation gate — resolves as `passed`
5724
- # so it never routes to forge-fix, while the report stays attached
5725
- # for later pickup. A bare zero count records no report keys, keeping
5726
- # the plain "verified clean" shape byte-identical to before.
5727
+ # An attached clean/advisory report, or residual findings the user
5728
+ # explicitly accepted at the escalation gate, resolves as `passed`
5729
+ # so it never routes to forge-fix while the audit artifact stays
5730
+ # attached. A bare zero count records no report keys, preserving the
5731
+ # legacy plain "verified clean" shape.
5727
5732
  entry["findingsFile"] = findings_file
5728
5733
  entry["findingsCount"] = findings_count
5729
5734
  entry["verifiedAt"] = now
@@ -5779,15 +5784,19 @@ def cmd_state_verify(
5779
5784
  write, so a contradictory call never lands a partial entry:
5780
5785
 
5781
5786
  - `passed` — REQUIRES `verified_stage_version`. MAY carry an attached
5782
- report (`findings_file` + `findings_count` together, count >= 1) in
5783
- two protocol cases: an ADVISORY-ONLY report (no blocking
5784
- `error`/`gap` findings), and residual findings the user explicitly
5785
- ACCEPTED at the round-ledger escalation (recorded first as a
5786
- `state-decision`; see "Escalation" in stage-exit-protocol.md).
5787
- Either way the stage resolves without routing to forge-fix and the
5788
- report stays attached. Half a pairing is refused: a file without a
5789
- count, a positive count without a file, or a file with a zero
5790
- count. Unaccepted blocking findings belong to `findings-reported`.
5787
+ report (`findings_file` + `findings_count` together, count >= 0) in
5788
+ three protocol cases: a CLEAN zero-finding round report (a fix
5789
+ pass's re-verify — valid audit evidence that lets the stage advance
5790
+ instead of stranding at `findings-applied`, #237), an ADVISORY-ONLY
5791
+ report (no blocking `error`/`gap` findings, count >= 1), and
5792
+ residual findings the user explicitly ACCEPTED at the round-ledger
5793
+ escalation (recorded first as a `state-decision`; see "Escalation"
5794
+ in stage-exit-protocol.md). In every case the stage resolves
5795
+ without routing to forge-fix and the report stays attached. Half a
5796
+ pairing is refused: a file without a count, or a positive count
5797
+ without a file. A bare `passed` (neither flag) is also accepted and
5798
+ records the report-free clean shape. Unaccepted blocking findings
5799
+ belong to `findings-reported`.
5791
5800
  - `findings-reported` — REQUIRES all three of `verified_stage_version`,
5792
5801
  `findings_file`, and a non-negative `findings_count`.
5793
5802
  - `findings-applied` — REFUSES `verified_stage_version`. Applying fixes
@@ -5914,8 +5923,9 @@ def cmd_state_verify(
5914
5923
  elif status == "passed":
5915
5924
  if findings_file is not None and findings_count is None:
5916
5925
  raise UsageError(
5917
- "--status passed with an advisory --findings-file requires "
5918
- "--findings-count N (the number of advisory findings it lists)"
5926
+ "--status passed with --findings-file requires --findings-count N "
5927
+ "(zero for a clean report, or the number of advisory/residual "
5928
+ "findings it lists)"
5919
5929
  )
5920
5930
  if findings_count is not None:
5921
5931
  if findings_count < 0:
@@ -5929,12 +5939,6 @@ def cmd_state_verify(
5929
5939
  f"report to read is unrecoverable. Blocking findings belong to "
5930
5940
  f"--status findings-reported instead."
5931
5941
  )
5932
- if findings_count == 0 and findings_file is not None:
5933
- raise UsageError(
5934
- "--status passed with --findings-file requires --findings-count "
5935
- ">= 1: an attached report claiming zero findings is "
5936
- "self-contradictory — omit both for a clean pass"
5937
- )
5938
5942
  if verified_stage_version is None:
5939
5943
  raise UsageError(
5940
5944
  "--status passed requires --verified-stage-version <current version>"
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -83,8 +83,8 @@ This gate runs **before** the runner version/setup gates (1c/1d) so a blocked fe
83
83
  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.
84
84
 
85
85
  1. Run the **version command** (`loopRunner.versionCommand`, default `rauf version --json`) via Bash.
86
- 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.
87
- 3. **Semver-compare** (NOT string-compare) the reported version against `loopRunner.minRunnerVersion` (default `0.6.0`), numerically by major, then minor, then patch.
86
+ 2. Parse `{ "version": "<semver>" }` from stdout. Do NOT use plain `rauf version` (its human output is `rauf v0.14.0` with a `v` prefix) — always the `--json` form.
87
+ 3. **Semver-compare** (NOT string-compare) the reported version against `loopRunner.minRunnerVersion` (default `0.14.0`), numerically by major, then minor, then patch.
88
88
 
89
89
  **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:
90
90
 
@@ -92,7 +92,7 @@ Enforce `loopRunner.minRunnerVersion` **before** doing anything else with the ru
92
92
  - Its stdout is not valid JSON, has no `version` field, or `version` is not a valid semver string.
93
93
  - The reported version is **< `minRunnerVersion`**.
94
94
 
95
- 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
+ For the version-too-old case, phrase it concretely, e.g.: "Your rauf is {reported}, but feature-forge needs ≥ {minRunnerVersion} — 0.14.0 is the version the package pins and the floor for full needs-human recovery. {installHint}". When the gate fails because the output couldn't be parsed, say so and show what the command printed before the `installHint`.
96
96
 
97
97
  > `installHint` points at the runner **CLI** install/upgrade — distinct from
98
98
  > `setupHint` (1d), which installs the runner's per-project artifacts.
@@ -156,11 +156,13 @@ to today. Degradation is **silent, not an error**, keeping alternate (non-rauf)
156
156
  runners first-class. The gate condition is owned by
157
157
  `02-config-schema-and-gating.md`.
158
158
 
159
- Independently, the **version gate** floors at the runner version that ships the
160
- agent surface. For rauf that is **0.6.0** (`loopRunner.minRunnerVersion`): the
161
- `--agent` flag, the `agents` probe, and the preset agent registry are present in
162
- rauf source at 0.6.0. A successful gate therefore guarantees those surfaces
163
- exist before any run. See `## Version gating` and
159
+ Independently, the **version gate** floors at the runner version the stage
160
+ depends on. For rauf that is **0.14.0** (`loopRunner.minRunnerVersion`): the
161
+ version the package pins and the floor for full needs-human recovery (0.14's
162
+ `backlog answer`). The agent surface — the `--agent` flag, the `agents` probe,
163
+ and the preset agent registry — has been present since rauf 0.6.0 and is
164
+ subsumed by the higher floor, so a successful gate guarantees both the recovery
165
+ and agent surfaces exist before any run. See `## Version gating` and
164
166
  `05-runner-discovery-version-gate.md`.
165
167
 
166
168
  **This document — the `## Agent selection` section, the `## Per-stage agent
@@ -210,9 +212,11 @@ belongs to execution only. If you find yourself adding `--agent` near a
210
212
 
211
213
  feature-forge requires a runner exposing `backlog validate` + backlog
212
214
  `schemaVersion`, and the unified exit-code/status contract it reads. The floor is
213
- now the **agent-surface floor**: the runner version that ships the `--agent`
214
- flag, the `agents` probe, and the preset agent registry. For rauf that is
215
- **0.6.0** (`loopRunner.minRunnerVersion`).
215
+ now the **capability floor** the stage actually depends on: the version the
216
+ package pins and the floor for full needs-human recovery (0.14's `backlog
217
+ answer`). It subsumes the older agent-surface floor (the `--agent` flag, the
218
+ `agents` probe, and the preset agent registry, present since 0.6.0). For rauf
219
+ that is **0.14.0** (`loopRunner.minRunnerVersion`).
216
220
  `forge-5-loop` runs `{bin} version --json`, semver-compares the reported version
217
221
  against `minRunnerVersion`, and on a missing-or-too-old runner stops with
218
222
  `loopRunner.installHint` (the CLI install/upgrade command) — **before** invoking
@@ -70,8 +70,8 @@ Notes:
70
70
  separate open-ended option for that.
71
71
  - **Option 3 is conditional.** Include it only when the Step 2a tally has `blocked
72
72
  > 0`; otherwise present options 1 and 2 only.
73
- - **Version floor.** rauf's explicit `review` signal ships in 0.5.0, below the
74
- `minRunnerVersion` floor (0.6.0) enforced at gate 1c — so `--review` is always
73
+ - **Version floor.** rauf's explicit `review` signal ships in 0.5.0, well below the
74
+ `minRunnerVersion` floor (0.14.0) enforced at gate 1c — so `--review` is always
75
75
  available once the loop is cleared to launch. No extra version check is needed.
76
76
  - **Non-rauf runners.** When `loopRunner.name != "rauf"`, add **no** Run-mode
77
77
  question — present the bare rendered command and let the user adjust via "Other",
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -235,8 +235,8 @@
235
235
  },
236
236
  "installHint": {
237
237
  "type": "string",
238
- "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.14.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.14.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
239
- "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.14.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
238
+ "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.15.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.15.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
239
+ "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.15.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
240
240
  },
241
241
  "schemaVersion": {
242
242
  "type": "string",
@@ -245,8 +245,8 @@
245
245
  },
246
246
  "minRunnerVersion": {
247
247
  "type": "string",
248
- "default": "0.6.0",
249
- "description": "Minimum runner version (semver). 0.6.0 is the AGENT-SURFACE FLOOR: the rauf version that ships the coding-agent selection surface (the --agent flag, the `agents` availability probe, and the preset agent registry) that this config's agentArgument/agentsProbeCommand consume. Flooring here guarantees a successful gate implies those surfaces exist. (0.5.0 was the prior grammar/contract-flip floor — unified exit codes, `loop run --detached`, explicit `review` signal, versioned events.ndjson — which predates the agent surface and so could not guarantee it.) forge-5 enforces this via versionCommand before any loop side-effects."
248
+ "default": "0.14.0",
249
+ "description": "Minimum runner version (semver). 0.14.0 is the CAPABILITY FLOOR the shipped stage actually depends on — it is the version needed for full post-run needs-human recovery: rauf 0.14's `backlog answer` injects a recorded answer into the next iteration (RECOVERY_MIN_RUNNER_VERSION in forge-session.py). Below it, recovery silently degrades to `backlog unblock` (answer not injected) and large Codex prompts retain the pre-0.14 argv-size (E2BIG) failure mode. Earlier surfaces are subsumed: 0.6.0 first shipped the coding-agent selection surface (--agent flag, `agents` availability probe, preset registry consumed by agentArgument/agentsProbeCommand); 0.5.0 added unified exit codes, `loop run --detached`, the explicit `review` signal, and versioned events.ndjson. Flooring at 0.14.0 guarantees a successful gate implies the recovery + agent surfaces both exist. The floor is distinct from the installer's `RAUF_PIN` (installHint) — the pin may sit ahead of the floor when a newer rauf ships nothing this floor's dependents need; it only rises when rauf ships a surface a shipped stage actually depends on. forge-5 enforces the floor via versionCommand before any loop side-effects."
250
250
  }
251
251
  }
252
252
  }
@@ -156,11 +156,13 @@ to today. Degradation is **silent, not an error**, keeping alternate (non-rauf)
156
156
  runners first-class. The gate condition is owned by
157
157
  `02-config-schema-and-gating.md`.
158
158
 
159
- Independently, the **version gate** floors at the runner version that ships the
160
- agent surface. For rauf that is **0.6.0** (`loopRunner.minRunnerVersion`): the
161
- `--agent` flag, the `agents` probe, and the preset agent registry are present in
162
- rauf source at 0.6.0. A successful gate therefore guarantees those surfaces
163
- exist before any run. See `## Version gating` and
159
+ Independently, the **version gate** floors at the runner version the stage
160
+ depends on. For rauf that is **0.14.0** (`loopRunner.minRunnerVersion`): the
161
+ version the package pins and the floor for full needs-human recovery (0.14's
162
+ `backlog answer`). The agent surface — the `--agent` flag, the `agents` probe,
163
+ and the preset agent registry — has been present since rauf 0.6.0 and is
164
+ subsumed by the higher floor, so a successful gate guarantees both the recovery
165
+ and agent surfaces exist before any run. See `## Version gating` and
164
166
  `05-runner-discovery-version-gate.md`.
165
167
 
166
168
  **This document — the `## Agent selection` section, the `## Per-stage agent
@@ -210,9 +212,11 @@ belongs to execution only. If you find yourself adding `--agent` near a
210
212
 
211
213
  feature-forge requires a runner exposing `backlog validate` + backlog
212
214
  `schemaVersion`, and the unified exit-code/status contract it reads. The floor is
213
- now the **agent-surface floor**: the runner version that ships the `--agent`
214
- flag, the `agents` probe, and the preset agent registry. For rauf that is
215
- **0.6.0** (`loopRunner.minRunnerVersion`).
215
+ now the **capability floor** the stage actually depends on: the version the
216
+ package pins and the floor for full needs-human recovery (0.14's `backlog
217
+ answer`). It subsumes the older agent-surface floor (the `--agent` flag, the
218
+ `agents` probe, and the preset agent registry, present since 0.6.0). For rauf
219
+ that is **0.14.0** (`loopRunner.minRunnerVersion`).
216
220
  `forge-5-loop` runs `{bin} version --json`, semver-compares the reported version
217
221
  against `minRunnerVersion`, and on a missing-or-too-old runner stops with
218
222
  `loopRunner.installHint` (the CLI install/upgrade command) — **before** invoking
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -227,14 +227,16 @@ Do NOT embed this question in your text output.
227
227
 
228
228
  ## Step 6: Record the Result Through `state-verify`
229
229
 
230
- Never hand-author a verify entry. Every `stages.forge-verify-*` transition is written by the `state-verify` verb described in the **Pipeline State Protocol** in `references/shared-conventions.md`, which owns its full flag surface, its status matrix, and the exit-2 failure protocol. Write `findings-reported` when the report lists at least one **blocking** finding (`error`/`gap`); write `passed` when it lists none — including an **advisory-only** report (`inconsistency`/`improvement` findings only), which records `passed` with the report still attached: pass `--findings-file` and `--findings-count` alongside `--status passed` so the advisories remain discoverable without blocking the stage. (One exception routes blocking findings to `passed`: residual findings the user explicitly accepted at the round-ledger escalation — recorded first as a `state-decision`, then `passed` with the report attached, per "Escalation" in `references/stage-exit-protocol.md`.) Never write `findings-applied` here — that belongs to the fix pass. `--stage` names the **served production stage** (Step 1's mode, mapped through the served-stage mapping in Step 7), `--findings-file` is the report path **relative to** the feature directory (the Step 4 filename, round discriminator included), and `--verified-stage-version` is that production stage entry's current `version`, so a later revision of the artifact makes this verification read stale and re-fires. Add `--epic "{epic}"` when the feature is an epic member — required, per the Pipeline State Protocol; omitting it for a member is an error and must never fall back to a same-named flat feature.
230
+ Never hand-author a verify entry. Every `stages.forge-verify-*` transition is written by the `state-verify` verb described in the **Pipeline State Protocol** in `references/shared-conventions.md`, which owns its full flag surface, its status matrix, and the exit-2 failure protocol. Write `findings-reported` when the report lists at least one **blocking** finding (`error`/`gap`); otherwise write `passed`. **Always attach the Step 4 report**, including a clean report with count `0`, so the completed round remains resumable and auditable. Advisory-only reports (`inconsistency`/`improvement`) use `passed` with their positive count and advance without a fix round. (One exception routes blocking findings to `passed`: residual findings the user explicitly accepted at the round-ledger escalation — recorded first as a `state-decision`, then `passed` with the report attached, per "Escalation" in `references/stage-exit-protocol.md`.) Never write `findings-applied` here — that belongs to the fix pass. `--stage` names the **served production stage** (Step 1's mode, mapped through the served-stage mapping in Step 7), `--findings-file` is the report path **relative to** the feature directory (the Step 4 filename, round discriminator included), and `--verified-stage-version` is that production stage entry's current `version`, so a later revision of the artifact makes this verification read stale and re-fires. Add `--epic "{epic}"` when the feature is an epic member — required, per the Pipeline State Protocol; omitting it for a member is an error and must never fall back to a same-named flat feature.
231
+
232
+ Choose result arguments from the report outcome, never a combined placeholder: clean uses `--status passed --findings-count 0`; advisory-only uses `--status passed` with its positive count; blocking uses `--status findings-reported` with its positive total count. All variants attach the Step 4 report:
231
233
 
232
234
  ```bash
233
235
  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')"
234
236
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
235
237
  python3 "$R/scripts/forge-session.py" state-verify \
236
- --feature "{feature}" --stage "{servedStage}" --status "{passed|findings-reported}" \
237
- --findings-file "{relative findings path}" --findings-count {n} \
238
+ --feature "{feature}" --stage "{servedStage}" --status "{outcome-specific status}" \
239
+ --findings-file "{relative findings path}" --findings-count {outcome-specific count} \
238
240
  --verified-stage-version {version} --specs-dir "{specsDir}"
239
241
  ```
240
242
 
@@ -131,10 +131,10 @@ violate REQ-STATE-02; per-feature status is always derived live from each member
131
131
  `.pipeline-state.json`).
132
132
 
133
133
  Set `stages.forge-verify-epic.status` to `findings-reported` when the report lists at
134
- least one **blocking** finding (`error`/`gap`), else `passed` — for an advisory-only
135
- report pass `--findings-file`/`--findings-count` alongside `--status passed`, exactly
136
- as in feature mode (the severity floor in `skills/forge-verify/SKILL.md`) — recording
137
- `findingsFile`, `findingsCount`, and `verifiedAt`.
134
+ least one **blocking** finding (`error`/`gap`), else `passed`. Always attach the report
135
+ and its total count, including count `0` for a clean report, exactly as in feature mode
136
+ (the severity floor in `skills/forge-verify/SKILL.md`) — recording `findingsFile`,
137
+ `findingsCount`, and `verifiedAt`.
138
138
 
139
139
  **Write it with `state-verify`, never by hand.** `--stage forge-0-epic` is the sanctioned
140
140
  epic writer: it creates the file lazily, mutates only `stages.forge-verify-epic` plus the
@@ -149,8 +149,8 @@ R="$(bash -c 'for d in "${FEATURE_FORGE_ROOT:-}" "$HOME"/.claude/skills/feature-
149
149
  [ -n "$R" ] || { echo "feature-forge: cannot locate plugin root" >&2; exit 1; }
150
150
  python3 "$R/scripts/forge-session.py" state-verify \
151
151
  --feature "{epic}" --stage forge-0-epic \
152
- --status "{passed|findings-reported}" \
153
- --findings-file "{relative findings path}" --findings-count {n} \
152
+ --status "{outcome-specific status}" \
153
+ --findings-file "{relative findings path}" --findings-count {outcome-specific count} \
154
154
  --verified-stage-version {manifest revision} --specs-dir "{specsDir}"
155
155
  ```
156
156
 
@@ -206,7 +206,7 @@ If a `state-*` verb exits 2, surface the plain `Error:` line from stderr verbati
206
206
 
207
207
  ### `state-verify` — verification results and provenance
208
208
 
209
- `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may additionally carry `--findings-file` + `--findings-count` together for an **advisory-only** report (`inconsistency`/`improvement` findings only, per forge-verify's severity floor) — the stage resolves without a fix round and the report stays attached:
209
+ `state-verify` writes exactly one `stages.forge-verify-{token}` entry — the verification result for the production stage named by `--stage` — plus the top-level `updatedAt`, and nothing else. `--stage` takes the **served production stage** (`forge-0-epic` through `forge-5-loop`; `forge-6-docs` has no verification token and is rejected). Add `--epic "{epic}"` when the feature is an epic member — required, per the member rule above. Result mode passes `--status` (`auto-verify-pending`, `passed`, `findings-reported`, `findings-applied`, or `skipped`) with whatever `--findings-file`, `--findings-count`, and `--verified-stage-version` that status requires; contradictory metadata is refused before any write. `passed` may carry `--findings-file` + `--findings-count` for a clean report (count `0`), an **advisory-only** report (`inconsistency`/`improvement` findings only), or accepted residual findings. The stage resolves without a fix round and the report stays attached, making a completed verification round directly resumable if provenance recording is interrupted. A bare `passed` remains accepted for backward compatibility:
210
210
 
211
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*.
212
212
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feature-forge",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "agent": "copilot",
5
5
  "generatedBy": "python3 scripts/build-adapters.py"
6
6
  }
@@ -235,8 +235,8 @@
235
235
  },
236
236
  "installHint": {
237
237
  "type": "string",
238
- "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.14.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.14.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
239
- "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.14.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
238
+ "default": "Provision rauf for a multi-agent setup with the cross-agent installer: `npx @garygentry/feature-forge install` (records the pinned @garygentry/rauf@0.15.0 default). Or install/upgrade just the rauf CLI: `npx @garygentry/rauf@0.15.0 --version`, or `curl -fsSL https://raw.githubusercontent.com/garygentry/rauf/main/scripts/install-binary.sh | bash`.",
239
+ "description": "Shown when the runner BINARY is missing or too old (version gate fails, minRunnerVersion floor) — how to obtain/upgrade the CLI itself. Names two distinct binary-provisioning paths: (1) the cross-agent installer (`npx @garygentry/feature-forge install`, the multi-agent provisioning path that pins @garygentry/rauf@0.15.0), and (2) the direct rauf-CLI install/upgrade one-liner. Distinct from setupHint (which installs per-project artifacts); a version-gate failure is ALWAYS this hint, never setupHint."
240
240
  },
241
241
  "schemaVersion": {
242
242
  "type": "string",
@@ -245,8 +245,8 @@
245
245
  },
246
246
  "minRunnerVersion": {
247
247
  "type": "string",
248
- "default": "0.6.0",
249
- "description": "Minimum runner version (semver). 0.6.0 is the AGENT-SURFACE FLOOR: the rauf version that ships the coding-agent selection surface (the --agent flag, the `agents` availability probe, and the preset agent registry) that this config's agentArgument/agentsProbeCommand consume. Flooring here guarantees a successful gate implies those surfaces exist. (0.5.0 was the prior grammar/contract-flip floor — unified exit codes, `loop run --detached`, explicit `review` signal, versioned events.ndjson — which predates the agent surface and so could not guarantee it.) forge-5 enforces this via versionCommand before any loop side-effects."
248
+ "default": "0.14.0",
249
+ "description": "Minimum runner version (semver). 0.14.0 is the CAPABILITY FLOOR the shipped stage actually depends on — it is the version needed for full post-run needs-human recovery: rauf 0.14's `backlog answer` injects a recorded answer into the next iteration (RECOVERY_MIN_RUNNER_VERSION in forge-session.py). Below it, recovery silently degrades to `backlog unblock` (answer not injected) and large Codex prompts retain the pre-0.14 argv-size (E2BIG) failure mode. Earlier surfaces are subsumed: 0.6.0 first shipped the coding-agent selection surface (--agent flag, `agents` availability probe, preset registry consumed by agentArgument/agentsProbeCommand); 0.5.0 added unified exit codes, `loop run --detached`, the explicit `review` signal, and versioned events.ndjson. Flooring at 0.14.0 guarantees a successful gate implies the recovery + agent surfaces both exist. The floor is distinct from the installer's `RAUF_PIN` (installHint) — the pin may sit ahead of the floor when a newer rauf ships nothing this floor's dependents need; it only rises when rauf ships a surface a shipped stage actually depends on. forge-5 enforces the floor via versionCommand before any loop side-effects."
250
250
  }
251
251
  }
252
252
  }