@khoavu882/doflow 2.0.0-beta.5 → 2.0.1

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 (494) hide show
  1. package/README.md +16 -16
  2. package/bin/doflow.js +22 -12
  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/mcp-tool-guard.sh +4 -1
  9. package/core/harnesses/claude/hooks/permission-audit.sh +3 -0
  10. package/core/harnesses/claude/hooks/post-compact.sh +35 -32
  11. package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
  12. package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
  13. package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
  14. package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
  15. package/core/harnesses/claude/hooks/pre-implement-gate.sh +4 -1
  16. package/core/harnesses/claude/hooks/session-end.sh +23 -10
  17. package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
  18. package/core/harnesses/claude/settings/settings.json +26 -9
  19. package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
  20. package/core/harnesses/codex/agents/core-implementer.toml +1 -0
  21. package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
  22. package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
  23. package/core/harnesses/codex/agents/research-writer.toml +1 -1
  24. package/core/harnesses/codex/agents/reviewer.toml +10 -0
  25. package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
  26. package/core/harnesses/codex/agents/system-architect.toml +1 -1
  27. package/core/harnesses/codex/hooks/hooks.json +0 -10
  28. package/core/harnesses/codex/hooks/lib.sh +44 -25
  29. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +4 -1
  30. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
  31. package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
  32. package/core/harnesses/codex/hooks/pre-implement-gate.sh +4 -1
  33. package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
  34. package/core/harnesses/codex/hooks/subagent-audit.sh +1 -0
  35. package/core/harnesses/copilot/hooks/doflow-lib.sh +94 -0
  36. package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
  37. package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
  38. package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
  39. package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
  40. package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
  41. package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
  42. package/core/harnesses/copilot/hooks/doflow.json +51 -0
  43. package/core/harnesses/kiro/agents/doflow.json +1 -11
  44. package/core/harnesses/kiro/hooks/doflow.json +0 -10
  45. package/core/harnesses/kiro/hooks/lib.sh +26 -6
  46. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +8 -3
  47. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +8 -3
  48. package/core/harnesses/kiro/hooks/session-start.sh +1 -0
  49. package/core/harnesses/kiro/hooks/stop-check.sh +1 -0
  50. package/core/harnesses/pi/extensions/doflow-guard.js +11 -2
  51. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +1 -2
  52. package/core/harnesses/shared/hooks/adapters/antigravity.js +1 -1
  53. package/core/harnesses/shared/hooks/bridge/bridge.sh +126 -23
  54. package/core/harnesses/shared/hooks/bridge/envelope.jq +87 -18
  55. package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
  56. package/core/harnesses/shared/hooks/bridge/respond.sh +16 -2
  57. package/core/harnesses/shared/hooks/policies/capture-failure.sh +49 -16
  58. package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
  59. package/core/harnesses/shared/hooks/policies/contract.sh +3 -0
  60. package/core/harnesses/shared/hooks/policies/deny-json.sh +20 -7
  61. package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
  62. package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
  63. package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
  64. package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
  65. package/core/harnesses/shared/hooks/policies/lib.sh +63 -40
  66. package/core/harnesses/shared/hooks/policies/mcp-policy.conf +1 -1
  67. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +7 -8
  68. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +132 -57
  69. package/core/harnesses/shared/hooks/policies/session-context.sh +30 -1
  70. package/core/harnesses/shared/hooks/policies/stop-check.sh +27 -15
  71. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +6 -3
  72. package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
  73. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +60 -155
  74. package/core/harnesses/shared/hooks/stream-hook-runner.js +58 -20
  75. package/core/harnesses/shared/locator/doflow-run +2 -3
  76. package/core/registry/advice.json +3 -3
  77. package/core/registry/assets.json +55 -82
  78. package/core/registry/capabilities.json +12 -0
  79. package/core/registry/contracts.json +58 -31
  80. package/core/registry/contribution-points.json +35 -0
  81. package/core/registry/gates.json +32 -0
  82. package/core/registry/guidance-caps.json +40 -0
  83. package/core/registry/harnesses.json +1445 -366
  84. package/core/registry/intake.json +53 -0
  85. package/core/registry/lifecycle.json +599 -996
  86. package/core/registry/mcp.json +5 -1
  87. package/core/registry/models.json +7 -1
  88. package/core/registry/package-templates/README.md +19 -0
  89. package/core/registry/package-templates/agent/files/agent.md +9 -0
  90. package/core/registry/package-templates/agent/template.json +4 -0
  91. package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
  92. package/core/registry/package-templates/capability-provider/template.json +11 -0
  93. package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
  94. package/core/registry/package-templates/debate-preset/template.json +4 -0
  95. package/core/registry/package-templates/intake-category/files/category.json +8 -0
  96. package/core/registry/package-templates/intake-category/template.json +4 -0
  97. package/core/registry/package-templates/review-preset/files/preset.json +30 -0
  98. package/core/registry/package-templates/review-preset/template.json +4 -0
  99. package/core/registry/package-templates/skill/files/SKILL.md +8 -0
  100. package/core/registry/package-templates/skill/template.json +4 -0
  101. package/core/registry/package-templates/worker/files/worker.json +92 -0
  102. package/core/registry/package-templates/worker/template.json +11 -0
  103. package/core/registry/packages/doflow/doflow-package.json +15 -0
  104. package/core/registry/packages/doflow/presets/debate-3.json +26 -0
  105. package/core/registry/protocols.json +61 -0
  106. package/core/registry/routes.json +17 -0
  107. package/core/registry/rules.json +431 -0
  108. package/core/registry/settings.json +272 -0
  109. package/core/registry/storage.json +687 -31
  110. package/core/registry/telemetry.json +236 -0
  111. package/core/registry/transcripts.json +142 -0
  112. package/core/registry/verification.json +76 -6
  113. package/core/registry/workflows.json +55 -0
  114. package/core/shared/agent-specs/core-implementer.md +3 -0
  115. package/core/shared/agent-specs/delivery-lead.md +68 -0
  116. package/core/shared/agent-specs/quality-guardian.md +5 -1
  117. package/core/shared/agent-specs/research-writer.md +10 -3
  118. package/core/shared/agent-specs/reviewer.md +53 -0
  119. package/core/shared/agent-specs/spec-analyst.md +5 -6
  120. package/core/shared/agent-specs/system-architect.md +5 -1
  121. package/core/shared/guidance/DOFLOW_CORE.md +1 -5
  122. package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
  123. package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
  124. package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
  125. package/core/shared/guidance/pointers/codex.md +1 -4
  126. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
  127. package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
  128. package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
  129. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
  130. package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
  131. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
  132. package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
  133. package/core/shared/guidance/references/ORCHESTRATION.md +3 -2
  134. package/core/shared/guidance/references/WORKFLOW_HANDOFF.md +19 -1
  135. package/core/shared/guidance/rules/RULES.md +45 -0
  136. package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
  137. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
  138. package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
  139. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
  140. package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
  141. package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
  142. package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
  143. package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
  144. package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
  145. package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
  146. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
  147. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +49 -5
  148. package/core/shared/scripts/doflow/bin/doflow-run +152 -34
  149. package/core/shared/skills/do/SKILL.md +14 -12
  150. package/core/shared/skills/do/references/advice_calls.md +26 -0
  151. package/core/shared/skills/do/references/pm_routing.md +1 -2
  152. package/core/shared/skills/do/references/program_mode.md +31 -0
  153. package/core/shared/skills/do-brainstorm/SKILL.md +45 -97
  154. package/core/shared/skills/do-brainstorm/references/handoff_branches.md +36 -0
  155. package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
  156. package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
  157. package/core/shared/skills/do-code-review/SKILL.md +48 -148
  158. package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
  159. package/core/shared/skills/do-code-review/references/tools.md +90 -0
  160. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
  161. package/core/shared/skills/do-design/SKILL.md +23 -20
  162. package/core/shared/skills/do-diagnose/SKILL.md +18 -6
  163. package/core/shared/skills/do-document/SKILL.md +12 -1
  164. package/core/shared/skills/do-document/references/deep_research.md +1 -2
  165. package/core/shared/skills/do-document/references/embedded-research.md +19 -7
  166. package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
  167. package/core/shared/skills/do-execute-plan/SKILL.md +19 -60
  168. package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
  169. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
  170. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +26 -1
  171. package/core/shared/skills/do-execute-plan/references/run_position.md +16 -2
  172. package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
  173. package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
  174. package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
  175. package/core/shared/skills/do-flow/SKILL.md +10 -11
  176. package/core/shared/skills/do-flow/references/task_classes.md +5 -5
  177. package/core/shared/skills/do-git/SKILL.md +4 -0
  178. package/core/shared/skills/do-implement/SKILL.md +13 -14
  179. package/core/shared/skills/do-plan/SKILL.md +34 -20
  180. package/core/shared/skills/do-test/SKILL.md +7 -4
  181. package/core/shared/templates/doflow/constitution-template.md +9 -3
  182. package/core/shared/templates/doflow/data-model-template.md +1 -1
  183. package/core/shared/templates/doflow/design-template.md +113 -16
  184. package/core/shared/templates/doflow/plan-template.md +11 -10
  185. package/core/shared/templates/doflow/question-log-template.md +14 -2
  186. package/core/shared/templates/doflow/requirement-template.md +1 -1
  187. package/core/shared/workflows/do-flow-chain.md +2 -0
  188. package/core/worker-evidence/antigravity/checks.json +14 -0
  189. package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
  190. package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
  191. package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
  192. package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
  193. package/core/worker-evidence/codex/checks.json +38 -0
  194. package/package.json +10 -6
  195. package/src/adapters/antigravity/index.js +143 -66
  196. package/src/adapters/claude/index.js +46 -5
  197. package/src/adapters/codex/agents.js +25 -15
  198. package/src/adapters/codex/hooks.js +39 -3
  199. package/src/adapters/codex/index.js +61 -13
  200. package/src/adapters/codex/native-projection.js +6 -2
  201. package/src/adapters/copilot/index.js +58 -23
  202. package/src/adapters/copy-tree.js +291 -46
  203. package/src/adapters/guidance-manifest.js +71 -0
  204. package/src/adapters/guidance-pointer.js +19 -0
  205. package/src/adapters/hook-commands.js +6 -10
  206. package/src/adapters/index.js +1 -0
  207. package/src/adapters/kiro/index.js +23 -12
  208. package/src/adapters/opencode/index.js +8 -8
  209. package/src/adapters/pi/hooks.js +2 -1
  210. package/src/adapters/pi/index.js +14 -7
  211. package/src/adapters/resolve-source.js +26 -2
  212. package/src/cli/commands/install.js +2 -1
  213. package/src/cli/commands/reconcile.js +53 -9
  214. package/src/cli/commands/remove.js +2 -2
  215. package/src/cli/commands/rollback.js +6 -3
  216. package/src/cli/commands/self-update.js +18 -9
  217. package/src/cli/commands/status.js +22 -3
  218. package/src/cli/commands/ui.js +99 -0
  219. package/src/cli/commands/update.js +2 -1
  220. package/src/cli/index.js +337 -32
  221. package/src/cli/runtime-commands.js +220 -60
  222. package/src/cli/shared.js +0 -2
  223. package/src/helper/git.js +1 -1
  224. package/src/helper/guardrails.js +1 -1
  225. package/src/helper/marker-merge.js +31 -13
  226. package/src/helper/package-ids.js +37 -0
  227. package/src/helper/semver.js +94 -0
  228. package/src/install/backup.js +105 -15
  229. package/src/install/context.js +1 -1
  230. package/src/install/targets.js +31 -16
  231. package/src/lifecycle/coverage.js +4 -16
  232. package/src/lifecycle/hook-tier.js +160 -0
  233. package/src/lifecycle/index.js +412 -78
  234. package/src/lifecycle/retired-harnesses.js +318 -0
  235. package/src/lifecycle/view.js +35 -15
  236. package/src/registry/index.js +551 -26
  237. package/src/registry/worker-ids.js +45 -0
  238. package/src/release/build-package.js +0 -3
  239. package/src/release/docs-blocks.js +472 -0
  240. package/src/release/preflight.js +425 -0
  241. package/src/release/rehearse.js +401 -0
  242. package/src/release/release-workflow.js +733 -0
  243. package/src/release/sync-plugin-versions.js +43 -7
  244. package/src/runtime/advice/bench-gate.js +25 -0
  245. package/src/runtime/advice/cli.js +59 -16
  246. package/src/runtime/advice/client.js +32 -9
  247. package/src/runtime/advice/config.js +98 -133
  248. package/src/runtime/advice/doctor.js +1 -1
  249. package/src/runtime/advice/elevation.js +97 -0
  250. package/src/runtime/advice/endpoint-guard.js +9 -3
  251. package/src/runtime/advice/mode.js +37 -0
  252. package/src/runtime/advice/record.js +18 -5
  253. package/src/runtime/advice/registry.js +4 -1
  254. package/src/runtime/advice/shadow-config.js +229 -0
  255. package/src/runtime/advice/shadow-dispatcher.js +276 -0
  256. package/src/runtime/brief-rules.js +81 -0
  257. package/src/runtime/brief-tools.js +111 -34
  258. package/src/runtime/candidate.js +20 -11
  259. package/src/runtime/capabilities/executor.js +450 -0
  260. package/src/runtime/capabilities/loopback.js +41 -0
  261. package/src/runtime/capabilities/sanitizer.js +88 -0
  262. package/src/runtime/capability-router.js +135 -3
  263. package/src/runtime/checkouts.js +73 -11
  264. package/src/runtime/claims.js +13 -7
  265. package/src/runtime/cli.js +196 -19
  266. package/src/runtime/config-home.js +42 -0
  267. package/src/runtime/context/arbitrate.js +767 -0
  268. package/src/runtime/context/delivery-store.js +4 -6
  269. package/src/runtime/context/emission-rules.js +118 -0
  270. package/src/runtime/context/identity.js +227 -0
  271. package/src/runtime/context/pointer.js +67 -12
  272. package/src/runtime/context/primary-command.js +117 -0
  273. package/src/runtime/context/primary.js +344 -0
  274. package/src/runtime/context/summary-store.js +655 -0
  275. package/src/runtime/context-pack.js +158 -79
  276. package/src/runtime/decision-register.js +13 -4
  277. package/src/runtime/dispatch/admission.js +392 -0
  278. package/src/runtime/dispatch/attempt-end.js +274 -0
  279. package/src/runtime/dispatch/command.js +628 -0
  280. package/src/runtime/dispatch/controls.js +904 -0
  281. package/src/runtime/dispatch/envelope.js +276 -0
  282. package/src/runtime/dispatch/grants.js +310 -0
  283. package/src/runtime/dispatch/integrate.js +617 -0
  284. package/src/runtime/dispatch/loop.js +1835 -0
  285. package/src/runtime/dispatch/store.js +352 -0
  286. package/src/runtime/dispatch/verify-run.js +201 -0
  287. package/src/runtime/evidence-ledger.js +52 -7
  288. package/src/runtime/failure/capture.js +3 -1
  289. package/src/runtime/failure/cli.js +25 -9
  290. package/src/runtime/failure/home.js +57 -30
  291. package/src/runtime/failure/store.js +7 -2
  292. package/src/runtime/feature-pointer.js +174 -0
  293. package/src/runtime/feature-resolve.js +13 -2
  294. package/src/runtime/fleet/command.js +77 -0
  295. package/src/runtime/fleet/projects.js +178 -0
  296. package/src/runtime/fleet/tree.js +383 -0
  297. package/src/runtime/freshness.js +33 -3
  298. package/src/runtime/git-memo.js +46 -0
  299. package/src/runtime/guidance/ablation.js +427 -0
  300. package/src/runtime/health.js +624 -18
  301. package/src/runtime/history-compactor.js +13 -3
  302. package/src/runtime/implementation-gate.js +281 -26
  303. package/src/runtime/intake/engine.js +677 -0
  304. package/src/runtime/intake/index.js +136 -0
  305. package/src/runtime/intake/manifest.js +140 -0
  306. package/src/runtime/intake/taxonomy.js +206 -0
  307. package/src/runtime/inventory/coverage.js +1 -1
  308. package/src/runtime/inventory/index.js +1 -1
  309. package/src/runtime/inventory/precedence.js +2 -2
  310. package/src/runtime/inventory/siblings.js +6 -4
  311. package/src/runtime/knowledge/code-corpus.js +277 -0
  312. package/src/runtime/knowledge/code-lexical.js +130 -0
  313. package/src/runtime/knowledge/code-retrieval.js +307 -0
  314. package/src/runtime/knowledge/code-validation.js +106 -0
  315. package/src/runtime/knowledge/gp3-gate.js +74 -0
  316. package/src/runtime/knowledge/graph-adapter.js +288 -0
  317. package/src/runtime/knowledge/graph-fallback.js +394 -0
  318. package/src/runtime/knowledge/hybrid.js +136 -8
  319. package/src/runtime/knowledge/retrieval.js +34 -1
  320. package/src/runtime/knowledge/rtk-compress.js +77 -0
  321. package/src/runtime/knowledge/semble-bridge.py +106 -0
  322. package/src/runtime/knowledge/semble-lifecycle.js +114 -0
  323. package/src/runtime/knowledge/semble-provider.js +365 -0
  324. package/src/runtime/lifecycle/cli.js +88 -10
  325. package/src/runtime/lifecycle/event-store.js +8 -6
  326. package/src/runtime/lifecycle/followup.js +38 -7
  327. package/src/runtime/lifecycle/overview.js +26 -2
  328. package/src/runtime/lifecycle/report-store.js +8 -10
  329. package/src/runtime/lifecycle/retention.js +95 -31
  330. package/src/runtime/lifecycle/root.js +9 -1
  331. package/src/runtime/lifecycle/status.js +34 -17
  332. package/src/runtime/lifecycle/store-upkeep.js +56 -7
  333. package/src/runtime/mask.js +134 -7
  334. package/src/runtime/mcp-consultations.js +40 -6
  335. package/src/runtime/model-router.js +79 -7
  336. package/src/runtime/models/catalogue.js +191 -0
  337. package/src/runtime/models/command.js +153 -0
  338. package/src/runtime/off-words.js +12 -0
  339. package/src/runtime/outcome.js +2 -2
  340. package/src/runtime/packages/command.js +1009 -0
  341. package/src/runtime/packages/contributions.js +116 -0
  342. package/src/runtime/packages/digest.js +132 -0
  343. package/src/runtime/packages/fetch.js +182 -0
  344. package/src/runtime/packages/grants.js +192 -0
  345. package/src/runtime/packages/index-file.js +134 -0
  346. package/src/runtime/packages/instruction.js +90 -0
  347. package/src/runtime/packages/manifest.js +331 -0
  348. package/src/runtime/packages/points.js +487 -0
  349. package/src/runtime/packages/programs.js +216 -0
  350. package/src/runtime/packages/scaffold.js +277 -0
  351. package/src/runtime/packages/source.js +90 -0
  352. package/src/runtime/packages/state.js +164 -0
  353. package/src/runtime/packages/store.js +449 -0
  354. package/src/runtime/packages/tar.js +106 -0
  355. package/src/runtime/packages/view.js +406 -0
  356. package/src/runtime/plan-check.js +59 -0
  357. package/src/runtime/plan-content.js +324 -0
  358. package/src/runtime/policy-init.js +118 -0
  359. package/src/runtime/profiles/doctor.js +96 -0
  360. package/src/runtime/profiles/resolve.js +244 -0
  361. package/src/runtime/profiles/rollback.js +254 -0
  362. package/src/runtime/profiles/sampler.js +41 -0
  363. package/src/runtime/readiness-record.js +16 -11
  364. package/src/runtime/readiness.js +46 -5
  365. package/src/runtime/research-request.js +50 -25
  366. package/src/runtime/retrieval-plan.js +10 -30
  367. package/src/runtime/retrieval-record.js +75 -5
  368. package/src/runtime/review/command.js +246 -0
  369. package/src/runtime/review/dominance.js +68 -0
  370. package/src/runtime/review/findings.js +434 -0
  371. package/src/runtime/review/identity.js +255 -0
  372. package/src/runtime/review/protocol-command.js +109 -0
  373. package/src/runtime/review/protocols.js +405 -0
  374. package/src/runtime/review/resolve-protocol.js +302 -0
  375. package/src/runtime/review/start.js +530 -0
  376. package/src/runtime/roadmap/attendance.js +137 -0
  377. package/src/runtime/roadmap/facts.js +479 -0
  378. package/src/runtime/roadmap/gates.js +273 -0
  379. package/src/runtime/roadmap/loop.js +1719 -0
  380. package/src/runtime/roadmap/merge.js +390 -0
  381. package/src/runtime/roadmap/rows.js +1122 -0
  382. package/src/runtime/roadmap/seed.js +1063 -0
  383. package/src/runtime/roadmap/worktree-cleanup.js +147 -0
  384. package/src/runtime/rules-report.js +336 -0
  385. package/src/runtime/scaffold/artifacts.js +60 -9
  386. package/src/runtime/scaffold/generate.js +21 -9
  387. package/src/runtime/settings/autopilot.js +106 -0
  388. package/src/runtime/settings/cli.js +280 -0
  389. package/src/runtime/settings/config-write.js +314 -0
  390. package/src/runtime/settings/files.js +271 -0
  391. package/src/runtime/settings/legacy.js +154 -0
  392. package/src/runtime/settings/lexical.js +56 -0
  393. package/src/runtime/settings/prepared-run.js +269 -0
  394. package/src/runtime/settings/project-layers.js +118 -0
  395. package/src/runtime/settings/refs.js +288 -0
  396. package/src/runtime/settings/registry.js +553 -0
  397. package/src/runtime/settings/resolve.js +713 -0
  398. package/src/runtime/settings/shared.js +37 -0
  399. package/src/runtime/settings/worker-billing.js +107 -0
  400. package/src/runtime/settings/write.js +269 -0
  401. package/src/runtime/slot-command.js +78 -0
  402. package/src/runtime/slots.js +671 -0
  403. package/src/runtime/source-version.js +1 -0
  404. package/src/runtime/state-root.js +217 -0
  405. package/src/runtime/storage/cli.js +12 -5
  406. package/src/runtime/storage/engine.js +9 -2
  407. package/src/runtime/storage/registry.js +14 -1
  408. package/src/runtime/storage/roots.js +66 -16
  409. package/src/runtime/storage/rules.js +82 -10
  410. package/src/runtime/storage/upkeep.js +10 -2
  411. package/src/runtime/storage/work-status.js +245 -26
  412. package/src/runtime/task-attempts.js +589 -69
  413. package/src/runtime/task-classifier.js +85 -14
  414. package/src/runtime/task-graph.js +373 -0
  415. package/src/runtime/task-run.js +778 -0
  416. package/src/runtime/task-scope.js +176 -55
  417. package/src/runtime/task-sources.js +147 -0
  418. package/src/runtime/task-state.js +373 -64
  419. package/src/runtime/team/admission.js +301 -0
  420. package/src/runtime/team/envelope.js +324 -0
  421. package/src/runtime/team/review-guard.js +156 -0
  422. package/src/runtime/trace/analyze.js +427 -0
  423. package/src/runtime/trace/baseline.js +770 -0
  424. package/src/runtime/trace/ledger.js +63 -140
  425. package/src/runtime/trace/otlp-export.js +568 -0
  426. package/src/runtime/trace/otlp-map.js +481 -0
  427. package/src/runtime/trace/spans.js +745 -0
  428. package/src/runtime/trace/telemetry.js +225 -0
  429. package/src/runtime/trace/views.js +1 -0
  430. package/src/runtime/transcripts/command.js +98 -0
  431. package/src/runtime/transcripts/cursor.js +326 -0
  432. package/src/runtime/transcripts/read.js +126 -0
  433. package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
  434. package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
  435. package/src/runtime/transcripts/readers/copilot-events.js +90 -0
  436. package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
  437. package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
  438. package/src/runtime/transcripts/registry.js +161 -0
  439. package/src/runtime/transcripts/stats.js +161 -0
  440. package/src/runtime/verb-view.js +267 -0
  441. package/src/runtime/verification/check-key.js +628 -0
  442. package/src/runtime/verification/contract-runner.js +546 -11
  443. package/src/runtime/verification/engine.js +499 -54
  444. package/src/runtime/verification/impact.js +617 -0
  445. package/src/runtime/verification/inflight.js +205 -0
  446. package/src/runtime/verification/registry.js +176 -0
  447. package/src/runtime/verification/reuse.js +184 -0
  448. package/src/runtime/verification/telemetry-emit.js +254 -0
  449. package/src/runtime/verification/test-selection.js +67 -7
  450. package/src/runtime/worker/active.js +90 -0
  451. package/src/runtime/worker/cancel.js +222 -0
  452. package/src/runtime/worker/catalogue.js +122 -0
  453. package/src/runtime/worker/command.js +677 -0
  454. package/src/runtime/worker/evidence.js +288 -0
  455. package/src/runtime/worker/launch.js +256 -0
  456. package/src/runtime/worker/models.js +137 -0
  457. package/src/runtime/worker/parsers.js +218 -0
  458. package/src/runtime/worker/probes/index.js +706 -0
  459. package/src/runtime/worker/process-tree.js +415 -0
  460. package/src/runtime/worker/quota.js +43 -0
  461. package/src/runtime/worker/readiness.js +713 -0
  462. package/src/runtime/worker/run-store.js +166 -0
  463. package/src/runtime/worker/supervisor.js +541 -0
  464. package/src/runtime/worker/worktree-check.js +252 -0
  465. package/src/runtime/workflow-engine.js +5 -1
  466. package/src/runtime/workflow-orchestrator.js +610 -67
  467. package/src/runtime/worktree.js +149 -22
  468. package/src/state/index.js +1 -1
  469. package/src/state/lockfile.js +64 -10
  470. package/src/state/run-lock.js +1 -1
  471. package/types/node-commonjs.d.ts +106 -7
  472. package/core/harnesses/claude/hooks/pre-bash-guard.sh +0 -10
  473. package/core/harnesses/codex/hooks/pre-bash-guard.sh +0 -10
  474. package/core/harnesses/gemini/hooks/hooks.json +0 -77
  475. package/core/harnesses/gemini/hooks/lib.sh +0 -302
  476. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -10
  477. package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
  478. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -10
  479. package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
  480. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -10
  481. package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
  482. package/core/harnesses/gemini/hooks/session-end.sh +0 -5
  483. package/core/harnesses/gemini/hooks/session-start.sh +0 -7
  484. package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
  485. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +0 -24
  486. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +0 -91
  487. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +0 -378
  488. package/core/shared/guidance/FLAGS.md +0 -25
  489. package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
  490. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
  491. package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
  492. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
  493. package/src/adapters/gemini/hooks.js +0 -251
  494. package/src/adapters/gemini/index.js +0 -429
