@khoavu882/doflow 2.0.0-beta.5 → 2.0.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.
Files changed (471) hide show
  1. package/README.md +12 -11
  2. package/bin/doflow.js +21 -11
  3. package/core/.antigravity-plugin/plugin.json +1 -2
  4. package/core/.claude-plugin/plugin.json +1 -1
  5. package/core/.codex-plugin/plugin.json +1 -1
  6. package/core/.plugin/plugin.json +1 -1
  7. package/core/harnesses/claude/hooks/lib.sh +43 -24
  8. package/core/harnesses/claude/hooks/permission-audit.sh +3 -0
  9. package/core/harnesses/claude/hooks/post-compact.sh +35 -32
  10. package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
  11. package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
  12. package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
  13. package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
  14. package/core/harnesses/claude/hooks/session-end.sh +23 -10
  15. package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
  16. package/core/harnesses/claude/settings/settings.json +18 -0
  17. package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
  18. package/core/harnesses/codex/agents/core-implementer.toml +1 -0
  19. package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
  20. package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
  21. package/core/harnesses/codex/agents/research-writer.toml +1 -1
  22. package/core/harnesses/codex/agents/reviewer.toml +10 -0
  23. package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
  24. package/core/harnesses/codex/agents/system-architect.toml +1 -1
  25. package/core/harnesses/codex/hooks/lib.sh +44 -25
  26. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
  27. package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
  28. package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
  29. package/core/harnesses/codex/hooks/subagent-audit.sh +1 -0
  30. package/core/harnesses/copilot/hooks/doflow-lib.sh +93 -0
  31. package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
  32. package/core/harnesses/copilot/hooks/doflow-pre-bash-guard.sh +9 -0
  33. package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
  34. package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
  35. package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
  36. package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
  37. package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
  38. package/core/harnesses/copilot/hooks/doflow.json +57 -0
  39. package/core/harnesses/kiro/agents/doflow.json +1 -1
  40. package/core/harnesses/kiro/hooks/lib.sh +26 -6
  41. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +1 -0
  42. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +1 -0
  43. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +1 -0
  44. package/core/harnesses/kiro/hooks/session-start.sh +1 -0
  45. package/core/harnesses/kiro/hooks/stop-check.sh +1 -0
  46. package/core/harnesses/pi/extensions/doflow-guard.js +8 -0
  47. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +0 -1
  48. package/core/harnesses/shared/hooks/bridge/bridge.sh +102 -9
  49. package/core/harnesses/shared/hooks/bridge/envelope.jq +87 -18
  50. package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
  51. package/core/harnesses/shared/hooks/bridge/respond.sh +10 -2
  52. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
  53. package/core/harnesses/shared/hooks/policies/capture-failure.sh +48 -15
  54. package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
  55. package/core/harnesses/shared/hooks/policies/contract.sh +3 -0
  56. package/core/harnesses/shared/hooks/policies/deny-json.sh +2 -11
  57. package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
  58. package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
  59. package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
  60. package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
  61. package/core/harnesses/shared/hooks/policies/lib.sh +63 -40
  62. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +3 -2
  63. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +213 -12
  64. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +114 -38
  65. package/core/harnesses/shared/hooks/policies/session-context.sh +30 -1
  66. package/core/harnesses/shared/hooks/policies/stop-check.sh +20 -9
  67. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +5 -2
  68. package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
  69. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +60 -155
  70. package/core/harnesses/shared/hooks/stream-hook-runner.js +47 -8
  71. package/core/harnesses/shared/locator/doflow-run +2 -3
  72. package/core/registry/advice.json +3 -3
  73. package/core/registry/assets.json +55 -82
  74. package/core/registry/capabilities.json +12 -0
  75. package/core/registry/contracts.json +58 -31
  76. package/core/registry/contribution-points.json +32 -0
  77. package/core/registry/gates.json +32 -0
  78. package/core/registry/guidance-caps.json +40 -0
  79. package/core/registry/harnesses.json +1442 -363
  80. package/core/registry/lifecycle.json +485 -304
  81. package/core/registry/mcp.json +5 -1
  82. package/core/registry/models.json +7 -1
  83. package/core/registry/package-templates/README.md +19 -0
  84. package/core/registry/package-templates/agent/files/agent.md +9 -0
  85. package/core/registry/package-templates/agent/template.json +4 -0
  86. package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
  87. package/core/registry/package-templates/capability-provider/template.json +11 -0
  88. package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
  89. package/core/registry/package-templates/debate-preset/template.json +4 -0
  90. package/core/registry/package-templates/review-preset/files/preset.json +30 -0
  91. package/core/registry/package-templates/review-preset/template.json +4 -0
  92. package/core/registry/package-templates/skill/files/SKILL.md +8 -0
  93. package/core/registry/package-templates/skill/template.json +4 -0
  94. package/core/registry/package-templates/worker/files/worker.json +92 -0
  95. package/core/registry/package-templates/worker/template.json +11 -0
  96. package/core/registry/packages/doflow/doflow-package.json +15 -0
  97. package/core/registry/packages/doflow/presets/debate-3.json +26 -0
  98. package/core/registry/protocols.json +61 -0
  99. package/core/registry/routes.json +17 -0
  100. package/core/registry/rules.json +431 -0
  101. package/core/registry/settings.json +276 -0
  102. package/core/registry/storage.json +679 -31
  103. package/core/registry/telemetry.json +236 -0
  104. package/core/registry/transcripts.json +142 -0
  105. package/core/registry/verification.json +76 -1
  106. package/core/registry/workflows.json +55 -0
  107. package/core/shared/agent-specs/core-implementer.md +3 -0
  108. package/core/shared/agent-specs/delivery-lead.md +68 -0
  109. package/core/shared/agent-specs/quality-guardian.md +5 -1
  110. package/core/shared/agent-specs/research-writer.md +10 -3
  111. package/core/shared/agent-specs/reviewer.md +53 -0
  112. package/core/shared/agent-specs/spec-analyst.md +5 -6
  113. package/core/shared/agent-specs/system-architect.md +5 -1
  114. package/core/shared/guidance/DOFLOW_CORE.md +1 -5
  115. package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
  116. package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
  117. package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
  118. package/core/shared/guidance/pointers/codex.md +1 -4
  119. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
  120. package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
  121. package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
  122. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
  123. package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
  124. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
  125. package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
  126. package/core/shared/guidance/references/ORCHESTRATION.md +1 -2
  127. package/core/shared/guidance/rules/RULES.md +45 -0
  128. package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
  129. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
  130. package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
  131. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
  132. package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
  133. package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
  134. package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
  135. package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
  136. package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
  137. package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
  138. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
  139. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +48 -4
  140. package/core/shared/scripts/doflow/bin/doflow-run +149 -34
  141. package/core/shared/skills/do/SKILL.md +12 -10
  142. package/core/shared/skills/do/references/advice_calls.md +26 -0
  143. package/core/shared/skills/do/references/pm_routing.md +1 -2
  144. package/core/shared/skills/do/references/program_mode.md +31 -0
  145. package/core/shared/skills/do-brainstorm/SKILL.md +20 -74
  146. package/core/shared/skills/do-brainstorm/references/handoff_branches.md +35 -0
  147. package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
  148. package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
  149. package/core/shared/skills/do-code-review/SKILL.md +41 -144
  150. package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
  151. package/core/shared/skills/do-code-review/references/tools.md +90 -0
  152. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
  153. package/core/shared/skills/do-design/SKILL.md +18 -17
  154. package/core/shared/skills/do-diagnose/SKILL.md +14 -4
  155. package/core/shared/skills/do-document/SKILL.md +11 -1
  156. package/core/shared/skills/do-document/references/deep_research.md +1 -2
  157. package/core/shared/skills/do-document/references/embedded-research.md +18 -6
  158. package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
  159. package/core/shared/skills/do-execute-plan/SKILL.md +15 -58
  160. package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
  161. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
  162. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +26 -1
  163. package/core/shared/skills/do-execute-plan/references/run_position.md +13 -1
  164. package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
  165. package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
  166. package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
  167. package/core/shared/skills/do-flow/SKILL.md +8 -9
  168. package/core/shared/skills/do-flow/references/task_classes.md +2 -2
  169. package/core/shared/skills/do-git/SKILL.md +4 -0
  170. package/core/shared/skills/do-implement/SKILL.md +4 -7
  171. package/core/shared/skills/do-plan/SKILL.md +26 -15
  172. package/core/shared/skills/do-test/SKILL.md +7 -4
  173. package/core/shared/templates/doflow/constitution-template.md +9 -3
  174. package/core/shared/templates/doflow/data-model-template.md +1 -1
  175. package/core/shared/templates/doflow/design-template.md +113 -16
  176. package/core/shared/templates/doflow/plan-template.md +11 -10
  177. package/core/shared/templates/doflow/question-log-template.md +14 -2
  178. package/core/shared/templates/doflow/requirement-template.md +1 -1
  179. package/core/worker-evidence/antigravity/checks.json +14 -0
  180. package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
  181. package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
  182. package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
  183. package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
  184. package/core/worker-evidence/codex/checks.json +38 -0
  185. package/package.json +10 -6
  186. package/src/adapters/antigravity/index.js +143 -66
  187. package/src/adapters/claude/index.js +24 -4
  188. package/src/adapters/codex/agents.js +25 -15
  189. package/src/adapters/codex/index.js +48 -13
  190. package/src/adapters/codex/native-projection.js +6 -2
  191. package/src/adapters/copilot/index.js +58 -23
  192. package/src/adapters/copy-tree.js +290 -44
  193. package/src/adapters/guidance-manifest.js +71 -0
  194. package/src/adapters/guidance-pointer.js +19 -0
  195. package/src/adapters/hook-commands.js +6 -10
  196. package/src/adapters/index.js +1 -0
  197. package/src/adapters/kiro/index.js +23 -12
  198. package/src/adapters/opencode/index.js +8 -8
  199. package/src/adapters/pi/hooks.js +2 -1
  200. package/src/adapters/pi/index.js +14 -7
  201. package/src/adapters/resolve-source.js +26 -2
  202. package/src/cli/commands/install.js +2 -1
  203. package/src/cli/commands/reconcile.js +53 -9
  204. package/src/cli/commands/remove.js +2 -2
  205. package/src/cli/commands/rollback.js +6 -3
  206. package/src/cli/commands/self-update.js +18 -9
  207. package/src/cli/commands/status.js +21 -2
  208. package/src/cli/commands/ui.js +99 -0
  209. package/src/cli/commands/update.js +2 -1
  210. package/src/cli/index.js +322 -29
  211. package/src/cli/runtime-commands.js +209 -57
  212. package/src/cli/shared.js +0 -2
  213. package/src/helper/git.js +1 -1
  214. package/src/helper/guardrails.js +1 -1
  215. package/src/helper/marker-merge.js +31 -13
  216. package/src/helper/package-ids.js +37 -0
  217. package/src/helper/semver.js +94 -0
  218. package/src/install/backup.js +105 -15
  219. package/src/install/context.js +1 -1
  220. package/src/install/targets.js +31 -16
  221. package/src/lifecycle/coverage.js +20 -3
  222. package/src/lifecycle/hook-tier.js +160 -0
  223. package/src/lifecycle/index.js +412 -78
  224. package/src/lifecycle/retired-harnesses.js +318 -0
  225. package/src/lifecycle/view.js +35 -15
  226. package/src/registry/index.js +551 -26
  227. package/src/registry/worker-ids.js +45 -0
  228. package/src/release/build-package.js +0 -3
  229. package/src/release/docs-blocks.js +492 -0
  230. package/src/release/preflight.js +425 -0
  231. package/src/release/rehearse.js +401 -0
  232. package/src/release/release-workflow.js +733 -0
  233. package/src/release/sync-plugin-versions.js +43 -7
  234. package/src/runtime/advice/bench-gate.js +25 -0
  235. package/src/runtime/advice/cli.js +59 -16
  236. package/src/runtime/advice/client.js +32 -9
  237. package/src/runtime/advice/config.js +98 -133
  238. package/src/runtime/advice/doctor.js +1 -1
  239. package/src/runtime/advice/elevation.js +97 -0
  240. package/src/runtime/advice/endpoint-guard.js +9 -3
  241. package/src/runtime/advice/mode.js +37 -0
  242. package/src/runtime/advice/record.js +18 -5
  243. package/src/runtime/advice/registry.js +4 -1
  244. package/src/runtime/advice/shadow-config.js +229 -0
  245. package/src/runtime/advice/shadow-dispatcher.js +276 -0
  246. package/src/runtime/brief-rules.js +81 -0
  247. package/src/runtime/brief-tools.js +111 -34
  248. package/src/runtime/candidate.js +20 -11
  249. package/src/runtime/capabilities/executor.js +450 -0
  250. package/src/runtime/capabilities/loopback.js +41 -0
  251. package/src/runtime/capabilities/sanitizer.js +88 -0
  252. package/src/runtime/capability-router.js +135 -3
  253. package/src/runtime/checkouts.js +73 -11
  254. package/src/runtime/claims.js +13 -7
  255. package/src/runtime/cli.js +196 -19
  256. package/src/runtime/config-home.js +42 -0
  257. package/src/runtime/context/arbitrate.js +767 -0
  258. package/src/runtime/context/delivery-store.js +4 -6
  259. package/src/runtime/context/emission-rules.js +118 -0
  260. package/src/runtime/context/identity.js +227 -0
  261. package/src/runtime/context/primary-command.js +117 -0
  262. package/src/runtime/context/primary.js +344 -0
  263. package/src/runtime/context/summary-store.js +655 -0
  264. package/src/runtime/context-pack.js +154 -78
  265. package/src/runtime/decision-register.js +13 -4
  266. package/src/runtime/dispatch/admission.js +392 -0
  267. package/src/runtime/dispatch/attempt-end.js +274 -0
  268. package/src/runtime/dispatch/command.js +628 -0
  269. package/src/runtime/dispatch/controls.js +904 -0
  270. package/src/runtime/dispatch/envelope.js +276 -0
  271. package/src/runtime/dispatch/grants.js +310 -0
  272. package/src/runtime/dispatch/integrate.js +617 -0
  273. package/src/runtime/dispatch/loop.js +1835 -0
  274. package/src/runtime/dispatch/store.js +352 -0
  275. package/src/runtime/dispatch/verify-run.js +201 -0
  276. package/src/runtime/evidence-ledger.js +34 -7
  277. package/src/runtime/failure/capture.js +3 -1
  278. package/src/runtime/failure/cli.js +25 -9
  279. package/src/runtime/failure/home.js +57 -30
  280. package/src/runtime/failure/store.js +7 -2
  281. package/src/runtime/feature-pointer.js +174 -0
  282. package/src/runtime/feature-resolve.js +13 -2
  283. package/src/runtime/fleet/command.js +77 -0
  284. package/src/runtime/fleet/projects.js +178 -0
  285. package/src/runtime/fleet/tree.js +383 -0
  286. package/src/runtime/freshness.js +33 -3
  287. package/src/runtime/git-memo.js +46 -0
  288. package/src/runtime/guidance/ablation.js +427 -0
  289. package/src/runtime/health.js +565 -17
  290. package/src/runtime/history-compactor.js +13 -3
  291. package/src/runtime/implementation-gate.js +277 -22
  292. package/src/runtime/inventory/coverage.js +1 -1
  293. package/src/runtime/inventory/index.js +1 -1
  294. package/src/runtime/inventory/precedence.js +2 -2
  295. package/src/runtime/inventory/siblings.js +6 -4
  296. package/src/runtime/knowledge/code-corpus.js +277 -0
  297. package/src/runtime/knowledge/code-lexical.js +130 -0
  298. package/src/runtime/knowledge/code-retrieval.js +307 -0
  299. package/src/runtime/knowledge/code-validation.js +106 -0
  300. package/src/runtime/knowledge/gp3-gate.js +74 -0
  301. package/src/runtime/knowledge/graph-adapter.js +288 -0
  302. package/src/runtime/knowledge/graph-fallback.js +394 -0
  303. package/src/runtime/knowledge/hybrid.js +136 -8
  304. package/src/runtime/knowledge/retrieval.js +34 -1
  305. package/src/runtime/knowledge/rtk-compress.js +77 -0
  306. package/src/runtime/knowledge/semble-bridge.py +106 -0
  307. package/src/runtime/knowledge/semble-lifecycle.js +114 -0
  308. package/src/runtime/knowledge/semble-provider.js +365 -0
  309. package/src/runtime/lifecycle/cli.js +16 -6
  310. package/src/runtime/lifecycle/event-store.js +8 -6
  311. package/src/runtime/lifecycle/followup.js +6 -1
  312. package/src/runtime/lifecycle/overview.js +24 -1
  313. package/src/runtime/lifecycle/report-store.js +8 -10
  314. package/src/runtime/lifecycle/retention.js +95 -31
  315. package/src/runtime/lifecycle/root.js +9 -1
  316. package/src/runtime/lifecycle/status.js +34 -17
  317. package/src/runtime/lifecycle/store-upkeep.js +56 -7
  318. package/src/runtime/mask.js +134 -7
  319. package/src/runtime/mcp-consultations.js +40 -6
  320. package/src/runtime/model-router.js +79 -7
  321. package/src/runtime/models/catalogue.js +191 -0
  322. package/src/runtime/models/command.js +153 -0
  323. package/src/runtime/off-words.js +12 -0
  324. package/src/runtime/outcome.js +2 -2
  325. package/src/runtime/packages/command.js +1009 -0
  326. package/src/runtime/packages/contributions.js +116 -0
  327. package/src/runtime/packages/digest.js +132 -0
  328. package/src/runtime/packages/fetch.js +182 -0
  329. package/src/runtime/packages/grants.js +192 -0
  330. package/src/runtime/packages/index-file.js +134 -0
  331. package/src/runtime/packages/instruction.js +90 -0
  332. package/src/runtime/packages/manifest.js +331 -0
  333. package/src/runtime/packages/points.js +477 -0
  334. package/src/runtime/packages/programs.js +216 -0
  335. package/src/runtime/packages/scaffold.js +277 -0
  336. package/src/runtime/packages/source.js +90 -0
  337. package/src/runtime/packages/state.js +164 -0
  338. package/src/runtime/packages/store.js +449 -0
  339. package/src/runtime/packages/tar.js +106 -0
  340. package/src/runtime/packages/view.js +406 -0
  341. package/src/runtime/plan-check.js +59 -0
  342. package/src/runtime/plan-content.js +324 -0
  343. package/src/runtime/policy-init.js +118 -0
  344. package/src/runtime/profiles/doctor.js +96 -0
  345. package/src/runtime/profiles/resolve.js +244 -0
  346. package/src/runtime/profiles/rollback.js +254 -0
  347. package/src/runtime/profiles/sampler.js +41 -0
  348. package/src/runtime/readiness-record.js +16 -11
  349. package/src/runtime/readiness.js +46 -5
  350. package/src/runtime/research-request.js +50 -25
  351. package/src/runtime/retrieval-plan.js +10 -30
  352. package/src/runtime/retrieval-record.js +75 -5
  353. package/src/runtime/review/command.js +246 -0
  354. package/src/runtime/review/dominance.js +68 -0
  355. package/src/runtime/review/findings.js +434 -0
  356. package/src/runtime/review/identity.js +255 -0
  357. package/src/runtime/review/protocol-command.js +109 -0
  358. package/src/runtime/review/protocols.js +405 -0
  359. package/src/runtime/review/resolve-protocol.js +302 -0
  360. package/src/runtime/review/start.js +530 -0
  361. package/src/runtime/roadmap/facts.js +479 -0
  362. package/src/runtime/roadmap/gates.js +270 -0
  363. package/src/runtime/roadmap/loop.js +1636 -0
  364. package/src/runtime/roadmap/merge.js +381 -0
  365. package/src/runtime/roadmap/rows.js +1113 -0
  366. package/src/runtime/roadmap/seed.js +951 -0
  367. package/src/runtime/rules-report.js +336 -0
  368. package/src/runtime/scaffold/artifacts.js +60 -9
  369. package/src/runtime/scaffold/generate.js +21 -9
  370. package/src/runtime/settings/autopilot.js +106 -0
  371. package/src/runtime/settings/cli.js +280 -0
  372. package/src/runtime/settings/config-write.js +314 -0
  373. package/src/runtime/settings/files.js +271 -0
  374. package/src/runtime/settings/legacy.js +154 -0
  375. package/src/runtime/settings/lexical.js +56 -0
  376. package/src/runtime/settings/prepared-run.js +269 -0
  377. package/src/runtime/settings/project-layers.js +118 -0
  378. package/src/runtime/settings/refs.js +288 -0
  379. package/src/runtime/settings/registry.js +553 -0
  380. package/src/runtime/settings/resolve.js +713 -0
  381. package/src/runtime/settings/shared.js +37 -0
  382. package/src/runtime/settings/worker-billing.js +107 -0
  383. package/src/runtime/settings/write.js +269 -0
  384. package/src/runtime/slot-command.js +78 -0
  385. package/src/runtime/slots.js +671 -0
  386. package/src/runtime/source-version.js +1 -0
  387. package/src/runtime/state-root.js +217 -0
  388. package/src/runtime/storage/cli.js +12 -5
  389. package/src/runtime/storage/engine.js +9 -2
  390. package/src/runtime/storage/registry.js +14 -1
  391. package/src/runtime/storage/roots.js +66 -16
  392. package/src/runtime/storage/rules.js +82 -10
  393. package/src/runtime/storage/upkeep.js +10 -2
  394. package/src/runtime/storage/work-status.js +245 -26
  395. package/src/runtime/task-attempts.js +589 -69
  396. package/src/runtime/task-classifier.js +47 -11
  397. package/src/runtime/task-graph.js +373 -0
  398. package/src/runtime/task-run.js +778 -0
  399. package/src/runtime/task-scope.js +176 -55
  400. package/src/runtime/task-sources.js +147 -0
  401. package/src/runtime/task-state.js +374 -64
  402. package/src/runtime/team/admission.js +301 -0
  403. package/src/runtime/team/envelope.js +324 -0
  404. package/src/runtime/team/review-guard.js +156 -0
  405. package/src/runtime/trace/analyze.js +427 -0
  406. package/src/runtime/trace/baseline.js +770 -0
  407. package/src/runtime/trace/ledger.js +63 -140
  408. package/src/runtime/trace/otlp-export.js +568 -0
  409. package/src/runtime/trace/otlp-map.js +481 -0
  410. package/src/runtime/trace/spans.js +745 -0
  411. package/src/runtime/trace/telemetry.js +225 -0
  412. package/src/runtime/trace/views.js +1 -0
  413. package/src/runtime/transcripts/command.js +98 -0
  414. package/src/runtime/transcripts/cursor.js +326 -0
  415. package/src/runtime/transcripts/read.js +126 -0
  416. package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
  417. package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
  418. package/src/runtime/transcripts/readers/copilot-events.js +90 -0
  419. package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
  420. package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
  421. package/src/runtime/transcripts/registry.js +161 -0
  422. package/src/runtime/transcripts/stats.js +161 -0
  423. package/src/runtime/verification/check-key.js +628 -0
  424. package/src/runtime/verification/contract-runner.js +546 -11
  425. package/src/runtime/verification/engine.js +499 -9
  426. package/src/runtime/verification/impact.js +617 -0
  427. package/src/runtime/verification/inflight.js +205 -0
  428. package/src/runtime/verification/registry.js +176 -0
  429. package/src/runtime/verification/reuse.js +184 -0
  430. package/src/runtime/verification/telemetry-emit.js +254 -0
  431. package/src/runtime/verification/test-selection.js +67 -7
  432. package/src/runtime/worker/active.js +90 -0
  433. package/src/runtime/worker/cancel.js +222 -0
  434. package/src/runtime/worker/catalogue.js +122 -0
  435. package/src/runtime/worker/command.js +677 -0
  436. package/src/runtime/worker/evidence.js +288 -0
  437. package/src/runtime/worker/launch.js +288 -0
  438. package/src/runtime/worker/models.js +137 -0
  439. package/src/runtime/worker/parsers.js +218 -0
  440. package/src/runtime/worker/probes/index.js +706 -0
  441. package/src/runtime/worker/process-tree.js +415 -0
  442. package/src/runtime/worker/quota.js +43 -0
  443. package/src/runtime/worker/readiness.js +713 -0
  444. package/src/runtime/worker/run-store.js +166 -0
  445. package/src/runtime/worker/supervisor.js +541 -0
  446. package/src/runtime/worker/worktree-check.js +252 -0
  447. package/src/runtime/workflow-engine.js +5 -1
  448. package/src/runtime/workflow-orchestrator.js +578 -63
  449. package/src/runtime/worktree.js +149 -22
  450. package/src/state/index.js +1 -1
  451. package/src/state/lockfile.js +64 -10
  452. package/src/state/run-lock.js +1 -1
  453. package/types/node-commonjs.d.ts +106 -7
  454. package/core/harnesses/gemini/hooks/hooks.json +0 -77
  455. package/core/harnesses/gemini/hooks/lib.sh +0 -302
  456. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -10
  457. package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
  458. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -10
  459. package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
  460. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -10
  461. package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
  462. package/core/harnesses/gemini/hooks/session-end.sh +0 -5
  463. package/core/harnesses/gemini/hooks/session-start.sh +0 -7
  464. package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
  465. package/core/shared/guidance/FLAGS.md +0 -25
  466. package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
  467. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
  468. package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
  469. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
  470. package/src/adapters/gemini/hooks.js +0 -251
  471. package/src/adapters/gemini/index.js +0 -429