@@ -0,0 +1,51 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "sessionStart": [
5
+ {
6
+ "type": "command",
7
+ "bash": "bash \"$(root=$(git rev-parse --show-toplevel 2>/dev/null) && [ -f \"$root/.github/hooks/doflow-session-start.sh\" ] && printf '%s/.github/hooks/doflow-session-start.sh' \"$root\" || printf '%s/hooks/doflow-session-start.sh' \"${COPILOT_HOME:-$HOME/.copilot}\")\"",
8
+ "cwd": ".",
9
+ "timeoutSec": 10
10
+ }
11
+ ],
12
+ "preToolUse": [
13
+ {
14
+ "type": "command",
15
+ "bash": "bash \"$(root=$(git rev-parse --show-toplevel 2>/dev/null) && [ -f \"$root/.github/hooks/doflow-pre-implement-gate.sh\" ] && printf '%s/.github/hooks/doflow-pre-implement-gate.sh' \"$root\" || printf '%s/hooks/doflow-pre-implement-gate.sh' \"${COPILOT_HOME:-$HOME/.copilot}\")\"",
16
+ "cwd": ".",
17
+ "timeoutSec": 20
18
+ },
19
+ {
20
+ "type": "command",
21
+ "bash": "bash \"$(root=$(git rev-parse --show-toplevel 2>/dev/null) && [ -f \"$root/.github/hooks/doflow-mcp-tool-guard.sh\" ] && printf '%s/.github/hooks/doflow-mcp-tool-guard.sh' \"$root\" || printf '%s/hooks/doflow-mcp-tool-guard.sh' \"${COPILOT_HOME:-$HOME/.copilot}\")\"",
22
+ "cwd": ".",
23
+ "timeoutSec": 20
24
+ }
25
+ ],
26
+ "agentStop": [
27
+ {
28
+ "type": "command",
29
+ "bash": "bash \"$(root=$(git rev-parse --show-toplevel 2>/dev/null) && [ -f \"$root/.github/hooks/doflow-stop-check.sh\" ] && printf '%s/.github/hooks/doflow-stop-check.sh' \"$root\" || printf '%s/hooks/doflow-stop-check.sh' \"${COPILOT_HOME:-$HOME/.copilot}\")\"",
30
+ "cwd": ".",
31
+ "timeoutSec": 30
32
+ }
33
+ ],
34
+ "subagentStart": [
35
+ {
36
+ "type": "command",
37
+ "bash": "bash \"$(root=$(git rev-parse --show-toplevel 2>/dev/null) && [ -f \"$root/.github/hooks/doflow-subagent-start.sh\" ] && printf '%s/.github/hooks/doflow-subagent-start.sh' \"$root\" || printf '%s/hooks/doflow-subagent-start.sh' \"${COPILOT_HOME:-$HOME/.copilot}\")\"",
38
+ "cwd": ".",
39
+ "timeoutSec": 10
40
+ }
41
+ ],
42
+ "subagentStop": [
43
+ {
44
+ "type": "command",
45
+ "bash": "bash \"$(root=$(git rev-parse --show-toplevel 2>/dev/null) && [ -f \"$root/.github/hooks/doflow-subagent-stop.sh\" ] && printf '%s/.github/hooks/doflow-subagent-stop.sh' \"$root\" || printf '%s/hooks/doflow-subagent-stop.sh' \"${COPILOT_HOME:-$HOME/.copilot}\")\"",
46
+ "cwd": ".",
47
+ "timeoutSec": 10
48
+ }
49
+ ]
50
+ }
51
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "doflow",
3
3
  "description": "DoFlow main session: spec-driven delivery with lifecycle hooks and specialist dispatch",
4
- "prompt": "You are the DoFlow main session. Follow the DoFlow steering files under .kiro/steering (principles, rules, the spec-driven chain) and the skills under .kiro/skills. Dispatch specialist work by role to core-implementer, quality-guardian, spec-analyst, system-architect or research-writer, and keep decisions, verification and records in this session.\n",
4
+ "prompt": "You are the DoFlow main session. Follow the DoFlow steering files under .kiro/steering (principles, rules, the spec-driven chain) and the skills under .kiro/skills. Dispatch specialist work by role to core-implementer, delivery-lead, quality-guardian, reviewer, spec-analyst, system-architect or research-writer, and keep decisions, verification and records in this session.\n",
5
5
  "tools": [
6
6
  "*"
7
7
  ],
@@ -16,16 +16,6 @@
16
16
  },
17
17
  "timeout": 10
18
18
  },
19
- {
20
- "name": "doflow-pre-bash-guard",
21
- "trigger": "preToolUse",
22
- "matcher": "shell",
23
- "action": {
24
- "type": "command",
25
- "command": "bash \"$(root=$(git rev-parse --show-toplevel 2>/dev/null) && [ -f \"$root/.kiro/hooks/pre-bash-guard.sh\" ] && printf '%s/.kiro/hooks/pre-bash-guard.sh' \"$root\" || printf '%s/.kiro/hooks/pre-bash-guard.sh' \"$HOME\")\""
26
- },
27
- "timeout": 10
28
- },
29
19
  {
30
20
  "name": "doflow-mcp-tool-guard",
31
21
  "trigger": "preToolUse",
@@ -19,16 +19,6 @@
19
19
  },