@@ -14,8 +14,12 @@
14
14
  #
15
15
  # Usage: doflow-run <verb> [args...]
16
16
  # enforcement --harness <id> --policy <id> [--profile <id>] [--json]
17
+ # context-emit --event launch|prompt|delta --cwd <dir> [--session <id>] [--harness <id>]
18
+ # [--nudge nudge|suppress|none] [--max-bytes <n>] [--task-id <id>] [--slug <slug>] [--peek] [--json]
19
+ # context-grant --summary <summaryId|pending> --to-run <id> --to-lineage <id>
20
+ # [--from-worktree <dir>] [--from-run <id>] [--from-lineage <id>] [--max-bytes <n>] [--json]
17
21
  # Every verb accepts --json. Exit 0 = success, 1 = an actionable finding, 2 = usage or
18
- # resolution error, 3 = context-pack overflow. Arguments, stdin and exit status pass through the
22
+ # resolution error, 3 = context-pack overflow or context-emit refusal. Arguments, stdin and exit status pass through the
19
23
  # dispatcher unmodified —
20
24
  # `sync-context` reads its block body from stdin, so anything that buffered or consumed it here
21
25
  # would break that verb rather than merely inconvenience it.
@@ -30,29 +34,61 @@ set -euo pipefail
30
34
  # `set -euo pipefail` never stops on it; nothing in it can reach the dispatcher's own options or
31
35
  # variables. Appends one JSON line of at most 1000 bytes (longer appends from concurrent writers can
32
36
  # interleave) and never rotates: rotation is done by the Node writers only (IC-015, DEC-019). It is
33
- # a no-op when no failure home can be resolved (HOME unset, or XDG_CONFIG_HOME relative) and while
34
- # capture is off (the `off` sentinel file wins; DOFLOW_FAILURE_CAPTURE=off|0|false|no also turns it
35
- # off). The line carries only names from DoFlow's own tables and the working directory: never an
36
- # argument, stdin or the environment.
37
+ # a no-op when there is no config home (neither XDG_CONFIG_HOME nor HOME is set to an absolute path;
38
+ # doflow_config_home below, the rule of src/runtime/config-home.ts) and while capture is off
39
+ # (DOFLOW_FAILURE_CAPTURE=off|0|false|no, the `off` sentinel file, or a `failure.capture` value other
40
+ # than "on" in <config home>/settings.json, read by doflow_lex_capture below). The line carries only
41
+ # names from DoFlow's own tables and the working directory: never an argument, stdin or the
42
+ # environment.
37
43
  # capture_failure <command> <kind> <exit status>
38
44
  CAPTURE_VERB=""
39
45
 
46
+ # BEGIN doflow-config-home v1 (rule: src/runtime/config-home.ts; checked by test/guards/settings.test.js)
47
+ doflow_config_home() {
48
+ DOFLOW_HOME=""
49
+ case "${XDG_CONFIG_HOME:-}" in
50
+ /*) DOFLOW_HOME="${XDG_CONFIG_HOME}/doflow"; return 0 ;;
51
+ [A-Za-z]:[\\/]*) case "${OSTYPE:-}" in msys*|cygwin*|win32*) DOFLOW_HOME="${XDG_CONFIG_HOME}/doflow"; return 0 ;; esac ;;
52
+ esac
53
+ case "${HOME:-}" in
54
+ /*) DOFLOW_HOME="${HOME}/.config/doflow" ;;
55
+ [A-Za-z]:[\\/]*) case "${OSTYPE:-}" in msys*|cygwin*|win32*) DOFLOW_HOME="${HOME}/.config/doflow" ;; esac ;;
56
+ esac
57
+ return 0
58
+ }
59
+ # END doflow-config-home v1
60
+
61
+ # BEGIN doflow-settings-lexical v1 (rule: src/runtime/settings/lexical.ts; checked by test/guards/settings.test.js)
62
+ doflow_lex_capture() {
63
+ local f="${1:-}" text="" rest="" d=""
64
+ local re='"failure\.capture"[[:space:]]*:[[:space:]]*("[^"]*"|[^,}"[:space:]]*)'
65
+ DOFLOW_LEX_CAPTURE=""
66
+ if [ ! -e "$f" ]; then
67
+ # Missing is no setting, unless the folder holding it cannot be searched (Node: EACCES is off).
68
+ d="${f%/*}"
69
+ if [ -n "$d" ] && [ "$d" != "$f" ] && [ -d "$d" ] && [ ! -x "$d" ]; then DOFLOW_LEX_CAPTURE="off"; fi
70
+ return 0
71
+ fi
72
+ if [ ! -f "$f" ] || [ ! -r "$f" ]; then DOFLOW_LEX_CAPTURE="off"; return 0; fi
73
+ IFS= read -r -d '' text < "$f" || true
74
+ rest="$text"
75
+ while [[ $rest =~ $re ]]; do
76
+ if [ "${BASH_REMATCH[1]}" = '"on"' ]; then DOFLOW_LEX_CAPTURE="${DOFLOW_LEX_CAPTURE:-on}"; else DOFLOW_LEX_CAPTURE="off"; fi
77
+ rest="${rest#*"${BASH_REMATCH[0]}"}"
78
+ done
79
+ return 0
80
+ }
81
+ # END doflow-settings-lexical v1
82
+
83
+
40
84
  capture_failure_write() {
41
85
  local command="${1:-}" kind="${2:-}" status="${3:-}"
42
86
  local home="" setting="" version="" candidate="" project="" harness="" at="" line="" cwd="" hp=""
43
87
  export LC_ALL=C
44
88
 
45
- if [ -n "${XDG_CONFIG_HOME:-}" ]; then
46
- case "$XDG_CONFIG_HOME" in
47
- /*) home="$XDG_CONFIG_HOME/doflow/failures" ;;
48
- *) return 0 ;;
49
- esac
50
- else
51
- case "${HOME:-}" in
52
- /*) home="$HOME/.config/doflow/failures" ;;
53
- *) return 0 ;;
54
- esac
55
- fi
89
+ doflow_config_home
90
+ [ -n "$DOFLOW_HOME" ] || return 0
91
+ home="$DOFLOW_HOME/failures"
56
92
 
57
93
  # Case-insensitive, whitespace trimmed at the ends only: the same reading the Node writer has.
58
94
  setting="$(printf '%s' "${DOFLOW_FAILURE_CAPTURE:-}" | tr '[:upper:]' '[:lower:]')" || return 0
@@ -62,6 +98,8 @@ capture_failure_write() {
62
98
  off|0|false|no) return 0 ;;
63
99
  esac
64
100
  [ -f "$home/off" ] && return 0
101
+ doflow_lex_capture "$DOFLOW_HOME/settings.json"
102
+ [ "$DOFLOW_LEX_CAPTURE" = off ] && return 0
65
103
 
66
104
  # The command is a verb the dispatcher has already matched against its own tables, or `dispatcher`.
67
105
  [[ "$command" =~ ^[a-z][a-z0-9-]{0,39}$ ]] || command="dispatcher"
@@ -114,14 +152,15 @@ capture_failure() {
114
152
 
115
153
  # After a verb ran: a status outside {0, 1, 2} is a crash worth recording (a signal, a runtime that
116
154
  # died), minus what is not DoFlow's fault (DEC-031): 127 (command not found), 130, 141 and 143
117
- # (interrupted, broken pipe, terminated), task-not-found status 3 of `task-brief`, and overflow
118
- # status 3 of `context-pack`. A Node crash exits 1 and is recorded by the CLI itself, so it is
155
+ # (interrupted, broken pipe, terminated), task-not-found status 3 of `task-brief`, overflow
156
+ # status 3 of `context-pack`, refused status 3 of `context-emit`, and over-budget status 3 of
157
+ # `context-grant`. A Node crash exits 1 and is recorded by the CLI itself, so it is
119
158
  # never counted twice.
120
159
  capture_exit_status() {
121
160
  local verb="${1:-}" status="${2:-0}"
122
161
  case "$status" in
123
162
  0|1|2|127|130|141|143) return 0 ;;
124
- 3) case "$verb" in task-brief|context-pack) return 0 ;; esac ;;
163
+ 3) case "$verb" in task-brief|context-pack|context-emit|context-grant) return 0 ;; esac ;;
125
164
  esac
126
165
  capture_failure "$verb" "exit-$status" "$status"
127
166
  return 0
@@ -165,8 +204,13 @@ resolve_config_dir() {
165
204
  dir="$(pwd -P 2>/dev/null || pwd)"
166
205
  while [ -n "$dir" ] && [ "$dir" != "/" ]; do
167
206
  if [ -d "$dir/.doflow" ]; then
168
- printf '%s' "$dir/.doflow"
169
- return 0
207
+ case "$dir/" in
208
+ */.doflow/*) ;;
209
+ *)
210
+ printf '%s' "$dir/.doflow"
211
+ return 0
212
+ ;;
213
+ esac
170
214
  fi
171
215
  dir="$(dirname "$dir")"
172
216
  done
@@ -353,7 +397,9 @@ Workflow and evidence:
353
397
  workflow resolve stages, dependencies and gates for a class
354
398
  orchestrate start/resume a run: complete stages, skip optional ones, decide gates
355
399
  research-request open, list or resolve a feature-stage research question
356
- task-attempt claim, finish, release or read the attempts on a plan's tasks
400
+ task-attempt claim, finish, release, start, pause, cancel, resume, inspect, reopen or report-usage on a plan's task attempts
401
+ worker discover, probe, describe, select, run, status or cancel an external headless worker on a claimed task
402
+ dispatch run a feature's task graph: start, step, run, submit, spawn, pause, inspect, cancel, takeover or resume
357
403
  retrieve BM25 search over the installed guidance tree (auto-refreshing index)
358
404
  model-role resolve an abstract model role to ranked, availability-annotated providers
359
405
  route resolve an information need to a healthy provider
@@ -361,6 +407,8 @@ Workflow and evidence:
361
407
  claim record or update a claim and its support state
362
408
  readiness evaluate readiness; return state and missing items
363
409
  context-pack emit the compiled context pack for a stage
410
+ context-emit decide and render one launch, prompt or delta emission (launcher entry)
411
+ context-grant grant one compacted summary to a launched run and lineage
364
412
  retrieval-plan declare the needs a stage will resolve, attempt each need, then report every declared item
365
413
  outcome record a task's terminal state with its basis, or show what was recorded
366
414
  scaffold emit the code scaffold the active feature's artifacts imply
@@ -369,6 +417,17 @@ Workflow and evidence:
369
417
  lifecycle overview, init, status, release or merged: follow-ups and feature tracking for the project
370
418
  goal add, check, link, list or close a goal and its checklist
371
419
  failure list, settle or switch off the failures DoFlow captured on this machine
420
+ roadmap session-driven autopilot runner: render or status the roadmap table
421
+ plan-check check a plan's task lines the way the task-attempt ledger reads them
422
+ review validate a feature's review/findings.json, print counts and advisories (review-package assembles the payload)
423
+ protocol print the review and debate protocol presets, or the one a run would use (read-only)
424
+ rules print the values the runtime owns for this project, each with its source (read-only)
425
+ primary resolve which harness and model the main session runs (read-only)
426
+ fleet list the projects this machine knows (read-only)
427
+ transcript read an agent's recent events, or the project's traffic (read-only)
428
+ package list the contribution points a package may fill, check a package directory, list/show packages (read-only), add/update a local package (a plan, then --plan applies it), or enable/disable/trust/exempt/revoke/verify/remove one
429
+ slot named machine-wide queue: run a command as its one holder, list or release
430
+ models synchronize, list, or inspect observed models across workers (--action sync|list|describe)
372
431
 
373
432
  Verification and recovery:
374
433
  verify compile the contract, run checks, emit the report
@@ -376,7 +435,7 @@ Verification and recovery:
376
435
  leak-scan report DoFlow-internal identifiers in shipped files
377
436
 
378
437
  Observability:
379
- trace current run trajectory
438
+ trace current run trajectory; trace spans: the span view; trace analyze: its detectors; trace export: OTLP/HTTP export
380
439
  stats aggregate run usage
381
440
  indicators per-stage and per-gate timings from the orchestration record
382
441
  discover missed opportunities in recorded runs
@@ -384,6 +443,7 @@ Observability:
384
443
  capabilities provider resolution
385
444
  enforcement verified lifecycle policy coverage
386
445
  doctor installation and provider health
446
+ config list effective settings and their origins
387
447
  storage report stored data and its retention bounds
388
448
  EOF
389
449
  }
@@ -439,12 +499,23 @@ now_ms() {
439
499
  #
440
500
  # Tracing never changes what a verb returned. Every step is failure-tolerant and the function
441
501
  # always succeeds: an unwritable state directory degrades observability, not the run.
502
+ #
503
+ # Session identity (082 IC-035, DEC-012, DEC-031, DEC-042): `run`, `lineage` and `attempt` come
504
+ # from the environment only, each written quoted when it matches identity.ts's pattern (ERE, held in
505
+ # a variable so `[[ =~ ]]` reads it unquoted, which bash 3.2 supports) and `null` otherwise. A value
506
+ # that passes holds no quote, backslash or control character, so quoting it cannot break the line.
507
+ # `[[ ]]` is a builtin: the trace starts no process beyond `mkdir` and `date` (NFR-007).
442
508
  trace_run() {
443
509
  local verb="$1" code="$2" duration="$3" argc="$4" started_at="$5"
444
510
  local runs_dir="$CONFIG_DIR/state/runs"
511
+ local id_re='^[A-Za-z0-9][A-Za-z0-9_-]{0,55}$' attempt_re='^[1-9][0-9]{0,3}$'
512
+ local run_v=null lineage_v=null attempt_v=null
513
+ if [[ "${DOFLOW_RUN_ID:-}" =~ $id_re && "${DOFLOW_RUN_ID}" != local ]]; then run_v="\"${DOFLOW_RUN_ID}\""; fi
514
+ if [[ "${DOFLOW_LINEAGE_ID:-}" =~ $id_re ]]; then lineage_v="\"${DOFLOW_LINEAGE_ID}\""; fi
515
+ if [[ "${DOFLOW_ATTEMPT:-}" =~ $attempt_re ]]; then attempt_v="\"${DOFLOW_ATTEMPT}\""; fi
445
516
  mkdir -p "$runs_dir" 2>/dev/null || return 0
446
- printf '{"timestamp":"%s","verb":"%s","exit_code":%s,"duration_ms":%s,"arg_count":%s}\n' \
447
- "$started_at" "$verb" "$code" "$duration" "$argc" \
517
+ printf '{"timestamp":"%s","verb":"%s","exit_code":%s,"duration_ms":%s,"arg_count":%s,"run":%s,"lineage":%s,"attempt":%s}\n' \
518
+ "$started_at" "$verb" "$code" "$duration" "$argc" "$run_v" "$lineage_v" "$attempt_v" \
448
519
  >>"$runs_dir/$(date -u +%Y-%m-%d).jsonl" 2>/dev/null || return 0
449
520
  return 0
450
521
  }
@@ -481,8 +552,8 @@ shell_helper_for() {
481
552
  # command list; an unbuilt verb is dispatched and the CLI answers for itself.
482
553
  is_node_verb() {
483
554
  case "$1" in
484
- classify|workflow|route|evidence|claim|readiness|context-pack|retrieval-plan|outcome|scaffold|decision|followup|lifecycle|goal|failure|verify|recover|leak-scan|\
485
- trace|stats|indicators|discover|inventory|capabilities|enforcement|doctor|orchestrate|research-request|task-attempt|retrieve|model-role|storage|brief-tools|advise) return 0 ;;
555
+ classify|workflow|route|evidence|claim|readiness|context-pack|context-emit|context-grant|retrieval-plan|outcome|scaffold|decision|followup|lifecycle|goal|failure|verify|recover|leak-scan|\
556
+ trace|stats|indicators|discover|inventory|capabilities|enforcement|doctor|config|orchestrate|research-request|task-attempt|worker|dispatch|retrieve|model-role|storage|brief-tools|advise|roadmap|plan-check|review|protocol|rules|primary|fleet|transcript|package|slot|models) return 0 ;;
486
557
  *) return 1 ;;
487
558
  esac
488
559
  }
@@ -502,7 +573,7 @@ dispatch_shell() {
502
573
 
503
574
  dispatch_node() {
504
575
  local verb="$1"; shift
505
- local marker tmpfile rc first_line
576
+ local marker tmpfile outfile registry_msg rc first_line runtime_root second_line trimmed_second first_val total_errs more
506
577
  if ! resolve_node_cli; then
507
578
  if marker="$(has_doflow_marker_nearby)"; then
508
579
  fail 2 "unlinked-checkout" \
@@ -514,17 +585,40 @@ dispatch_node() {
514
585
  if [ "$NODE_CLI_KIND" = "script" ]; then
515
586
  command -v node >/dev/null 2>&1 || fail 2 "node-not-found" \
516
587
  "verb '$verb' needs node on PATH to run $NODE_CLI_PATH"
517
- case "$NODE_CLI_SOURCE" in
518
- project-runtime|global-runtime)
588
+ case "$NODE_CLI_SOURCE:$verb" in
589
+ # `slot run` streams its command's output and holds the queue for as long as the command
590
+ # runs, so its stderr is never held back for the stale-runtime check below.
591
+ *:slot)
592
+ node "$NODE_CLI_PATH" "$verb" "$@"
593
+ ;;
594
+ project-runtime:*|global-runtime:*)
519
595
  # These two sources are a *projected copy* of the runtime, not the checkout itself, so
520
596
  # they can drift out of sync with the working tree's registry. Stdout still streams
521
597
  # directly; only stderr is captured, so a version-drift crash can be told apart from a
522
598
  # verb legitimately reporting a finding (e.g. readiness's NEEDS_EVIDENCE) before either
523
599
  # reaches the caller.
524
600
  tmpfile="$(mktemp)"
525
- trap 'rm -f "$tmpfile" 2>/dev/null || true' EXIT
601
+ outfile=""
602
+ # `worker` and `dispatch` catch the registry error themselves and, under --json, report it as
603
+ # a JSON body on stdout (error "registry-invalid") with nothing on stderr; the other verbs let
604
+ # it reach stderr. Only those two have stdout held back (their --json body is a single
605
+ # document written at the end), so the same stale-runtime report can be built for them.
606
+ case "$verb" in
607
+ worker|dispatch) if [ "$wants_json" = true ]; then outfile="$(mktemp)"; fi ;;
608
+ esac
609
+ trap 'rm -f "$tmpfile" "$outfile" 2>/dev/null || true' EXIT
526
610
  rc=0
527
- node "$NODE_CLI_PATH" "$verb" "$@" 2>"$tmpfile" || rc=$?
611
+ if [ -n "$outfile" ]; then
612
+ node "$NODE_CLI_PATH" "$verb" "$@" >"$outfile" 2>"$tmpfile" || rc=$?
613
+ if [ "$rc" -eq 2 ]; then
614
+ registry_msg="$(node -e 'try{const o=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8"));if(o&&o.error==="registry-invalid"&&typeof o.message==="string")process.stdout.write(o.message)}catch{}' "$outfile" 2>/dev/null)" || registry_msg=""
615
+ if [ -n "$registry_msg" ]; then
616
+ printf '[ERROR] %s\n' "$registry_msg" >"$tmpfile"
617
+ fi
618
+ fi
619
+ else
620
+ node "$NODE_CLI_PATH" "$verb" "$@" 2>"$tmpfile" || rc=$?
621
+ fi
528
622
  if [ "$rc" -ne 0 ]; then
529
623
  first_line=""
530
624
  IFS= read -r first_line <"$tmpfile" || true
@@ -533,13 +627,34 @@ dispatch_node() {
533
627
  # anchored match against the registry loader's raw prefix never fires in practice.
534
628
  case "$first_line" in
535
629
  *"Invalid DoFlow registry:"*)
630
+ runtime_root="$(dirname "$(dirname "$NODE_CLI_PATH")")"
631
+ second_line=""
632
+ {
633
+ read -r _
634
+ IFS= read -r second_line || true
635
+ } <"$tmpfile"
636
+ second_line="${second_line%$'\r'}"
637
+ trimmed_second="${second_line#"${second_line%%[![:space:]]*}"}"
638
+ first_val="${trimmed_second#- }"
639
+ if [ -z "$first_val" ]; then
640
+ first_val="${first_line#*Invalid DoFlow registry:}"
641
+ first_val="${first_val#"${first_val%%[![:space:]]*}"}"
642
+ fi
643
+ first_val="${first_val%$'\r'}"
644
+ total_errs="$(grep -c '^[[:space:]]*- ' "$tmpfile" || true)"
645
+ case "$total_errs" in *[!0-9]*|"") total_errs=0 ;; esac
646
+ more=""
647
+ if [ "$total_errs" -gt 1 ]; then
648
+ more=" ($(( total_errs - 1 )) more)"
649
+ fi
536
650
  fail 2 "stale-runtime" \
537
- "verb '$verb' failed against $NODE_CLI_PATH, which appears out of date relative to the working checkout; reinstall or re-run the doflow installer to refresh it"
651
+ "verb '$verb' failed: the registry at $runtime_root/core/registry is invalid: $first_val$more; reinstall DoFlow if this runtime was projected from another version"
538
652
  ;;
539
653
  esac
540
654
  fi
655
+ if [ -n "$outfile" ]; then cat "$outfile"; fi
541
656
  cat "$tmpfile" >&2
542
- rm -f "$tmpfile"
657
+ rm -f "$tmpfile" "$outfile"
543
658
  trap - EXIT
544
659
  return "$rc"
545
660
  ;;
@@ -18,7 +18,7 @@ Universal command dispatcher, task decomposer, capability router, and developmen
18
18
 
19
19
  1. **Session & Command Dispatch**:
20
20
  - If invoked with no arguments or `--help`, announce DoFlow session status and display the core command reference.
21
- - If `$1` matches a known `/do-*` skill (`do-flow`, `do-brainstorm`, `do-design`, `do-plan`, `do-execute-plan`, `do-test`, `do-code-review`, `do-git`, `do-constitution`, `do-diagnose`, `do-document`, `do-implement`), forward to that skill directly.
21
+ - If `$1` matches a `/do-*` skill in the Core Command Reference table below, forward to that skill directly.
22
22
  - Otherwise, resolve the runtime seam **once** and reuse `$DOFLOW` for every later call here:
23
23
 
24
24
  ```bash
@@ -38,14 +38,18 @@ Run every command below from the project root — the walk-up starts at `$PWD`.
38
38
  `doflow-run lifecycle --action overview --maintain --since T --json` (`doflow-run` is the
39
39
  `$DOFLOW` resolved above), and settle each pending item with the question tool through the
40
40
  `doflow-run followup`, `doflow-run goal` or `doflow-run failure` command its `next` lines give.
41
+ Advice on a follow-up: `references/advice_calls.md`, followup-triage.
41
42
  Rerun with the same `--since T` until nothing is pending. A product problem the user reports
42
43
  goes to `doflow-run followup --action report`; a large goal they state, to
43
44
  `doflow-run goal --action add`. It edits no source file.
45
+ - `/do program <goal>`, or an ask larger than one feature: follow `references/program_mode.md`, researching per
46
+ `../do-document/references/deep_research.md` at the tiers the guidance tree's `references/MODEL_SELECTION.md` gives.
47
+ - `/do package <idea>` or "make this a DoFlow extension/package/plugin": run `"$DOFLOW" package --action points --json`; stop if a needed point is not open. Ask up to 3 questions (what/why, id, points) via the question tool; run `"$DOFLOW" package --action new --id <id> --points <point[:local],...>`; follow `next` lines. No evidence batch; never write `grants.jsonl`, add remote sources or create a feature folder.
44
48
 
45
49
  2. **Multi-Part / Ambiguous Request Routing (`--depth`)**:
46
50
  - When a request bundles 2+ unrelated asks across different files or domains, verify referenced files exist first.
47
51
  - Decompose into independent or sequenced work packages, then propose **one task class per
48
- package** and let the runtime validate each: `"$DOFLOW" classify --task-class "<proposed>" --calling-skill do [--request <shell-escaped argument> | --request-file <file>] --json`. Prefer `--request-file`: create a temporary UTF-8 file with `mktemp`, write the verbatim request as the body of a single-quoted heredoc whose delimiter does not occur on any request line, pass only its path, and install cleanup traps plus explicit removal. Never interpolate raw request text into a shell command or word; use `--request` only as one safely shell-escaped argument, and omit the optional opinion if safe transport is unavailable. The flags are mutually exclusive.
52
+ package** and let the runtime validate each: `"$DOFLOW" classify --task-class "<proposed>" --calling-skill do (--request-file <file> | --request <shell-escaped argument>) --json`. Always pass the request. Prefer `--request-file`: create a temporary UTF-8 file with `mktemp`, write the verbatim request as the body of a single-quoted heredoc whose delimiter does not occur on any request line, pass only its path, and install cleanup traps plus explicit removal. Never interpolate raw request text into a shell command or word; use `--request` only as one safely shell-escaped argument, and omit the optional opinion if safe transport is unavailable. The flags are mutually exclusive.
49
53
 
50
54
  When the JSON carries `secondOpinion.status: "answered"` with `agrees: false`, tell the user the decision model picked a different class, in one line naming both; the verdict stands, and no other action follows from it.
51
55
 
@@ -64,17 +68,14 @@ Route each package to the accepted workflow's first stage. A workflow whose `sta
64
68
  that does the package's work is a misclassification — re-propose the class rather than routing the
65
69
  package under one the runtime accepted for a different kind of task.
66
70
 
71
+ Advice on a worker's tier: `references/advice_calls.md`, tier.
72
+
67
73
  - For detailed decomposition and dependency graph formatting, consult this skill's own
68
- `references/pm_routing.md`.
74
+ `references/pm_routing.md`; before dispatching agents, read the guidance tree's
75
+ `references/ORCHESTRATION.md` and `references/MODEL_SELECTION.md`.
69
76
 
70
77
  3. **Capability & Tool Selection**:
71
- - Before routing, check what recorded runs already show — run `"$DOFLOW" discover --json`
72
- (reuse `$DOFLOW` resolved in step 1). **It exits 1 when there is a finding — that is signal,
73
- not failure; never treat that exit code as an error.** When the analysis cannot be settled
74
- from the recorded metadata, `discover` reports `UNKNOWN` rather than "clear"; surface `UNKNOWN`
75
- as undetermined and never round it up to "no missed opportunities". `do` surfaces the finding
76
- to the user — it takes no automatic action on it, and no finding is ever rendered as a number,
77
- a percentage, or a confidence.
78
+ - Before routing, run `"$DOFLOW" discover --json` to check recorded runs. Exit 1 signals a finding, not an error. When metadata cannot settle the analysis, surface `UNKNOWN` as undetermined, never clear. Show findings to the user; take no automatic action. Never render findings as a number, percentage or confidence.
78
79
  - Routing an information need to a tool is unconditional, not a mode this skill can be asked
79
80
  for: whenever a search, graph, or testing need arises, query the Capability Router — run `"$DOFLOW" capabilities` (add `--json` to parse, `--check` for a deep
80
81
  smoke check), or `"$DOFLOW" route --intent <intent> --json` to resolve one need end to end. It
@@ -82,6 +83,7 @@ package under one the runtime accepted for a different kind of task.
82
83
  Ripgrep when absent, and a static table cannot know that.
83
84
  - Consult this skill's own `references/tool_matrix.md` for the intent→capability map and the two
84
85
  fallback layers. Treat the router's output as authoritative when the two disagree.
86
+ - Advice on an MCP server's trigger: `references/advice_calls.md`, mcp-need.
85
87
 
86
88
  4. **Scope & Effort Estimation (`--estimate`)**:
87
89
  - When asked for sizing, complexity, or timeline estimates, produce a range anchored against git history and file scope, stating the assumptions that set its width and the unknowns that would narrow it. Never attach a numeric or percentage certainty to the range — the assumptions are the honest expression of what is not yet known.
@@ -0,0 +1,26 @@
1
+ # Advice calls
2
+
3
+ Optional. Skip a call and its outcome call unless `status` is `answered`; on `agrees: false` say so in one line and keep your judgement. `classify` asks `task-class` itself.
4
+
5
+ ## tier
6
+
7
+ ```bash
8
+ "$DOFLOW" advise --kind tier --state "<the package>" --static "<light|standard|frontier>" --task-id "<task id>" --json
9
+ "$DOFLOW" advise --action outcome --pick-id "<pickId>" --actual "<tier used>"
10
+ ```
11
+
12
+ ## mcp-need
13
+
14
+ ```bash
15
+ "$DOFLOW" advise --kind mcp-need --server <id> --state "<the stage>" --static <yes|no> --task-id "<task id>" --json
16
+ "$DOFLOW" advise --action outcome --pick-id "<pickId>" --actual "<yes|no: server used>"
17
+ ```
18
+
19
+ ## followup-triage
20
+
21
+ No `--static`; the pick is input to the question.
22
+
23
+ ```bash
24
+ "$DOFLOW" advise --kind followup-triage --state "<its text>" --task-id "<its id>" --json
25
+ "$DOFLOW" advise --action outcome --pick-id "<pickId>" --actual "<now|later|dismiss>"
26
+ ```
@@ -7,8 +7,7 @@ Decomposition depth guidelines when `/do` processes multi-part, cross-domain req
7
7
  Produce a flat table: Part | Domain | Target Skill / Agent | Completion Gate
8
8
  - `--depth normal` (Shared context or sequence dependencies):
9
9
  Produce the shallow table plus an explicit dependency check (e.g., API contract before UI binding).
10
- - `--depth deep` (Multi-service / complex initiatives):
11
- Full Epic $\rightarrow$ Story $\rightarrow$ Task hierarchy ready for `/do-plan`.
10
+ - `--depth deep` (programme-sized: more than one feature): program mode, `program_mode.md`.
12
11
 
13
12
  ## Delegation Matrix
14
13
  - Feature discovery $\rightarrow$ `/do-brainstorm`
@@ -0,0 +1,31 @@
1
+ # Program mode
2
+
3
+ For an ask larger than one feature: research, offer roadmap shapes, hand over a checked draft. It
4
+ writes no roadmap row and edits no source.
5
+
6
+ 1. **Enter.** `/do program <goal>` enters. An ask naming more than one independently shippable
7
+ outcome may enter: name the signal in one line and ask with the question tool (program mode
8
+ first, "one feature" second) before any research. Anything else routes as before.
9
+ 2. **Contract.** Write the sub-questions the roadmap needs (users, scope edges, existing surfaces,
10
+ ordering risks), at most 6. Task id: `program-<kebab-of-goal>`.
11
+ 3. **Research.** One broad round over the whole goal, then one targeted round per sub-question, per
12
+ `../do-document/references/deep_research.md` (no report file), at most 6 sources each. Run
13
+ independent sub-questions as parallel subagents where the harness has them, else in turn, at the
14
+ tier the guidance tree's `references/MODEL_SELECTION.md` gives: `light` to scout or extract,
15
+ `standard` to research, `frontier` to judge and pick shapes. Mark each finding sourced (with its
16
+ locator) or inferred. Stop when every sub-question has an answer or a stated gap and the last
17
+ round added nothing; report the gaps. Record one evidence batch and one claim per conclusion
18
+ under this task id with SKILL.md step 5's commands, per the guidance tree's
19
+ `references/EVIDENCE_LEDGER.md`.
20
+ 4. **Shapes.** Offer two or three roadmap shapes through the question tool, recommended first: rows
21
+ in outline, order and the main trade-off. One viable shape: say why the others fell.
22
+ 5. **Draft.** Write the chosen shape as `{"schema":1,"rows":[...]}`: per row `id`, `slug`, `title`,
23
+ `class`, `needs`, a rough `writeSet`, one-line `intent`, at most 8 `acceptance` lines; nothing a
24
+ row's own chain decides later. New rows go to `agent-docs/roadmap/draft.json` with ids above the
25
+ store's highest; changes to rows not started go to `agent-docs/roadmap/draft-amend.json`. Ask
26
+ before overwriting either file.
27
+ 6. **Check.** Run `"$DOFLOW" roadmap seed --action check --draft <path> --json` per draft. Fix the
28
+ findings and re-check, at most 3 times; every row of a draft must carry the same `change`. Show
29
+ the result line, overlaps, `alone` rows and gaps. A draft with findings is not ready.
30
+ 7. **Hand over.** Show the person the `land` command `check` printed and stop. Landing is the
31
+ person's act: never run it, and never hand it to a subagent, a policy or autopilot.
@@ -18,23 +18,8 @@ session-end without a separate save step.
18
18
  /do-brainstorm [topic/idea] [--intent <path>] [--depth shallow|normal|deep]
19
19
  ```
20
20
 
21
- **`--intent <path>`** seeds this stage from a pre-branch intent. An intent lives at
22
- `agent-docs/intent/<kebab-description>.md`, outside the branch-coupled tree, and is written before any
23
- branch or feature exists — so it is the one input this skill may be given that did not come from the
24
- conversation. When the flag is present:
25
-
26
- - Read the file. Carry its Problem, Proposed outcome, Affected and Constraints into the requirement you
27
- write, in §1, §2 and §4 respectively. Treat its **Open questions** as ambiguities for step 3's
28
- clarification loop — they are the originator saying what they did not know, not answers to fold in.
29
- - Fill `requirement.md`'s `**Intent:**` header field with the path you read, so a reader can see where
30
- the problem statement came from and judge whether it was reinterpreted.
31
- - Never move, rename, delete or rewrite the intent. It records what was asked; `requirement.md` records
32
- what the project decided to do about it, and the two are allowed to diverge.
33
- - A path that does not exist is a mistake, not an absence: say so and stop, rather than proceeding as
34
- though no intent had been named.
35
-
36
- Without the flag, nothing below changes and no intent is owed — discovery starting from a conversation
37
- alone is the ordinary case.
21
+ **`--intent <path>`** seeds this stage from a pre-branch intent at `agent-docs/intent/`. When the flag is
22
+ present, read `references/intent_seed.md` before step 1. Without the flag, no intent is owed.
38
23
 
39
24
  ## Behavioral Flow
40
25
 
@@ -63,7 +48,7 @@ Run every command below from the project root — the walk-up starts at `$PWD`.
63
48
  If `feature_slug` is `null` **and** `candidate_slugs` is non-empty (a non-git root — e.g.
64
49
  doflow installed at a multi-service container root — with 2+ `agent-docs/doflow/` feature dirs
65
50
  and no branch to disambiguate), this is NOT "no active feature" — it's an unresolved choice.
66
- Ask via `AskUserQuestion`, one option per `candidate_slugs` entry, before continuing to step 3;
51
+ Ask via the question tool, one option per `candidate_slugs` entry, before continuing to step 3;
67
52
  never fall through to step 4's fresh-feature path on an ambiguous result, that would create a
68
53
  duplicate feature dir. Re-resolve with `"$DOFLOW" paths --json --slug="<chosen>"` and
69
54
  use that slug for the rest of this flow. If `/do-flow` already disambiguated and is invoking this skill
@@ -99,30 +84,22 @@ workflow never reads.
99
84
  fact → verify it per `MCP_Context7.md`, read-only, never a tech choice.
100
85
  - MCP `sequential-thinking`: a round's open ambiguity spans 2+ components, actors or FRs →
101
86
  reason it per `MCP_Sequential.md`.
102
- After each dialogue round, before moving to the next round, partition any ambiguities
103
- surfaced that round into: *independent* ones (answerable without knowing another's answer) —
104
- up to 4 — batched into one `AskUserQuestion` call (the tool's 4-question max); *dependent*
105
- ones (whose options depend on a prior answer) — asked as their own individual `AskUserQuestion`
106
- call, in dependency order, after the dependency resolves; never batched with something it
107
- depends on. Every question built for this loop MUST include an explicit "Decide for me" choice
108
- among its listed options (on top of the tool's automatic "Other" free-text escape), so the
109
- defer path below is actually selectable. Any question where the user picks that "Decide for
110
- me" option (distinct from the general "Other" free-text escape) resolves via a recorded
111
- assumption rather than by re-prompting — see Step 5 for where that assumption is recorded.
87
+ After each dialogue round, partition surfaced ambiguities into: *independent* ones (answerable
88
+ without knowing another's answer) — up to 4 batched into one question-tool call (the tool's 4-question max);
89
+ *dependent* ones — asked individually in dependency order after the prior answer resolves.
90
+ Every question must include an explicit "Decide for me" choice (on top of "Other" free-text escape);
91
+ picking it resolves via a recorded assumption (see Step 5).
92
+
93
+ ### Structured Multiple-Choice Format
94
+ When asking clarifying questions:
95
+ - Use structured multiple-choice options — never bury free-form questions in prose.
96
+ - Present 2–4 meaningful, mutually-exclusive options covering the realistic scenarios.
97
+ - Lead with the recommended default choice; provide an "Other" free-text escape as the final choice.
98
+
112
99
  **Stop when** every ambiguity the contract names has an answer or a stated gap, **and** the last round produced no new ambiguity. A round that only restates what you already have is the last round. Report the remaining gaps rather than continuing.
113
100
  The loop's posture — how deep to question, what a round is for — is the Behavioral Posture read
114
101
  below, not a second rule stated here.
115
- **Log each round.** One file per round, never appended to a prior round's file:
116
- `agent-docs/doflow/<slug>/intention/brainstorm-<NN>-question.md`, shaped by
117
- `templates/doflow/question-log-template.md` (same install path resolution as the requirement
118
- template in step 5) — every question as asked, the options offered, and the answer given, with a
119
- "Decide for me" pick recorded as the assumption it becomes rather than as an answer. `<NN>` is
120
- zero-padded to two digits and starts at step 1's `intention_next_round` — never hand-counted:
121
- the resolver already scanned the subdir, and this session's second round is that value plus one,
122
- its third plus two. Write the round's file as soon as its answers land, `mkdir -p` the
123
- `intention/` directory first. If `feature_slug` was still null at step 1 (a trunk branch with no
124
- feature picked yet), there is no directory to write into until step 4 resolves one — hold the
125
- rounds and write them all, in round order, immediately after step 4's `mkdir`.
102
+ **Log each round** to its own file, per `references/round_log.md`: read it before the first round ends.
126
103
  4. **Pick the feature** — if `feature_slug` is non-null (branch-derived, auto-selected from a
127
104
  single non-git candidate, or resolved via step 1's disambiguation), use it. If still null
128
105
  (genuinely no active feature: trunk branch, or a non-git root with zero existing feature dirs),
@@ -156,7 +133,7 @@ The template is `templates/doflow/requirement-template.md` in the install step 1
156
133
  with a one-line rationale.
157
134
  The `[NEEDS CLARIFICATION]` marker syntax remains only as a fallback for a session aborted
158
135
  mid-loop, not for a completed artifact. Populate the `**Ticket:**` header field only if the user
159
- referenced a PBI/epic/ticket ID during the dialogue (confirm the exact ID via `AskUserQuestion`
136
+ referenced a PBI/epic/ticket ID during the dialogue (confirm the exact ID via the question tool
160
137
  if it was ambiguous) — otherwise write `none`; do not add a new forced question to every
161
138
  brainstorm session just to fill this field.
162
139
  Structure the artifact per the guidance tree's `references/ARTIFACT_FORMAT.md` — read it before filling the template; it names which of this artifact's sections take an index-then-detail table.
@@ -189,39 +166,8 @@ Item schema, provenance rules, and the refused-field list: the guidance tree's `
189
166
  "$DOFLOW" orchestrate --action handoff --task-id "<slug>" --task-class "<class>" --calling-skill do-brainstorm --note "<requirement path written; §7 marker count>" --mcp-outcome "context7=<outcome>" --mcp-outcome "sequential-thinking=<outcome>" --json
190
167
  ```
191
168
  `<slug>` is step 1's `feature_slug`; `<class>` is step 2's accepted class.
192
- Branch on the response's `disposition`, not the exit code:
193
- - **`completed`** — this stage was recorded normally; check `awaitingGate` below.
194
- - **`annotated`** — this stage was already recorded on an earlier run of this skill (a
195
- re-invocation to amend `requirement.md`, say); the rerun note was appended, no gate to recheck.
196
- - **`deferred`** — a gate ahead of this stage, an unfinished mutating stage, or a rejected run
197
- prevented the handoff. Discovery is the chain's first stage, so nothing before it can open a
198
- gate; report `reason` plainly and stop rather than resolving something that is not this
199
- stage's.
200
- - **`standalone`** — no workflow applies; there is nothing further to record here.
201
-
202
- Then the gate anchored to this stage, read directly off the same response rather than re-derived
203
- from `workflow.gates[]`. A non-null `awaitingGate` carries the `gateId`, `name` and `prompt`
204
- (`gate-0`, "Unresolved clarifications", in the `feature` workflow); a null one means no gate
205
- follows this stage in this workflow and there is nothing to decide. `gate-0` is
206
- `clarification`-kind and its `unresolved-clarifications` trigger is exactly what step 9 already
207
- checks — so this stage resolves it rather than leaving a mechanically-answerable gate for a
208
- human. When §7 genuinely carries zero markers, approve it plainly — this is the routine path,
209
- never a forced one:
210
- ```bash
211
- "$DOFLOW" orchestrate --action decide-gate --task-id "<slug>" --gate "<awaitingGate.gateId>" --decision approve --note "requirement.md §7 carries zero markers" --json
212
- ```
213
- In the rare aborted-session case where markers remain, do **not** decide the gate at all: leave
214
- the run `AWAITING_GATE` and say so — resolving it is a human's call, and approving it anyway
215
- would be a forced override this stage has no reason to make. Finish by rendering the trail. The
216
- `--slug` value attaches with an `=`; a space-separated one is rejected with an error rather than
217
- silently rendering the wrong feature's trail:
218
- ```bash
219
- "$DOFLOW" render-audit --slug="<slug>" --json
220
- ```
221
- Every call in this step is advisory to the trail, not to the artifact. If one fails for a reason
222
- outside this flow's control (an unwritable local state directory, say), report the failure plainly and
223
- continue — a missing `audit.md` entry degrades the record, it does not make `requirement.md`
224
- wrong. None of these calls is a gate on finishing this skill.
169
+ Then read `references/handoff_branches.md` and branch on `disposition` and `awaitingGate` as it says;
170
+ every call in this step is advisory to the trail.
225
171
  9. **Stop** — report the requirement path and confirmation that §7 has zero remaining
226
172
  `[NEEDS CLARIFICATION]` markers (or, in the rare aborted-session case, whatever markers remain).
227
173
 
@@ -233,7 +179,7 @@ so skipping the read silently drops the posture it defines.
233
179
 
234
180
  ## Embedded feature research
235
181
 
236
- For an external fact gap or explicit request, follow the conditional protocol in `../do-document/references/embedded-research.md` before stage completion.
182
+ Run the ideation pass of `../do-document/references/embedded-research.md` before the first question round and its gap-or-request protocol on a gap; a skip says `ideation: skipped (<reason>)` at handoff.
237
183
 
238
184
  ## Boundaries
239
185
  **Will:** propose a task class and have the runtime validate it, run Socratic discovery, log each
@@ -0,0 +1,35 @@
1
+ # Step 8: branching on the handoff
2
+
3
+ Steps named here are SKILL.md's.
4
+
5
+ Branch on the response's `disposition`, not the exit code:
6
+ - **`completed`** — this stage was recorded normally; check `awaitingGate` below.
7
+ - **`annotated`** — this stage was already recorded on an earlier run of this skill (a
8
+ re-invocation to amend `requirement.md`, say); the rerun note was appended, no gate to recheck.
9
+ - **`deferred`** — a gate ahead of this stage, an unfinished mutating stage, or a rejected run
10
+ prevented the handoff. Discovery is the chain's first stage, so nothing before it can open a
11
+ gate; report `reason` plainly and stop rather than resolving something that is not this
12
+ stage's.
13
+ - **`standalone`** — no workflow applies; there is nothing further to record here.
14
+
15
+ Then the gate anchored to this stage, read directly off the same response rather than re-derived
16
+ from `workflow.gates[]`. A non-null `awaitingGate` carries the `gateId`, `name` and `prompt`
17
+ (`gate-0`, "Unresolved clarifications", in the `feature` workflow); a null one means no gate
18
+ follows this stage in this workflow and there is nothing to decide. `gate-0` is
19
+ `clarification`-kind and its `unresolved-clarifications` trigger is exactly what step 9 already
20
+ checks — so this stage resolves it rather than leaving a mechanically-answerable gate for a
21
+ human. When §7 genuinely carries zero markers, approve it plainly — this is the routine path,
22
+ never a forced one:
23
+ ```bash
24
+ "$DOFLOW" orchestrate --action decide-gate --task-id "<slug>" --gate "<awaitingGate.gateId>" --decision approve --note "requirement.md §7 carries zero markers" --json
25
+ ```
26
+ In the rare aborted-session case where markers remain, do **not** decide the gate at all: leave
27
+ the run `AWAITING_GATE` and say so — resolving it is a human's call, and approving it anyway
28
+ would be a forced override this stage has no reason to make. Finish by rendering the trail. The
29
+ `--slug` value attaches with an `=`; a space-separated one is rejected with an error rather than
30
+ silently rendering the wrong feature's trail:
31
+ ```bash
32
+ "$DOFLOW" render-audit --slug="<slug>" --json
33
+ ```
34
+ Every call in this step is advisory to the trail. If one fails, report it plainly and continue;
35
+ trail logging issues do not invalidate `requirement.md` or block finishing this skill.