20
20
  "enabled": true
21
21
  },
22
- {
23
- "name": "doflow-pre-bash-guard",
24
- "trigger": "PreToolUse",
25
- "matcher": "shell",
26
- "action": {
27
- "type": "command",
28
- "command": "bash \"$(root=$(git rev-parse --show-toplevel 2>/dev/null) && [ -f \"$root/.kiro/hooks/pre-bash-guard.sh\" ] && printf '%s/.kiro/hooks/pre-bash-guard.sh' \"$root\" || printf '%s/.kiro/hooks/pre-bash-guard.sh' \"$HOME\")\""
29
- },
30
- "enabled": true
31
- },
32
22
  {
33
23
  "name": "doflow-mcp-tool-guard",
34
24
  "trigger": "PreToolUse",
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
2
3
  # lib.sh — shared constants and helpers for session lifecycle hooks
3
4
  #
4
5
  # Usage: source "$(dirname "$0")/lib.sh"
@@ -17,13 +18,30 @@ set -euo pipefail
17
18
 
18
19
  # ── State directories ────────────────────────────────────────────────────────
19
20
 
20
- # XDG-compliant, agent-agnostic store shared by Claude Code, Codex, Gemini, etc.
21
- DOFLOW_HOME="${XDG_CONFIG_HOME:-$HOME/.config}/doflow"
22
- STATE_DIR="$DOFLOW_HOME/session-env"
23
- SESSION_DIR="$STATE_DIR/sessions"
24
- PROJECTS_DIR="$STATE_DIR/projects"
21
+ # XDG-compliant, agent-agnostic store shared by every harness DoFlow supports, under the config home
22
+ # (doflow_config_home: an absolute XDG_CONFIG_HOME, else an absolute HOME + /.config, else none). With
23
+ # no config home every state path below is empty, sourcing this file still never exits, and each state
24
+ # function returns 0 at once: session work is skipped and a guard reaches its own decision (086 IC-010).
25
+ # BEGIN doflow-config-home v1 (rule: src/runtime/config-home.js; checked by test/guards/settings.test.js)
26
+ doflow_config_home() {
27
+ DOFLOW_HOME=""
28
+ case "${XDG_CONFIG_HOME:-}" in
29
+ /*) DOFLOW_HOME="${XDG_CONFIG_HOME}/doflow"; return 0 ;;
30
+ [A-Za-z]:[\\/]*) case "${OSTYPE:-}" in msys*|cygwin*|win32*) DOFLOW_HOME="${XDG_CONFIG_HOME}/doflow"; return 0 ;; esac ;;
31
+ esac
32
+ case "${HOME:-}" in
33
+ /*) DOFLOW_HOME="${HOME}/.config/doflow" ;;
34
+ [A-Za-z]:[\\/]*) case "${OSTYPE:-}" in msys*|cygwin*|win32*) DOFLOW_HOME="${HOME}/.config/doflow" ;; esac ;;
35
+ esac
36
+ return 0
37
+ }
38
+ # END doflow-config-home v1
39
+ doflow_config_home
40
+ STATE_DIR="${DOFLOW_HOME:+$DOFLOW_HOME/session-env}"
41
+ SESSION_DIR="${STATE_DIR:+$STATE_DIR/sessions}"
42
+ PROJECTS_DIR="${STATE_DIR:+$STATE_DIR/projects}"
25
43
  # shellcheck disable=SC2034 # used by session-start.sh and session-end.sh which source this file
26
- SESSIONS_LOG="$DOFLOW_HOME/sessions.log"
44
+ SESSIONS_LOG="${DOFLOW_HOME:+$DOFLOW_HOME/sessions.log}"
27
45
 
28
46
  # Identifies which agent is running. Override via env var for non-Claude agents.
29
47
  export DOFLOW_AGENT="${DOFLOW_AGENT:-unknown}"
@@ -246,6 +264,7 @@ cwd_hash() {
246
264
  # Safe to call multiple times (mkdir -p is idempotent).
247
265
  ensure_session_dir() {
248
266
  local session_id="$1"
267
+ [ -n "$SESSION_DIR" ] || return 0
249
268
  mkdir -p "$SESSION_DIR/$session_id"
250
269
  echo "$SESSION_DIR/$session_id"
251
270
  }
@@ -255,6 +274,7 @@ ensure_session_dir() {
255
274
  ensure_project_dir() {
256
275
  local cwd="$1"
257
276
  local hash
277
+ [ -n "$PROJECTS_DIR" ] || return 0
258
278
  hash=$(cwd_hash "$cwd")
259
279
  mkdir -p "$PROJECTS_DIR/$hash"
260
280
  echo "$PROJECTS_DIR/$hash"
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
2
3
  # Kiro front door: mcp-tool-guard through the shared lifecycle bridge.
3
4
  set -euo pipefail
4
5
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
@@ -10,11 +11,15 @@ payload=$(kiro_bridge_payload <<<"$raw")
10
11
  event="PreToolUse"
11
12
  if command -v jq >/dev/null 2>&1; then event=$(printf '%s' "$raw" | jq -r '.hook_event_name // "PreToolUse"' 2>/dev/null) || event="PreToolUse"; fi
12
13
  bridge="$here/../../.doflow/shared/hooks/bridge/bridge.sh"
13
- if [ ! -f "$bridge" ]; then
14
+ # D1: a missing bridge allows with a warning on stderr. Only strict-1, a person's opt-in, blocks.
15
+ bridge_missing=0
16
+ [ -f "$bridge" ] || bridge_missing=1
17
+ if [ "$bridge_missing" -eq 0 ]; then . "$bridge" 2>/dev/null || bridge_missing=1; fi
18
+ if [ "$bridge_missing" -eq 1 ]; then
14
19
  printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2
15
- exit 2
20
+ if [ "${DOFLOW_FAULT_PROFILE:-}" = strict-1 ]; then exit 2; fi
21
+ exit 0
16
22
  fi
17
- . "$bridge" 2>/dev/null || { printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2; exit 2; }
18
23
  if doflow_bridge kiro "$event" mcp-tool-guard <<<"$payload"; then
19
24
  status=0
20
25
  else
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
2
3
  # Kiro front door: pre-implementation-gate through the shared lifecycle bridge.
3
4
  set -euo pipefail
4
5
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
@@ -10,11 +11,15 @@ payload=$(kiro_bridge_payload <<<"$raw")
10
11
  event="PreToolUse"
11
12
  if command -v jq >/dev/null 2>&1; then event=$(printf '%s' "$raw" | jq -r '.hook_event_name // "PreToolUse"' 2>/dev/null) || event="PreToolUse"; fi
12
13
  bridge="$here/../../.doflow/shared/hooks/bridge/bridge.sh"
13
- if [ ! -f "$bridge" ]; then
14
+ # D1: a missing bridge allows with a warning on stderr. Only strict-1, a person's opt-in, blocks.
15
+ bridge_missing=0
16
+ [ -f "$bridge" ] || bridge_missing=1
17
+ if [ "$bridge_missing" -eq 0 ]; then . "$bridge" 2>/dev/null || bridge_missing=1; fi
18
+ if [ "$bridge_missing" -eq 1 ]; then
14
19
  printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2
15
- exit 2
20
+ if [ "${DOFLOW_FAULT_PROFILE:-}" = strict-1 ]; then exit 2; fi
21
+ exit 0
16
22
  fi
17
- . "$bridge" 2>/dev/null || { printf '%s\n' '[doflow] shared hooks lack the bridge; run: doflow update -t kiro' >&2; exit 2; }
18
23
  if doflow_bridge kiro "$event" pre-implementation-gate <<<"$payload"; then
19
24
  status=0
20
25
  else
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
2
3
  # Kiro front door: session-context through the shared lifecycle bridge.
3
4
  set -euo pipefail
4
5
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
2
3
  # Kiro Stop front door: translate the native payload, then render the bridge verdict for its engine.
3
4
  set -uo pipefail
4
5
  export DOFLOW_AGENT="${DOFLOW_AGENT:-kiro}"
@@ -6,7 +6,6 @@ import { fileURLToPath } from 'node:url';
6
6
  const BRIDGE = new URL('../../shared/hooks/bridge/bridge.sh', import.meta.url);
7
7
  const ROUTES = [
8
8
  { tools: ['edit', 'write'], policy: 'pre-implementation-gate' },
9
- { tools: ['bash'], policy: 'pre-bash-guard' },
10
9
  ];
11
10
  const LIMIT = 1024 * 1024;
12
11
  const TIMEOUT_MS = 5000;
@@ -136,7 +135,16 @@ export default function (pi) {
136
135
  if (profile !== 'compat-1' && profile !== 'strict-1') captureFailure(policy, 'fault-profile-unknown');
137
136
  if (!existsSync(BRIDGE)) {
138
137
  captureFailure(policy, 'bridge-missing');
139
- return { block: true, reason: '[doflow] shared hooks lack the bridge; run: doflow update -t pi' };
138
+ // D1: a missing bridge allows (the failure is recorded for doctor); only strict-1, a person's opt-in, blocks.
139
+ if (profile === 'strict-1') return { block: true, reason: '[doflow] shared hooks lack the bridge; run: doflow update -t pi' };
140
+ return undefined;
141
+ }
142
+ let model;
143
+ try {
144
+ const modelId = ctx.model?.id;
145
+ if (typeof modelId === 'string' && modelId.length > 0) model = modelId;
146
+ } catch {
147
+ // A model getter must not prevent the tool call from reaching the bridge.
140
148
  }
141
149
  const payload = JSON.stringify({
142
150
  type: event.type,
@@ -146,6 +154,7 @@ export default function (pi) {
146
154
  input: event.input,
147
155
  cwd: ctx.cwd,
148
156
  sessionId: ctx.sessionManager?.getSessionId?.() ?? null,
157
+ ...(model ? { model } : {}),
149
158
  });
150
159
  if (Buffer.byteLength(payload) > LIMIT) throw Object.assign(new Error('bridge input exceeded limit'), { failurePoint: 'bridge-input-limit' });
151
160
  return await bridgeCall(policy, payload, ctx);
@@ -22,7 +22,6 @@ tool's official docs (cross-checked against tool source where docs were incomple
22
22
  |---|---|---|
23
23
  | Claude Code | `PreToolUse` | `tool_name` Edit/Write/MultiEdit; `tool_input.file_path` |
24
24
  | Codex | `PreToolUse` | `apply_patch` carries paths inside a unified diff under `tool_input.command` — the ONE decoder that must parse patch text |
25
- | Gemini CLI | `BeforeTool` | also offers `BeforeToolSelection` (pre-selection restriction), which the gate does not use |
26
25
  | GitHub Copilot | `preToolUse` | camelCase event names; `permissionRequest` is CLI-only, not fired in the cloud agent |
27
26
  | OpenCode | `tool.execute.before` | a pluggable hook method, not a sub-event of the generic `event` hook |
28
27
  | Pi | `tool_call` | The live-observed `cli-extension` pre-implementation gate row blocks. Project-interactive and user-interactive rows remain unknown; interactive loading and project-trust behavior were not observed. `tool_execution_start` is observation-only |
@@ -37,7 +36,7 @@ them through), but sending nothing for a non-edit tool is equally correct and ch
37
36
  ## Version and mixed-install rules
38
37
 
39
38
  - A missing envelope or version, empty or non-object input, or a missing `contract.sh` is out of
40
- step. The gate, bash guard and MCP guard deny with `DoFlow hooks out of step; run: doflow update
39
+ step. The gate and MCP guard deny with `DoFlow hooks out of step; run: doflow update
41
40
  -t <harness>`; Stop and context policies exit silently, except the prompt hook emits its `{}`
42
41
  no-op. Other envelope versions are unsupported and policies evaluate nothing.
43
42
  - If a door cannot load `bridge/bridge.sh`, it renders its fixed native out-of-step response. The
@@ -20,7 +20,7 @@
20
20
  *
21
21
  * SessionStart and PostToolUse have no dedicated Antigravity-native shim in
22
22
  * src/adapters/antigravity/index.js's live projection. No Phase A canonical policy owns PostToolUse today (only
23
- * session-context, pre-implementation-gate, mcp-tool-guard, stop-check, pre-bash-guard exist),
23
+ * session-context, pre-implementation-gate, mcp-tool-guard, stop-check exist),
24
24
  * so its native shape is an ack passthrough either way.
25
25
  */
26
26
 
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env bash
2
+ case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
2
3
  # Shared lifecycle bridge. Sourcing defines functions only; it sets no shell options or traps.
3
- case ${BASH_SOURCE[0]} in */*) _DOFLOW_BRIDGE_DIR=${BASH_SOURCE[0]%/*} ;; *) _DOFLOW_BRIDGE_DIR=. ;; esac
4
+ _DOFLOW_SRC=${BASH_SOURCE[0]//\\//}; case $_DOFLOW_SRC in */*) _DOFLOW_BRIDGE_DIR=${_DOFLOW_SRC%/*} ;; *) _DOFLOW_BRIDGE_DIR=. ;; esac
4
5
 
5
6
  doflow_bridge_failure() {
6
7
  local policy="$1" point="$2"
@@ -41,64 +42,151 @@ doflow_bridge_effect() {
41
42
  profile=compat-1; doflow_bridge_failure "$policy" fault-profile-unknown
42
43
  fi
43
44
  DF_BRIDGE_PROFILE="$profile"
44
- case "$policy" in pre-implementation-gate|pre-bash-guard|mcp-tool-guard|stop-check) block=1;; esac
45
+ case "$policy" in pre-implementation-gate|mcp-tool-guard|stop-check) block=1;; esac
45
46
  DF_BRIDGE_EFFECT=proceed
46
47
  if [ "$outcome" = deny ]; then DF_BRIDGE_EFFECT=block
47
48
  elif [ "$profile" = strict-1 ] && [ "$block" -eq 1 ] && [ "$policy" != stop-check ] && { [ "$outcome" = error ] || [ "$outcome" = unsupported ] || [ "$DF_BRIDGE_CODE" = bridge-spawn ] || [ "$DF_BRIDGE_CODE" = envelope-encode ]; }; then DF_BRIDGE_EFFECT=block
48
- elif [ "$outcome" = error ] && [ "$DF_BRIDGE_CODE" != bridge-spawn ] && [ -n "$DF_BRIDGE_POINT" ] && [ "$profile" = compat-1 ]; then
49
- case "$harness:$event" in
50
- claude:PreToolUse|codex:PreToolUse|gemini:BeforeTool|pi:tool_call) DF_BRIDGE_EFFECT=block ;;
51
- antigravity:PreToolUse|antigravity:Stop) case "$DF_BRIDGE_CODE" in signal-*) DF_BRIDGE_EFFECT=proceed;; *) DF_BRIDGE_EFFECT=block;; esac ;;
52
- kiro:PreToolUse) [ "$DF_BRIDGE_CODE" = exit-2-unmarked ] && DF_BRIDGE_EFFECT=block ;;
53
- claude:Stop) [ "$DF_BRIDGE_CODE" = exit-2-unmarked ] && DF_BRIDGE_EFFECT=block ;;
54
- codex:Stop|codex:stop|kiro:Stop|kiro:stop) [ "$DF_BRIDGE_CODE" = exit-2-unmarked ] && DF_BRIDGE_EFFECT=block || DF_BRIDGE_EFFECT=proceed ;;
55
- esac
56
49
  fi
50
+ # D1 (advise-only hooks): under compat-1 a faulting policy never blocks, on any harness. Only a policy
51
+ # that answered deny (mcp-tool-guard blocked-pattern) blocks, and strict-1, a person's opt-in, blocks
52
+ # on a fault of a blocking policy (above).
57
53
  }
58
54
 
59
55
  doflow_bridge_drops_tool_streams() {
60
56
  case "$1" in
61
- pre-implementation-gate|pre-bash-guard|mcp-tool-guard) ;;
57
+ pre-implementation-gate|mcp-tool-guard) ;;
62
58
  *) return 1 ;;
63
59
  esac
64
60
  case "$2:$3" in
65
- claude:PreToolUse|codex:PreToolUse|gemini:BeforeTool|kiro:PreToolUse|antigravity:PreToolUse|antigravity:Stop|pi:tool_call) return 0 ;;
61
+ claude:PreToolUse|codex:PreToolUse|copilot:PreToolUse|kiro:PreToolUse|antigravity:PreToolUse|antigravity:Stop|pi:tool_call) return 0 ;;
66
62
  *) return 1 ;;
67
63
  esac
68
64
  }
69
65
 
70
66
  doflow_bridge_drops_tool_stderr() {
71
67
  case "$1:$2:$3" in
72
- pre-implementation-gate:kiro:PreToolUse|pre-bash-guard:kiro:PreToolUse|mcp-tool-guard:kiro:PreToolUse) return 1 ;;
68
+ pre-implementation-gate:kiro:PreToolUse|mcp-tool-guard:kiro:PreToolUse) return 1 ;;
73
69
  esac
74
70
  doflow_bridge_drops_tool_streams "$1" "$2" "$3"
75
71
  }
76
72
 
73
+ # One hook line (IC-004) for an allowlisted surface, from the encode tuple in DF_TUPLE, appended to
74
+ # <config>/state/runs/telemetry/<UTC date>.jsonl. Builtins only on the path that writes; every step
75
+ # returns 0, and nothing reaches stdout or stderr. Args: harness, normalised event, policy, and the
76
+ # policy's emit record (rider R1, user-prompt-submit only): its reason, byte count and digest are
77
+ # written only when each passes its pattern (a vocabulary member, digits, 8 lowercase hex or null),
78
+ # else all three are null, as they are on every other line.
79
+ doflow_bridge_hook_line() {
80
+ local d="" f="" day="" rest="" duration=null t1="" er=null eb=null eg=null r="" b="" g=""
81
+ [ "${DOFLOW_TELEMETRY:-}" != off ] || return 0
82
+ case "$DF_TUPLE" in ''|'{"dft":1}') return 0 ;; esac
83
+ case "$1:$3:$2" in
84
+ claude:user-prompt-submit:UserPromptSubmit|codex:user-prompt-submit:UserPromptSubmit) ;;
85
+ *) return 0 ;;
86
+ esac
87
+ if [ -n "${DOFLOW_CONFIG_DIR:-}" ]; then
88
+ d=$DOFLOW_CONFIG_DIR
89
+ else
90
+ d=${PWD:-}
91
+ case "$d" in /*) ;; *) return 0 ;; esac
92
+ while :; do
93
+ if [ -d "$d/.doflow" ]; then
94
+ case "$d/" in
95
+ */.doflow/*) ;;
96
+ *) d=${d%/}/.doflow; break ;;
97
+ esac
98
+ fi
99
+ [ -n "$d" ] && [ "$d" != "/" ] || return 0
100
+ d=${d%/*}
101
+ done
102
+ fi
103
+ [ -d "$d/state" ] || return 0
104
+ day=${DF_TUPLE:17:10}
105
+ case "$day" in [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ;; *) return 0 ;; esac
106
+ rest=${DF_TUPLE#\{\"dft\":1,\"date\":\"??????????\",}
107
+ case "$rest" in \"timestamp\":*\}) ;; *) return 0 ;; esac
108
+ if [ -n "$_df_t0" ]; then
109
+ t1=${EPOCHREALTIME:-}; t1=${t1/[.,]/}; _df_t0=${_df_t0/[.,]/}
110
+ case "$t1$_df_t0" in ''|*[!0-9]*) ;; *) duration=$(( (t1 - _df_t0) / 1000 )); [ "$duration" -ge 0 ] || duration=null ;; esac
111
+ fi
112
+ if [ "$3" = user-prompt-submit ] && [ -n "${4:-}" ]; then
113
+ r=${4#*\"reason\":\"}; r=${r%%\"*}
114
+ b=${4#*\"bytes\":}; b=${b%%[,\}]*}
115
+ g=${4#*\"digest\":}; g=${g%%[,\}]*}
116
+ case "$r" in
117
+ emit|refused:mandatory-over-budget|silent:already-bootstrapped|silent:unchanged|silent:no-home|fault:deps|fault:unit|fault:slot|fault:summary|fault:grant|fault:warning|fault:render) ;;
118
+ *) r="" ;;
119
+ esac
120
+ # Explicit character lists: a locale's collation can put capitals inside a range such as [a-f].
121
+ case "$b" in ''|*[!0123456789]*|0?*|???????????*) b="" ;; esac
122
+ case "$g" in
123
+ null|\"[0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef]\") ;;
124
+ *) g="" ;;
125
+ esac
126
+ if [ -n "$r" ] && [ -n "$b" ] && [ -n "$g" ]; then er=\"$r\"; eb=$b; eg=$g; fi
127
+ fi
128
+ [ -d "$d/state/runs/telemetry" ] || mkdir "$d/state/runs/telemetry" 2>/dev/null || return 0
129
+ f=$d/state/runs/telemetry/$day.jsonl
130
+ [ ! -e "$f" ] || [ -f "$f" ] || return 0
131
+ { printf '{"kind":"hook","harness":"%s","event":"%s","policy":"%s","verdict":"%s","duration_ms":%s,"emit_reason":%s,"emit_bytes":%s,"emit_digest":%s,%s\n' "$1" "$2" "$3" "$DF_BRIDGE_OUTCOME" "$duration" "$er" "$eb" "$eg" "$rest" >>"$f"; } 2>/dev/null || true
132
+ return 0
133
+ }
134
+
77
135
  doflow_bridge() {
78
- local harness="${1:-}" event="${2:-}" policy="${3:-}" response_event="" emit="native" payload="" encoded="" policy_path="" captured="" err="" code=0 policy_code=0 record="" reason="" decision_reason="" stdout="" status=0 decision="" line="" spawn_failed=0 encode_failed=0
136
+ local harness="${1:-}" event="${2:-}" policy="${3:-}" response_event="" emit="native" payload="" encoded="" policy_path="" captured="" err="" code=0 policy_code=0 record="" emit_record="" reason="" decision_reason="" stdout="" status=0 decision="" advice="" out_of_step=0 line="" spawn_failed=0 encode_failed=0 _df_t0=""
137
+ DF_TUPLE=""
138
+ if [ "${BASH_VERSINFO[0]:-0}" -ge 5 ] 2>/dev/null; then _df_t0=${EPOCHREALTIME:-}; fi
79
139
  . "$_DOFLOW_BRIDGE_DIR/respond.sh"
80
140
  doflow_bridge_native_event_var "$harness" "$event"; response_event=$DF_NE
81
141
  if [ "${4:-}" = --emit ]; then emit="${5:-native}"; fi
82
142
  payload="$(cat)"
83
143
  if command -v jq >/dev/null 2>&1; then
84
- encoded="$(printf '%s\n' "$payload" | DOFLOW_TASK_ID="${DOFLOW_TASK_ID:-}" DOFLOW_RUN_ID="${DOFLOW_RUN_ID:-}" DOFLOW_ATTEMPT="${DOFLOW_ATTEMPT:-}" DOFLOW_SESSION_ROLE="${DOFLOW_SESSION_ROLE:-}" jq -c --arg harness "$harness" --arg event "$event" --arg policy "$policy" --arg mode encode -f "$_DOFLOW_BRIDGE_DIR/envelope.jq" 2>/dev/null)" && {
144
+ encoded="$(printf '%s\n' "$payload" | DOFLOW_TASK_ID="${DOFLOW_TASK_ID:-}" DOFLOW_RUN_ID="${DOFLOW_RUN_ID:-}" DOFLOW_ATTEMPT="${DOFLOW_ATTEMPT:-}" DOFLOW_LINEAGE_ID="${DOFLOW_LINEAGE_ID:-}" DOFLOW_SESSION_ROLE="${DOFLOW_SESSION_ROLE:-}" DOFLOW_WORKTREE="${DOFLOW_WORKTREE:-}" jq -c --arg harness "$harness" --arg event "$event" --arg policy "$policy" --arg mode encode -f "$_DOFLOW_BRIDGE_DIR/envelope.jq" 2>/dev/null)" || encode_failed=1
145
+ # The telemetry tuple is the first line; without an envelope line after it there is no envelope.
146
+ case "$encoded" in
147
+ '{"dft"'*)
148
+ DF_TUPLE=${encoded%%$'\n'*}
149
+ case "$encoded" in *$'\n'*) encoded=${encoded#*$'\n'} ;; *) encoded="" ;; esac
150
+ ;;
151
+ esac
152
+ if [ "$encode_failed" -eq 0 ]; then
85
153
  case "$encoded" in \{*) payload="$encoded" ;; *) encode_failed=1 ;; esac
86
- } || { encode_failed=1; }
154
+ fi
87
155
  if [ "$encode_failed" -eq 1 ]; then
88
156
  encoded="$(jq -cn --arg harness "$harness" --arg event "$event" --arg policy "$policy" --arg mode minimal -f "$_DOFLOW_BRIDGE_DIR/envelope.jq" 2>/dev/null)" || encoded=""
89
157
  case "$encoded" in \{*) payload="$encoded" ;; *) payload="{\"doflow_event\":{\"version\":1,\"harness\":\"$harness\",\"event\":\"$event\",\"operation\":\"tool\"}}" ;; esac
90
158
  doflow_bridge_failure "$policy" envelope-encode
159
+ else
160
+ # Step observe-model (row 120 IC-005): an envelope whose identity names a model is recorded
161
+ # under the config home. It never changes the decision, the exit code or the streams.
162
+ case "$payload" in
163
+ *'"doflow_event":{'*'"model":"'*)
164
+ [ ! -f "$_DOFLOW_BRIDGE_DIR/observe-model.sh" ] || ( . "$_DOFLOW_BRIDGE_DIR/observe-model.sh" && doflow_observe_model "$harness" "$payload" ) >/dev/null 2>&1 </dev/null || true
165
+ ;;
166
+ esac
91
167
  fi
92
168
  else
93
169
  doflow_bridge_failure "$policy" dependency-missing:jq
94
170
  fi
95
171
  case "$policy" in
96
- pre-implementation-gate|pre-bash-guard|mcp-tool-guard|stop-check|session-context|user-prompt-submit|subagent-audit) ;;
172
+ pre-implementation-gate|mcp-tool-guard|stop-check|session-context|user-prompt-submit|subagent-audit) ;;
97
173
  *) spawn_failed=1 ;;
98
174
  esac
99
175
  policy_path="$_DOFLOW_BRIDGE_DIR/../policies/$policy.sh"
100
- if [ "$spawn_failed" -eq 1 ] || [ ! -f "$policy_path" ]; then
176
+ if [ "$spawn_failed" -eq 1 ] || [ ! -f "$policy_path" ] || [ ! -f "$_DOFLOW_BRIDGE_DIR/../policies/contract.sh" ]; then
101
177
  code=127; err=""; spawn_failed=1
178
+ # Without contract.sh no policy can run. The gate and the tool guard still say so: the one
179
+ # out-of-step line goes out as advice below, and the fault is recorded as bridge-spawn.
180
+ case "$policy" in
181
+ pre-implementation-gate|mcp-tool-guard)
182
+ if [ -f "$policy_path" ] && [ ! -f "$_DOFLOW_BRIDGE_DIR/../policies/contract.sh" ]; then
183
+ out_of_step="${DOFLOW_AGENT:-$harness}"
184
+ if [[ "$out_of_step" =~ ^[a-z]+$ ]]; then err="[$policy] DoFlow hooks out of step; run: doflow update -t $out_of_step"$'\n'
185
+ else err="[$policy] DoFlow hooks out of step; run: doflow update"$'\n'; fi
186
+ out_of_step=1
187
+ fi
188
+ ;;
189
+ esac
102
190
  else
103
191
  if [ "$emit" = decision ] || doflow_bridge_drops_tool_streams "$policy" "$harness" "$response_event" || { [ "$harness" = kiro ] && [ "$response_event" = Stop ]; }; then exec 5>/dev/null; else exec 5>&1; fi
104
192
  captured="$( {
@@ -113,7 +201,11 @@ doflow_bridge() {
113
201
  case "$line" in
114
202
  *$'\036'*)
115
203
  local prefix="${line%%$'\036'*}"
116
- record="${line#*$'\036'}"
204
+ # Rider R1: the emit record is telemetry, never the decision record.
205
+ case "${line#*$'\036'}" in
206
+ '{"v":1,"emit":'*) emit_record="${line#*$'\036'}" ;;
207
+ *) record="${line#*$'\036'}" ;;
208
+ esac
117
209
  [ -z "$prefix" ] || err="$err$prefix"$'\n'
118
210
  ;;
119
211
  *) err="$err$line"$'\n' ;;
@@ -125,6 +217,7 @@ doflow_bridge() {
125
217
  if [ "$spawn_failed" -eq 1 ]; then DF_BRIDGE_OUTCOME=error; DF_BRIDGE_CODE=bridge-spawn; DF_BRIDGE_REASON=bridge-spawn; DF_BRIDGE_VERSION=0; DF_BRIDGE_POINT=bridge-spawn; fi
126
218
  if [ -n "$DF_BRIDGE_POINT" ] && [ "$DF_BRIDGE_POINT" != decision-mismatch ] && [ "$DF_BRIDGE_POINT" != eval-error:signal-TERM ] && [ "$DF_BRIDGE_POINT" != eval-error:signal-INT ] && [ "$DF_BRIDGE_POINT" != eval-error:signal-PIPE ]; then doflow_bridge_failure "$policy" "$DF_BRIDGE_POINT"; fi
127
219
  doflow_bridge_effect "$harness" "$event" "$policy" "$DF_BRIDGE_OUTCOME"
220
+ doflow_bridge_hook_line "$harness" "$response_event" "$policy" "$emit_record"
128
221
  if [ "$DF_BRIDGE_EFFECT" = block ] && [ "$DF_BRIDGE_OUTCOME" != deny ]; then reason="[$policy] DoFlow policy error; details: doflow-run failure list"; fi
129
222
  if [ "$DF_BRIDGE_OUTCOME" != deny ] && [ "$DF_BRIDGE_EFFECT" = proceed ]; then
130
223
  case "$harness:$response_event:$DF_BRIDGE_OUTCOME" in
@@ -155,7 +248,9 @@ doflow_bridge() {
155
248
  status=0
156
249
  if [ "$DF_BRIDGE_OUTCOME" = error ]; then
157
250
  case "$policy:$harness:$response_event" in
158
- session-context:*:*|user-prompt-submit:*:*|subagent-audit:*:*|*:kiro:PreToolUse|*:claude:Stop) status="$code" ;;
251
+ session-context:*:*|user-prompt-submit:*:*|subagent-audit:*:*) status="$code" ;;
252
+ # The blocking-set policies are advise-only (D1): a proceed effect must not let a raw exit 2 block.
253
+ *:kiro:PreToolUse|*:claude:Stop) case "$policy" in pre-implementation-gate|mcp-tool-guard|stop-check) status=0 ;; *) status="$code" ;; esac ;;
159
254
  esac
160
255
  fi
161
256
  fi
@@ -165,14 +260,22 @@ doflow_bridge() {
165
260
  local render_status=$?
166
261
  return "$render_status"
167
262
  fi
263
+ # D1: an advisory (or out-of-step) line from a blocking-set policy is shown where the harness shows it.
264
+ advice=""
265
+ if [ "$DF_BRIDGE_EFFECT" = proceed ] && { [ "$DF_BRIDGE_OUTCOME" = advisory ] || [ "$DF_BRIDGE_OUTCOME" = unsupported ] || [ "$out_of_step" = 1 ]; } && [ -n "$err" ]; then
266
+ case "$policy:$harness:$response_event" in
267
+ pre-implementation-gate:claude:PreToolUse|pre-implementation-gate:codex:PreToolUse|mcp-tool-guard:claude:PreToolUse|mcp-tool-guard:codex:PreToolUse|stop-check:claude:Stop|stop-check:codex:Stop|stop-check:codex:stop)
268
+ advice="${err%$'\n'}"; advice="${advice//$'\n'/ }" ;;
269
+ esac
270
+ fi
168
271
  case "$policy:$DF_BRIDGE_OUTCOME:$harness:$response_event:$DF_BRIDGE_CODE" in
169
272
  session-context:error:*:*:*|user-prompt-submit:error:*:*:*|subagent-audit:error:*:*:*|session-context:unsupported:*:*:*|user-prompt-submit:unsupported:*:*:*|subagent-audit:unsupported:*:*:*) ;;
170
- *:error:codex:Stop:exit-*|*:error:codex:Stop:signal-*|*:error:codex:stop:exit-*|*:error:codex:stop:signal-*|*:error:kiro:PreToolUse:exit-*|*:error:kiro:PreToolUse:signal-*|*:error:kiro:Stop:exit-*|*:error:kiro:Stop:signal-*|*:error:claude:Stop:exit-*|*:error:claude:Stop:signal-*) ;;
273
+ *:error:codex:Stop:exit-*|*:error:codex:Stop:signal-*|*:error:copilot:Stop:exit-*|*:error:copilot:Stop:signal-*|*:error:codex:stop:exit-*|*:error:codex:stop:signal-*|*:error:kiro:PreToolUse:exit-*|*:error:kiro:PreToolUse:signal-*|*:error:kiro:Stop:exit-*|*:error:kiro:Stop:signal-*|*:error:claude:Stop:exit-*|*:error:claude:Stop:signal-*) ;;
171
274
  *)
172
- if ! doflow_bridge_drops_tool_stderr "$policy" "$harness" "$response_event" && [ -n "$err" ]; then printf '%s' "$err" >&2; fi
275
+ if [ -z "$advice" ] && ! doflow_bridge_drops_tool_stderr "$policy" "$harness" "$response_event" && [ -n "$err" ]; then printf '%s' "$err" >&2; fi
173
276
  ;;
174
277
  esac
175
- doflow_render_response "$harness" "$event" "$DF_BRIDGE_OUTCOME" "$reason" "$status"
278
+ doflow_render_response "$harness" "$event" "$DF_BRIDGE_OUTCOME" "$reason" "$status" "$advice"
176
279
  local render_status=$?
177
280
  return "$render_status"
178
281
  }