@khoavu882/doflow 2.0.0-beta.4 → 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 (497) hide show
  1. package/README.md +12 -11
  2. package/bin/doflow.js +21 -11
  3. package/core/.antigravity-plugin/plugin.json +1 -3
  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 +7 -17
  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-bash-guard.sh +7 -17
  15. package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
  16. package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
  17. package/core/harnesses/claude/hooks/session-end.sh +23 -10
  18. package/core/harnesses/claude/hooks/session-start.sh +5 -3
  19. package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
  20. package/core/harnesses/claude/hooks/stop-check.sh +5 -3
  21. package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
  22. package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
  23. package/core/harnesses/claude/settings/settings.json +18 -0
  24. package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
  25. package/core/harnesses/codex/agents/core-implementer.toml +1 -0
  26. package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
  27. package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
  28. package/core/harnesses/codex/agents/research-writer.toml +1 -1
  29. package/core/harnesses/codex/agents/reviewer.toml +10 -0
  30. package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
  31. package/core/harnesses/codex/agents/system-architect.toml +1 -1
  32. package/core/harnesses/codex/hooks/lib.sh +44 -25
  33. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +7 -15
  34. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
  35. package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
  36. package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
  37. package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
  38. package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
  39. package/core/harnesses/codex/hooks/session-start.sh +5 -3
  40. package/core/harnesses/codex/hooks/stop-check.sh +6 -5
  41. package/core/harnesses/codex/hooks/subagent-audit.sh +18 -6
  42. package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
  43. package/core/harnesses/copilot/hooks/doflow-lib.sh +93 -0
  44. package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
  45. package/core/harnesses/copilot/hooks/doflow-pre-bash-guard.sh +9 -0
  46. package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
  47. package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
  48. package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
  49. package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
  50. package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
  51. package/core/harnesses/copilot/hooks/doflow.json +57 -0
  52. package/core/harnesses/kiro/agents/doflow.json +1 -1
  53. package/core/harnesses/kiro/hooks/lib.sh +26 -6
  54. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +21 -5
  55. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +21 -5
  56. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +21 -5
  57. package/core/harnesses/kiro/hooks/session-start.sh +12 -5
  58. package/core/harnesses/kiro/hooks/stop-check.sh +22 -30
  59. package/core/harnesses/pi/extensions/doflow-guard.js +167 -0
  60. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -12
  61. package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
  62. package/core/harnesses/shared/hooks/bridge/bridge.sh +277 -0
  63. package/core/harnesses/shared/hooks/bridge/envelope.jq +129 -0
  64. package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
  65. package/core/harnesses/shared/hooks/bridge/respond.sh +70 -0
  66. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
  67. package/core/harnesses/shared/hooks/policies/capture-failure.sh +51 -16
  68. package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
  69. package/core/harnesses/shared/hooks/policies/contract.sh +78 -0
  70. package/core/harnesses/shared/hooks/policies/deny-json.sh +35 -9
  71. package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
  72. package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
  73. package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
  74. package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
  75. package/core/harnesses/shared/hooks/policies/lib.sh +65 -40
  76. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +48 -35
  77. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +284 -33
  78. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +180 -110
  79. package/core/harnesses/shared/hooks/policies/session-context.sh +66 -7
  80. package/core/harnesses/shared/hooks/policies/stop-check.sh +61 -23
  81. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +39 -6
  82. package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
  83. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +97 -159
  84. package/core/harnesses/shared/hooks/stream-hook-runner.js +114 -187
  85. package/core/harnesses/shared/locator/doflow-run +2 -3
  86. package/core/registry/advice.json +3 -3
  87. package/core/registry/assets.json +72 -80
  88. package/core/registry/capabilities.json +12 -0
  89. package/core/registry/contracts.json +60 -33
  90. package/core/registry/contribution-points.json +32 -0
  91. package/core/registry/gates.json +32 -0
  92. package/core/registry/guidance-caps.json +40 -0
  93. package/core/registry/harnesses.json +1542 -277
  94. package/core/registry/lifecycle.json +2837 -37
  95. package/core/registry/mcp.json +5 -1
  96. package/core/registry/models.json +7 -1
  97. package/core/registry/package-templates/README.md +19 -0
  98. package/core/registry/package-templates/agent/files/agent.md +9 -0
  99. package/core/registry/package-templates/agent/template.json +4 -0
  100. package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
  101. package/core/registry/package-templates/capability-provider/template.json +11 -0
  102. package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
  103. package/core/registry/package-templates/debate-preset/template.json +4 -0
  104. package/core/registry/package-templates/review-preset/files/preset.json +30 -0
  105. package/core/registry/package-templates/review-preset/template.json +4 -0
  106. package/core/registry/package-templates/skill/files/SKILL.md +8 -0
  107. package/core/registry/package-templates/skill/template.json +4 -0
  108. package/core/registry/package-templates/worker/files/worker.json +92 -0
  109. package/core/registry/package-templates/worker/template.json +11 -0
  110. package/core/registry/packages/doflow/doflow-package.json +15 -0
  111. package/core/registry/packages/doflow/presets/debate-3.json +26 -0
  112. package/core/registry/protocols.json +61 -0
  113. package/core/registry/routes.json +17 -0
  114. package/core/registry/rules.json +431 -0
  115. package/core/registry/settings.json +276 -0
  116. package/core/registry/storage.json +701 -30
  117. package/core/registry/telemetry.json +236 -0
  118. package/core/registry/transcripts.json +142 -0
  119. package/core/registry/verification.json +76 -1
  120. package/core/registry/workflows.json +55 -0
  121. package/core/shared/agent-specs/core-implementer.md +3 -0
  122. package/core/shared/agent-specs/delivery-lead.md +68 -0
  123. package/core/shared/agent-specs/quality-guardian.md +5 -1
  124. package/core/shared/agent-specs/research-writer.md +10 -3
  125. package/core/shared/agent-specs/reviewer.md +53 -0
  126. package/core/shared/agent-specs/spec-analyst.md +5 -6
  127. package/core/shared/agent-specs/system-architect.md +5 -1
  128. package/core/shared/guidance/DOFLOW_CORE.md +1 -5
  129. package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
  130. package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
  131. package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
  132. package/core/shared/guidance/pointers/codex.md +1 -4
  133. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
  134. package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
  135. package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
  136. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
  137. package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
  138. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
  139. package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
  140. package/core/shared/guidance/references/ORCHESTRATION.md +1 -2
  141. package/core/shared/guidance/rules/RULES.md +45 -0
  142. package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
  143. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
  144. package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
  145. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
  146. package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
  147. package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
  148. package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
  149. package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
  150. package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
  151. package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
  152. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
  153. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +48 -4
  154. package/core/shared/scripts/doflow/bin/doflow-run +154 -35
  155. package/core/shared/skills/do/SKILL.md +12 -10
  156. package/core/shared/skills/do/references/advice_calls.md +26 -0
  157. package/core/shared/skills/do/references/pm_routing.md +1 -2
  158. package/core/shared/skills/do/references/program_mode.md +31 -0
  159. package/core/shared/skills/do-brainstorm/SKILL.md +20 -74
  160. package/core/shared/skills/do-brainstorm/references/handoff_branches.md +35 -0
  161. package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
  162. package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
  163. package/core/shared/skills/do-code-review/SKILL.md +41 -144
  164. package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
  165. package/core/shared/skills/do-code-review/references/tools.md +90 -0
  166. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
  167. package/core/shared/skills/do-design/SKILL.md +24 -23
  168. package/core/shared/skills/do-diagnose/SKILL.md +14 -4
  169. package/core/shared/skills/do-document/SKILL.md +11 -1
  170. package/core/shared/skills/do-document/references/deep_research.md +1 -2
  171. package/core/shared/skills/do-document/references/embedded-research.md +18 -6
  172. package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
  173. package/core/shared/skills/do-execute-plan/SKILL.md +17 -59
  174. package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
  175. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
  176. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +28 -1
  177. package/core/shared/skills/do-execute-plan/references/run_position.md +13 -1
  178. package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
  179. package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
  180. package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
  181. package/core/shared/skills/do-flow/SKILL.md +8 -9
  182. package/core/shared/skills/do-flow/references/task_classes.md +2 -2
  183. package/core/shared/skills/do-git/SKILL.md +4 -0
  184. package/core/shared/skills/do-implement/SKILL.md +7 -9
  185. package/core/shared/skills/do-plan/SKILL.md +29 -19
  186. package/core/shared/skills/do-test/SKILL.md +7 -4
  187. package/core/shared/templates/doflow/constitution-template.md +9 -3
  188. package/core/shared/templates/doflow/data-model-template.md +1 -1
  189. package/core/shared/templates/doflow/design-template.md +113 -16
  190. package/core/shared/templates/doflow/plan-template.md +11 -10
  191. package/core/shared/templates/doflow/question-log-template.md +14 -2
  192. package/core/shared/templates/doflow/requirement-template.md +1 -1
  193. package/core/worker-evidence/antigravity/checks.json +14 -0
  194. package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
  195. package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
  196. package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
  197. package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
  198. package/core/worker-evidence/codex/checks.json +38 -0
  199. package/package.json +10 -6
  200. package/src/adapters/antigravity/index.js +226 -113
  201. package/src/adapters/claude/index.js +39 -5
  202. package/src/adapters/codex/agents.js +25 -15
  203. package/src/adapters/codex/hooks.js +40 -5
  204. package/src/adapters/codex/index.js +100 -22
  205. package/src/adapters/codex/native-projection.js +6 -2
  206. package/src/adapters/copilot/index.js +58 -23
  207. package/src/adapters/copy-tree.js +294 -48
  208. package/src/adapters/guidance-manifest.js +71 -0
  209. package/src/adapters/guidance-pointer.js +19 -0
  210. package/src/adapters/hook-commands.js +6 -10
  211. package/src/adapters/index.js +1 -0
  212. package/src/adapters/kiro/index.js +38 -13
  213. package/src/adapters/opencode/index.js +8 -8
  214. package/src/adapters/pi/hooks.js +120 -0
  215. package/src/adapters/pi/index.js +48 -16
  216. package/src/adapters/resolve-source.js +26 -2
  217. package/src/cli/commands/install.js +3 -2
  218. package/src/cli/commands/reconcile.js +53 -9
  219. package/src/cli/commands/remove.js +2 -2
  220. package/src/cli/commands/rollback.js +6 -3
  221. package/src/cli/commands/self-update.js +18 -9
  222. package/src/cli/commands/status.js +21 -2
  223. package/src/cli/commands/ui.js +99 -0
  224. package/src/cli/commands/update.js +3 -2
  225. package/src/cli/index.js +338 -33
  226. package/src/cli/runtime-commands.js +243 -52
  227. package/src/cli/shared.js +0 -2
  228. package/src/helper/git.js +1 -1
  229. package/src/helper/guardrails.js +1 -1
  230. package/src/helper/marker-merge.js +31 -13
  231. package/src/helper/package-ids.js +37 -0
  232. package/src/helper/semver.js +94 -0
  233. package/src/install/backup.js +105 -15
  234. package/src/install/context.js +1 -1
  235. package/src/install/targets.js +31 -16
  236. package/src/lifecycle/coverage.js +74 -0
  237. package/src/lifecycle/hook-step.js +61 -0
  238. package/src/lifecycle/hook-tier.js +160 -0
  239. package/src/lifecycle/index.js +434 -86
  240. package/src/lifecycle/retired-harnesses.js +318 -0
  241. package/src/lifecycle/view.js +35 -15
  242. package/src/registry/index.js +686 -32
  243. package/src/registry/worker-ids.js +45 -0
  244. package/src/release/build-package.js +0 -3
  245. package/src/release/docs-blocks.js +492 -0
  246. package/src/release/preflight.js +425 -0
  247. package/src/release/rehearse.js +401 -0
  248. package/src/release/release-workflow.js +733 -0
  249. package/src/release/sync-plugin-versions.js +43 -7
  250. package/src/runtime/advice/bench-gate.js +25 -0
  251. package/src/runtime/advice/cli.js +59 -16
  252. package/src/runtime/advice/client.js +32 -9
  253. package/src/runtime/advice/config.js +98 -133
  254. package/src/runtime/advice/doctor.js +1 -1
  255. package/src/runtime/advice/elevation.js +97 -0
  256. package/src/runtime/advice/endpoint-guard.js +9 -3
  257. package/src/runtime/advice/mode.js +37 -0
  258. package/src/runtime/advice/record.js +18 -5
  259. package/src/runtime/advice/registry.js +4 -1
  260. package/src/runtime/advice/shadow-config.js +229 -0
  261. package/src/runtime/advice/shadow-dispatcher.js +276 -0
  262. package/src/runtime/brief-rules.js +81 -0
  263. package/src/runtime/brief-tools.js +111 -34
  264. package/src/runtime/candidate.js +514 -0
  265. package/src/runtime/capabilities/executor.js +450 -0
  266. package/src/runtime/capabilities/loopback.js +41 -0
  267. package/src/runtime/capabilities/sanitizer.js +88 -0
  268. package/src/runtime/capability-router.js +135 -3
  269. package/src/runtime/checkouts.js +73 -11
  270. package/src/runtime/claims.js +27 -12
  271. package/src/runtime/cli-result.js +11 -4
  272. package/src/runtime/cli.js +221 -277
  273. package/src/runtime/config-home.js +42 -0
  274. package/src/runtime/context/arbitrate.js +767 -0
  275. package/src/runtime/context/budget.js +203 -0
  276. package/src/runtime/context/compose.js +1367 -0
  277. package/src/runtime/context/delivery-store.js +100 -0
  278. package/src/runtime/context/emission-rules.js +118 -0
  279. package/src/runtime/context/identity.js +227 -0
  280. package/src/runtime/context/mandatory.js +594 -0
  281. package/src/runtime/context/pointer.js +142 -0
  282. package/src/runtime/context/primary-command.js +117 -0
  283. package/src/runtime/context/primary.js +344 -0
  284. package/src/runtime/context/summary-store.js +655 -0
  285. package/src/runtime/context-pack.js +1106 -245
  286. package/src/runtime/decision-register.js +13 -4
  287. package/src/runtime/dispatch/admission.js +392 -0
  288. package/src/runtime/dispatch/attempt-end.js +274 -0
  289. package/src/runtime/dispatch/command.js +628 -0
  290. package/src/runtime/dispatch/controls.js +904 -0
  291. package/src/runtime/dispatch/envelope.js +276 -0
  292. package/src/runtime/dispatch/grants.js +310 -0
  293. package/src/runtime/dispatch/integrate.js +617 -0
  294. package/src/runtime/dispatch/loop.js +1835 -0
  295. package/src/runtime/dispatch/store.js +352 -0
  296. package/src/runtime/dispatch/verify-run.js +201 -0
  297. package/src/runtime/evidence-fields.js +39 -0
  298. package/src/runtime/evidence-ledger.js +41 -7
  299. package/src/runtime/failure/capture.js +3 -1
  300. package/src/runtime/failure/cli.js +25 -9
  301. package/src/runtime/failure/home.js +57 -30
  302. package/src/runtime/failure/store.js +7 -2
  303. package/src/runtime/feature-pointer.js +174 -0
  304. package/src/runtime/feature-resolve.js +13 -2
  305. package/src/runtime/fleet/command.js +77 -0
  306. package/src/runtime/fleet/projects.js +178 -0
  307. package/src/runtime/fleet/tree.js +383 -0
  308. package/src/runtime/freshness.js +77 -10
  309. package/src/runtime/git-memo.js +46 -0
  310. package/src/runtime/guidance/ablation.js +427 -0
  311. package/src/runtime/health.js +565 -17
  312. package/src/runtime/history-compactor.js +13 -3
  313. package/src/runtime/implementation-gate.js +277 -22
  314. package/src/runtime/inventory/coverage.js +1 -1
  315. package/src/runtime/inventory/index.js +1 -1
  316. package/src/runtime/inventory/precedence.js +2 -2
  317. package/src/runtime/inventory/siblings.js +6 -4
  318. package/src/runtime/knowledge/code-corpus.js +277 -0
  319. package/src/runtime/knowledge/code-lexical.js +130 -0
  320. package/src/runtime/knowledge/code-retrieval.js +307 -0
  321. package/src/runtime/knowledge/code-validation.js +106 -0
  322. package/src/runtime/knowledge/gp3-gate.js +74 -0
  323. package/src/runtime/knowledge/graph-adapter.js +288 -0
  324. package/src/runtime/knowledge/graph-fallback.js +394 -0
  325. package/src/runtime/knowledge/hybrid.js +136 -8
  326. package/src/runtime/knowledge/retrieval.js +34 -1
  327. package/src/runtime/knowledge/rtk-compress.js +77 -0
  328. package/src/runtime/knowledge/semble-bridge.py +106 -0
  329. package/src/runtime/knowledge/semble-lifecycle.js +114 -0
  330. package/src/runtime/knowledge/semble-provider.js +365 -0
  331. package/src/runtime/lifecycle/cli.js +16 -6
  332. package/src/runtime/lifecycle/event-store.js +8 -6
  333. package/src/runtime/lifecycle/followup.js +6 -1
  334. package/src/runtime/lifecycle/overview.js +24 -1
  335. package/src/runtime/lifecycle/report-store.js +8 -10
  336. package/src/runtime/lifecycle/retention.js +95 -31
  337. package/src/runtime/lifecycle/root.js +9 -1
  338. package/src/runtime/lifecycle/status.js +34 -17
  339. package/src/runtime/lifecycle/store-upkeep.js +56 -7
  340. package/src/runtime/mask.js +134 -7
  341. package/src/runtime/mcp-consultations.js +40 -6
  342. package/src/runtime/model-router.js +79 -7
  343. package/src/runtime/models/catalogue.js +191 -0
  344. package/src/runtime/models/command.js +153 -0
  345. package/src/runtime/off-words.js +12 -0
  346. package/src/runtime/outcome.js +3 -3
  347. package/src/runtime/packages/command.js +1009 -0
  348. package/src/runtime/packages/contributions.js +116 -0
  349. package/src/runtime/packages/digest.js +132 -0
  350. package/src/runtime/packages/fetch.js +182 -0
  351. package/src/runtime/packages/grants.js +192 -0
  352. package/src/runtime/packages/index-file.js +134 -0
  353. package/src/runtime/packages/instruction.js +90 -0
  354. package/src/runtime/packages/manifest.js +331 -0
  355. package/src/runtime/packages/points.js +477 -0
  356. package/src/runtime/packages/programs.js +216 -0
  357. package/src/runtime/packages/scaffold.js +277 -0
  358. package/src/runtime/packages/source.js +90 -0
  359. package/src/runtime/packages/state.js +164 -0
  360. package/src/runtime/packages/store.js +449 -0
  361. package/src/runtime/packages/tar.js +106 -0
  362. package/src/runtime/packages/view.js +406 -0
  363. package/src/runtime/plan-check.js +59 -0
  364. package/src/runtime/plan-content.js +324 -0
  365. package/src/runtime/policy-init.js +118 -0
  366. package/src/runtime/profiles/doctor.js +96 -0
  367. package/src/runtime/profiles/resolve.js +244 -0
  368. package/src/runtime/profiles/rollback.js +254 -0
  369. package/src/runtime/profiles/sampler.js +41 -0
  370. package/src/runtime/readiness-record.js +16 -11
  371. package/src/runtime/readiness.js +127 -16
  372. package/src/runtime/research-request.js +50 -25
  373. package/src/runtime/retrieval-plan.js +402 -73
  374. package/src/runtime/retrieval-record.js +293 -0
  375. package/src/runtime/review/command.js +246 -0
  376. package/src/runtime/review/dominance.js +68 -0
  377. package/src/runtime/review/findings.js +434 -0
  378. package/src/runtime/review/identity.js +255 -0
  379. package/src/runtime/review/protocol-command.js +109 -0
  380. package/src/runtime/review/protocols.js +405 -0
  381. package/src/runtime/review/resolve-protocol.js +302 -0
  382. package/src/runtime/review/start.js +530 -0
  383. package/src/runtime/roadmap/facts.js +479 -0
  384. package/src/runtime/roadmap/gates.js +270 -0
  385. package/src/runtime/roadmap/loop.js +1636 -0
  386. package/src/runtime/roadmap/merge.js +381 -0
  387. package/src/runtime/roadmap/rows.js +1113 -0
  388. package/src/runtime/roadmap/seed.js +951 -0
  389. package/src/runtime/rules-report.js +336 -0
  390. package/src/runtime/scaffold/artifacts.js +63 -9
  391. package/src/runtime/scaffold/generate.js +21 -9
  392. package/src/runtime/settings/autopilot.js +106 -0
  393. package/src/runtime/settings/cli.js +280 -0
  394. package/src/runtime/settings/config-write.js +314 -0
  395. package/src/runtime/settings/files.js +271 -0
  396. package/src/runtime/settings/legacy.js +154 -0
  397. package/src/runtime/settings/lexical.js +56 -0
  398. package/src/runtime/settings/prepared-run.js +269 -0
  399. package/src/runtime/settings/project-layers.js +118 -0
  400. package/src/runtime/settings/refs.js +288 -0
  401. package/src/runtime/settings/registry.js +553 -0
  402. package/src/runtime/settings/resolve.js +713 -0
  403. package/src/runtime/settings/shared.js +37 -0
  404. package/src/runtime/settings/worker-billing.js +107 -0
  405. package/src/runtime/settings/write.js +269 -0
  406. package/src/runtime/slot-command.js +78 -0
  407. package/src/runtime/slots.js +671 -0
  408. package/src/runtime/source-version.js +290 -0
  409. package/src/runtime/state-root.js +217 -0
  410. package/src/runtime/storage/cli.js +12 -5
  411. package/src/runtime/storage/engine.js +9 -2
  412. package/src/runtime/storage/registry.js +14 -1
  413. package/src/runtime/storage/roots.js +66 -16
  414. package/src/runtime/storage/rules.js +82 -10
  415. package/src/runtime/storage/upkeep.js +10 -2
  416. package/src/runtime/storage/work-status.js +245 -26
  417. package/src/runtime/task-attempts.js +589 -69
  418. package/src/runtime/task-classifier.js +47 -11
  419. package/src/runtime/task-graph.js +373 -0
  420. package/src/runtime/task-run.js +778 -0
  421. package/src/runtime/task-scope.js +202 -56
  422. package/src/runtime/task-sources.js +147 -0
  423. package/src/runtime/task-state.js +440 -65
  424. package/src/runtime/team/admission.js +301 -0
  425. package/src/runtime/team/envelope.js +324 -0
  426. package/src/runtime/team/review-guard.js +156 -0
  427. package/src/runtime/trace/analyze.js +427 -0
  428. package/src/runtime/trace/baseline.js +770 -0
  429. package/src/runtime/trace/ledger.js +63 -140
  430. package/src/runtime/trace/otlp-export.js +568 -0
  431. package/src/runtime/trace/otlp-map.js +481 -0
  432. package/src/runtime/trace/spans.js +745 -0
  433. package/src/runtime/trace/telemetry.js +225 -0
  434. package/src/runtime/trace/views.js +1 -0
  435. package/src/runtime/transcripts/command.js +98 -0
  436. package/src/runtime/transcripts/cursor.js +326 -0
  437. package/src/runtime/transcripts/read.js +126 -0
  438. package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
  439. package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
  440. package/src/runtime/transcripts/readers/copilot-events.js +90 -0
  441. package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
  442. package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
  443. package/src/runtime/transcripts/registry.js +161 -0
  444. package/src/runtime/transcripts/stats.js +161 -0
  445. package/src/runtime/verification/check-key.js +628 -0
  446. package/src/runtime/verification/contract-runner.js +546 -11
  447. package/src/runtime/verification/engine.js +499 -9
  448. package/src/runtime/verification/impact.js +617 -0
  449. package/src/runtime/verification/inflight.js +205 -0
  450. package/src/runtime/verification/registry.js +176 -0
  451. package/src/runtime/verification/reuse.js +184 -0
  452. package/src/runtime/verification/telemetry-emit.js +254 -0
  453. package/src/runtime/verification/test-selection.js +67 -7
  454. package/src/runtime/worker/active.js +90 -0
  455. package/src/runtime/worker/cancel.js +222 -0
  456. package/src/runtime/worker/catalogue.js +122 -0
  457. package/src/runtime/worker/command.js +677 -0
  458. package/src/runtime/worker/evidence.js +288 -0
  459. package/src/runtime/worker/launch.js +288 -0
  460. package/src/runtime/worker/models.js +137 -0
  461. package/src/runtime/worker/parsers.js +218 -0
  462. package/src/runtime/worker/probes/index.js +706 -0
  463. package/src/runtime/worker/process-tree.js +415 -0
  464. package/src/runtime/worker/quota.js +43 -0
  465. package/src/runtime/worker/readiness.js +713 -0
  466. package/src/runtime/worker/run-store.js +166 -0
  467. package/src/runtime/worker/supervisor.js +541 -0
  468. package/src/runtime/worker/worktree-check.js +252 -0
  469. package/src/runtime/workflow-engine.js +5 -1
  470. package/src/runtime/workflow-orchestrator.js +578 -63
  471. package/src/runtime/worktree.js +149 -22
  472. package/src/state/index.js +1 -1
  473. package/src/state/lockfile.js +64 -10
  474. package/src/state/run-lock.js +1 -1
  475. package/types/node-commonjs.d.ts +106 -7
  476. package/core/.antigravity-plugin/hooks.json +0 -39
  477. package/core/harnesses/gemini/hooks/hooks.json +0 -77
  478. package/core/harnesses/gemini/hooks/lib.sh +0 -302
  479. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -21
  480. package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
  481. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -21
  482. package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
  483. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -22
  484. package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
  485. package/core/harnesses/gemini/hooks/session-end.sh +0 -5
  486. package/core/harnesses/gemini/hooks/session-start.sh +0 -5
  487. package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
  488. package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
  489. package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
  490. package/core/harnesses/shared/hooks/hooks.json +0 -47
  491. package/core/shared/guidance/FLAGS.md +0 -25
  492. package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
  493. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
  494. package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
  495. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
  496. package/src/adapters/gemini/hooks.js +0 -210
  497. package/src/adapters/gemini/index.js +0 -390
@@ -0,0 +1,167 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ // C.3's renderer replaces this relative source-tree path for each install scope.
6
+ const BRIDGE = new URL('../../shared/hooks/bridge/bridge.sh', import.meta.url);
7
+ const ROUTES = [
8
+ { tools: ['edit', 'write'], policy: 'pre-implementation-gate' },
9
+ { tools: ['bash'], policy: 'pre-bash-guard' },
10
+ ];
11
+ const LIMIT = 1024 * 1024;
12
+ const TIMEOUT_MS = 5000;
13
+ const ERROR_REASON = (policy) => `[${policy}] DoFlow policy error; details: doflow-run failure list`;
14
+
15
+ function route(toolName) {
16
+ for (const row of ROUTES) {
17
+ if (row.tools.includes(toolName)) return row.policy;
18
+ }
19
+ return typeof toolName === 'string' && toolName.startsWith('mcp__') ? 'mcp-tool-guard' : undefined;
20
+ }
21
+
22
+ function captureFailure(policy, point) {
23
+ const script = new URL('../policies/capture-failure.sh', BRIDGE);
24
+ try {
25
+ const child = spawn('bash', ['-c', '. "$1"; doflow_capture_failure "$2" "$3"', 'doflow-capture', fileURLToPath(script), policy, point], {
26
+ detached: true,
27
+ stdio: 'ignore',
28
+ });
29
+ child.unref();
30
+ } catch {
31
+ // Failure capture must never change Pi's tool-call decision.
32
+ }
33
+ }
34
+
35
+ function bridgeCall(policy, payload, ctx) {
36
+ return new Promise((resolve, reject) => {
37
+ let child;
38
+ try {
39
+ const env = { ...process.env };
40
+ delete env.DOFLOW_PROJECT_DIR;
41
+ child = spawn('bash', [fileURLToPath(BRIDGE), 'pi', 'tool_call', policy], {
42
+ cwd: ctx.cwd,
43
+ env,
44
+ stdio: ['pipe', 'pipe', 'pipe'],
45
+ detached: true,
46
+ });
47
+ } catch (error) {
48
+ reject(Object.assign(error, { failurePoint: 'bridge-spawn' }));
49
+ return;
50
+ }
51
+
52
+ const stdout = [];
53
+ let stdoutBytes = 0;
54
+ let stderrBytes = 0;
55
+ let settled = false;
56
+ let timedOut = false;
57
+ let overflow = false;
58
+ let aborted = false;
59
+ const finish = (error, result) => {
60
+ if (settled) return;
61
+ settled = true;
62
+ clearTimeout(timer);
63
+ ctx.signal?.removeEventListener('abort', onAbort);
64
+ if (error) reject(error);
65
+ else resolve(result);
66
+ };
67
+ const kill = () => {
68
+ try {
69
+ if (child.pid && process.platform !== 'win32') process.kill(-child.pid, 'SIGKILL');
70
+ else child.kill('SIGKILL');
71
+ } catch {
72
+ try { child.kill('SIGKILL'); } catch {}
73
+ }
74
+ };
75
+ const fail = (point) => {
76
+ overflow = point === 'bridge-output-limit';
77
+ kill();
78
+ finish(Object.assign(new Error(point), { failurePoint: point }));
79
+ };
80
+ const onAbort = () => {
81
+ aborted = true;
82
+ kill();
83
+ finish(null, undefined);
84
+ };
85
+ const timer = setTimeout(() => {
86
+ timedOut = true;
87
+ kill();
88
+ }, TIMEOUT_MS);
89
+ if (ctx.signal?.aborted) onAbort();
90
+ else ctx.signal?.addEventListener('abort', onAbort, { once: true });
91
+
92
+ child.on('error', (error) => finish(Object.assign(error, { failurePoint: 'bridge-spawn' })));
93
+ child.stdout.on('data', (chunk) => {
94
+ stdoutBytes += chunk.length;
95
+ if (stdoutBytes > LIMIT) return fail('bridge-output-limit');
96
+ stdout.push(chunk);
97
+ });
98
+ child.stderr.on('data', (chunk) => {
99
+ stderrBytes += chunk.length;
100
+ if (stderrBytes > LIMIT) return fail('bridge-output-limit');
101
+ });
102
+ child.on('close', (code) => {
103
+ if (settled) return;
104
+ if (aborted) return finish(null, undefined);
105
+ if (timedOut) return finish(Object.assign(new Error('bridge timed out'), { failurePoint: 'bridge-timeout' }));
106
+ if (overflow) return finish(Object.assign(new Error('bridge output exceeded limit'), { failurePoint: 'bridge-output-limit' }));
107
+ if (code !== 0) return finish(Object.assign(new Error(`bridge exited ${code}`), { failurePoint: 'bridge-spawn' }));
108
+ const output = Buffer.concat(stdout).toString('utf8');
109
+ if (!output.trim()) return finish(null, undefined);
110
+ if (output.trim().split(/\r?\n/).length !== 1) {
111
+ return finish(Object.assign(new Error('bridge answer must be one JSON line'), { failurePoint: 'bridge-spawn' }));
112
+ }
113
+ try {
114
+ const answer = JSON.parse(output);
115
+ if (!answer || typeof answer !== 'object' || Array.isArray(answer) || answer.block !== true || typeof answer.reason !== 'string') {
116
+ throw new Error('invalid bridge answer');
117
+ }
118
+ finish(null, { block: true, reason: answer.reason });
119
+ } catch {
120
+ finish(Object.assign(new Error('invalid bridge answer'), { failurePoint: 'bridge-spawn' }));
121
+ }
122
+ });
123
+ child.stdin.on('error', () => {});
124
+ child.stdin.end(payload);
125
+ });
126
+ }
127
+
128
+ export default function (pi) {
129
+ pi.on('tool_call', async (event, ctx) => {
130
+ let policy = 'unknown';
131
+ let profile = process.env.DOFLOW_FAULT_PROFILE || 'compat-1';
132
+ try {
133
+ policy = route(event.toolName);
134
+ if (!policy) return undefined;
135
+ profile = process.env.DOFLOW_FAULT_PROFILE || 'compat-1';
136
+ if (profile !== 'compat-1' && profile !== 'strict-1') captureFailure(policy, 'fault-profile-unknown');
137
+ if (!existsSync(BRIDGE)) {
138
+ captureFailure(policy, 'bridge-missing');
139
+ return { block: true, reason: '[doflow] shared hooks lack the bridge; run: doflow update -t pi' };
140
+ }
141
+ let model;
142
+ try {
143
+ const modelId = ctx.model?.id;
144
+ if (typeof modelId === 'string' && modelId.length > 0) model = modelId;
145
+ } catch {
146
+ // A model getter must not prevent the tool call from reaching the bridge.
147
+ }
148
+ const payload = JSON.stringify({
149
+ type: event.type,
150
+ toolName: event.toolName,
151
+ toolCallId: event.toolCallId,
152
+ parentToolCallId: event.parentToolCallId,
153
+ input: event.input,
154
+ cwd: ctx.cwd,
155
+ sessionId: ctx.sessionManager?.getSessionId?.() ?? null,
156
+ ...(model ? { model } : {}),
157
+ });
158
+ if (Buffer.byteLength(payload) > LIMIT) throw Object.assign(new Error('bridge input exceeded limit'), { failurePoint: 'bridge-input-limit' });
159
+ return await bridgeCall(policy, payload, ctx);
160
+ } catch (error) {
161
+ const point = error?.failurePoint || 'bridge-spawn';
162
+ captureFailure(policy, point === 'bridge-timeout' || point === 'bridge-missing' ? point : 'bridge-spawn');
163
+ if (profile === 'strict-1') return { block: true, reason: ERROR_REASON(policy) };
164
+ return undefined;
165
+ }
166
+ });
167
+ }
@@ -1,16 +1,17 @@
1
1
  # The normalized hook envelope, and each front door's share of the migration
2
2
 
3
+ Every shipped bridge places envelope version 1 under `doflow_event`, beside the native fields. Policies read v1 fields only when `version` is the JSON number `1`; any other version is unsupported and is evaluated as such (IC-034, DEC-030).
4
+
3
5
  `policies/pre-implementation-gate.sh` prefers one normalized event over every native payload
4
6
  shape (review R7):
5
7
 
6
8
  ```json
7
- {"doflow_event": {"operation": "edit", "paths": ["src/a.js"], "projectRoot": "/repo", "taskId": "001-auth"}}
9
+ {"doflow_event": {"version": 1, "harness": "claude", "event": "PreToolUse", "operation": "edit", "paths": ["src/a.js"], "projectRoot": "/repo", "taskId": "001-auth"}}
8
10
  ```
9
11
 
10
- A front door that sends this envelope needs none of the policy's legacy union parsing — the four
11
- tool-name spellings, five file-path field names, and Codex `apply_patch` diff extraction exist
12
- only for front doors still forwarding raw native payloads. Each adapter that adopts the envelope
13
- retires its share of that union; when the last one does, the union decoder is deleted.
12
+ The envelope is the only policy input contract. A caller outside a shipped bridge must either
13
+ send a v1 envelope itself or pipe its native payload through
14
+ `bash .doflow/shared/hooks/bridge/bridge.sh <harness> <event> <policy>`.
14
15
 
15
16
  ## Which native event each front door decodes
16
17
 
@@ -21,19 +22,33 @@ tool's official docs (cross-checked against tool source where docs were incomple
21
22
  |---|---|---|
22
23
  | Claude Code | `PreToolUse` | `tool_name` Edit/Write/MultiEdit; `tool_input.file_path` |
23
24
  | Codex | `PreToolUse` | `apply_patch` carries paths inside a unified diff under `tool_input.command` — the ONE decoder that must parse patch text |
24
- | Gemini CLI | `BeforeTool` | also offers `BeforeToolSelection` (pre-selection restriction), which the gate does not use |
25
25
  | GitHub Copilot | `preToolUse` | camelCase event names; `permissionRequest` is CLI-only, not fired in the cloud agent |
26
26
  | OpenCode | `tool.execute.before` | a pluggable hook method, not a sub-event of the generic `event` hook |
27
- | Pi | `tool_execution_start` | Pi's 36-event surface also exposes `tool_call`; the execution-start event is the gate's anchor |
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 |
28
28
  | Antigravity | `PreToolUse` | 5-event surface, `hooks.json` + stdin/stdout JSON contract |
29
29
 
30
+ Pi 1.1.0 declares 41 `on()` overloads in its shipped extension types. `tool_call` is the enforcement event; `tool_execution_start` is not a gate.
31
+
30
32
  `operation` is `"edit"` for anything that writes source; a decoder maps its native create/replace/
31
33
  patch tool vocabulary down to that one word. Non-edit operations may be sent (the policy allows
32
34
  them through), but sending nothing for a non-edit tool is equally correct and cheaper.
33
35
 
34
- ## Rules that hold on both paths
35
-
36
- - The envelope, when present, **outranks** any native fields beside it.
36
+ ## Version and mixed-install rules
37
+
38
+ - A missing envelope or version, empty or non-object input, or a missing `contract.sh` is out of
39
+ step. The gate, bash guard and MCP guard deny with `DoFlow hooks out of step; run: doflow update
40
+ -t <harness>`; Stop and context policies exit silently, except the prompt hook emits its `{}`
41
+ no-op. Other envelope versions are unsupported and policies evaluate nothing.
42
+ - If a door cannot load `bridge/bridge.sh`, it renders its fixed native out-of-step response. The
43
+ Pi extension blocks with the fixed native out-of-step reason; a present bridge that fails to spawn or answer follows
44
+ the configured bridge-fault behavior.
45
+
46
+ Other current bridge behavior: Codex Stop crash stderr is suppressed (DEC-037). Stop-check
47
+ enforcement is answered from Stop coverage rows (DEC-038). Strict-1 never fault-blocks Stop, though
48
+ a real Stop deny still blocks (DEC-039). Bridge capture uses no temporary file, so an unwritable
49
+ `TMPDIR` does not turn a gate deny into an allow; background jobs do not hold Stop or SessionStart
50
+ open; strict-1 renders native denies without `jq`. `doflow update -t codex -f` re-merges edited
51
+ Codex `hooks.json` while keeping user entries (DEC-040).
37
52
  - Root resolution: `DOFLOW_PROJECT_DIR` beats the envelope's `projectRoot` beats git discovery.
38
- - The policy remains a pure file-existence gate (FR-012): the envelope changes how it hears about
39
- an edit, never what it decides, and it must never consult readiness or evidence state.
53
+ - The pre-implementation gate checks required artifacts and reads run and readiness records; it
54
+ does not consult evidence state.
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * Antigravity payload/decision adapter for the Cross-Harness Hook Runner (design.md C2's
5
- * Payload Adapter / Decision Adapter seam, D2).
4
+ * Antigravity native decision renderer for the Cross-Harness Hook Runner's
5
+ * Decision Adapter seam, D2). The shared bridge owns native payload decoding.
6
6
  *
7
7
  * Antigravity's own native contracts — evidenced by core/harnesses/antigravity/hooks/*.sh (the
8
8
  * shims src/adapters/antigravity/index.js actually projects today) and
@@ -19,67 +19,24 @@
19
19
  * vocabulary than PreToolUse's allow/deny/ask/force_ask, not an oversight.
20
20
  *
21
21
  * SessionStart and PostToolUse have no dedicated Antigravity-native shim in
22
- * src/adapters/antigravity/index.js's live projection; core/.antigravity-plugin/hooks.json (a
23
- * separate, read-only-to-this-task artifact) documents both routed directly to the *Gemini*
24
- * session-start.sh / post-edit-lint.sh scripts, which read the Claude/Gemini-style
25
- * session_id/cwd/tool_name/tool_input field names, not the toolCall envelope above — this
26
- * adapter honors that evidence for those two events rather than guessing at a toolCall shape
27
- * with no corroborating source. No Phase A canonical policy owns PostToolUse today (only
22
+ * src/adapters/antigravity/index.js's live projection. No Phase A canonical policy owns PostToolUse today (only
28
23
  * session-context, pre-implementation-gate, mcp-tool-guard, stop-check, pre-bash-guard exist),
29
24
  * so its native shape is an ack passthrough either way.
30
25
  */
31
26
 
32
- const { FILE_PATH_ARG_FIELDS, COMMAND_ARG_FIELDS, firstArgField } = require('./arg-fields');
33
-
34
- function toCanonical(event, payload) {
35
- const safePayload = payload && typeof payload === 'object' ? payload : {};
36
-
37
- switch (event) {
38
- case 'SessionStart':
39
- return { session_id: safePayload.session_id || '', cwd: safePayload.cwd || '' };
40
-
41
- case 'PreToolUse': {
42
- const toolCall = safePayload.toolCall || {};
43
- const args = toolCall.args || {};
44
- return {
45
- tool_name: toolCall.name || '',
46
- tool_input: {
47
- file_path: firstArgField(args, FILE_PATH_ARG_FIELDS),
48
- command: firstArgField(args, COMMAND_ARG_FIELDS),
49
- },
50
- };
51
- }
52
-
53
- case 'PostToolUse':
54
- // No Phase A policy consumes this event — canonical shape kept for symmetry only.
55
- return {
56
- tool_name: safePayload.tool_name || '',
57
- session_id: safePayload.session_id || '',
58
- tool_input: { file_path: (safePayload.tool_input && safePayload.tool_input.file_path) || '' },
59
- };
60
-
61
- case 'Stop':
62
- return {
63
- session_id: safePayload.session_id || '',
64
- transcript_path: safePayload.transcriptPath || safePayload.transcript_path || '',
65
- };
66
-
67
- case 'PreInvocation':
68
- // No Phase A policy — ack only (injectSteps handled entirely in toNative).
69
- return {};
70
-
71
- default:
72
- return safePayload;
73
- }
74
- }
75
-
76
27
  function toNative(event, decision) {
77
28
  const safeDecision = decision || { decision: 'allow' };
29
+ const blocked = safeDecision.effect === 'block' || safeDecision.decision === 'deny';
30
+ const reason = safeDecision.outcome === 'deny'
31
+ ? safeDecision.reason
32
+ : safeDecision.effect === 'block'
33
+ ? `[${safeDecision.policy}] DoFlow policy error; details: doflow-run failure list`
34
+ : safeDecision.reason;
78
35
 
79
36
  switch (event) {
80
37
  case 'PreToolUse':
81
- if (safeDecision.decision === 'deny') {
82
- return { decision: 'deny', reason: safeDecision.reason };
38
+ if (blocked) {
39
+ return { decision: 'deny', reason };
83
40
  }
84
41
  return { decision: 'allow' };
85
42
 
@@ -88,8 +45,8 @@ function toNative(event, decision) {
88
45
  return {};
89
46
 
90
47
  case 'Stop':
91
- if (safeDecision.decision === 'deny') {
92
- return { decision: 'continue', reason: safeDecision.reason };
48
+ if (blocked) {
49
+ return { decision: 'continue', reason };
93
50
  }
94
51
  // Silence (no positive field) lets the session stop, per Antigravity's own documented
95
52
  // Stop contract — not the allow/deny vocabulary PreToolUse uses.
@@ -108,4 +65,4 @@ function toNative(event, decision) {
108
65
  }
109
66
  }
110
67
 
111
- module.exports = { toCanonical, toNative };
68
+ module.exports = { toNative };
@@ -0,0 +1,277 @@
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
3
+ # Shared lifecycle bridge. Sourcing defines functions only; it sets no shell options or traps.
4
+ _DOFLOW_SRC=${BASH_SOURCE[0]//\\//}; case $_DOFLOW_SRC in */*) _DOFLOW_BRIDGE_DIR=${_DOFLOW_SRC%/*} ;; *) _DOFLOW_BRIDGE_DIR=. ;; esac
5
+
6
+ doflow_bridge_failure() {
7
+ local policy="$1" point="$2"
8
+ ( . "$_DOFLOW_BRIDGE_DIR/../policies/capture-failure.sh"; doflow_capture_failure "$policy" "$point" ) >/dev/null 2>&1 || true
9
+ }
10
+
11
+ doflow_bridge_classify() {
12
+ local code="$1" record="$2" outcome="" decision_code="" version=0 reason="$3"
13
+ if [ -n "$record" ]; then
14
+ outcome="${record#*\"outcome\":\"}"; outcome="${outcome%%\"*}"
15
+ decision_code="${record#*\"code\":\"}"; decision_code="${decision_code%%\"*}"
16
+ version="${record#*\"policyVersion\":}"; version="${version%%,*}"
17
+ case "$version" in ''|*[^0-9]*) version=0;; esac
18
+ fi
19
+ DF_BRIDGE_OUTCOME=error; DF_BRIDGE_CODE=exit-"$code"; DF_BRIDGE_VERSION="$version"; DF_BRIDGE_REASON="$DF_BRIDGE_CODE"; DF_BRIDGE_POINT="eval-error:exit-$code"
20
+ if [ "$code" -eq 2 ] 2>/dev/null; then
21
+ if [ "$outcome" = deny ]; then DF_BRIDGE_OUTCOME=deny; DF_BRIDGE_CODE="$decision_code"; DF_BRIDGE_REASON="$reason"; DF_BRIDGE_POINT=""
22
+ else DF_BRIDGE_CODE=exit-2-unmarked; DF_BRIDGE_REASON=exit-2-unmarked; DF_BRIDGE_POINT=eval-error:exit-2-unmarked; fi
23
+ elif [ "$code" -eq 0 ] 2>/dev/null; then
24
+ case "$outcome" in
25
+ allow|advisory|error|unsupported) DF_BRIDGE_OUTCOME="$outcome"; DF_BRIDGE_CODE="$decision_code"; DF_BRIDGE_REASON="$decision_code"; DF_BRIDGE_POINT="" ;;
26
+ deny) DF_BRIDGE_OUTCOME=allow; DF_BRIDGE_CODE=decision-mismatch; DF_BRIDGE_REASON=decision-mismatch; DF_BRIDGE_POINT=decision-mismatch ;;
27
+ *) DF_BRIDGE_OUTCOME=allow; DF_BRIDGE_CODE=allow; DF_BRIDGE_REASON=allow; DF_BRIDGE_POINT=""; DF_BRIDGE_VERSION=0 ;;
28
+ esac
29
+ elif [ "$code" -ge 129 ] && [ "$code" -le 255 ] && [ "$code" -ne 255 ] 2>/dev/null; then
30
+ local sig=""
31
+ sig="$(kill -l "$((code - 128))" 2>/dev/null)" || sig=""
32
+ sig="${sig#SIG}"
33
+ case "$sig" in ''|*[!A-Za-z0-9_-]*) return;; esac
34
+ DF_BRIDGE_OUTCOME=error; DF_BRIDGE_CODE=signal-"$sig"; DF_BRIDGE_REASON="$DF_BRIDGE_CODE"; DF_BRIDGE_POINT="eval-error:signal-$sig"
35
+ fi
36
+ }
37
+
38
+ doflow_bridge_effect() {
39
+ local harness="$1" event="$2" policy="$3" outcome="$4" profile="${DOFLOW_FAULT_PROFILE:-compat-1}" block=0
40
+ doflow_bridge_native_event_var "$harness" "$event"; event=$DF_NE
41
+ if [ "$profile" != compat-1 ] && [ "$profile" != strict-1 ]; then
42
+ profile=compat-1; doflow_bridge_failure "$policy" fault-profile-unknown
43
+ fi
44
+ DF_BRIDGE_PROFILE="$profile"
45
+ case "$policy" in pre-implementation-gate|pre-bash-guard|mcp-tool-guard|stop-check) block=1;; esac
46
+ DF_BRIDGE_EFFECT=proceed
47
+ if [ "$outcome" = deny ]; then DF_BRIDGE_EFFECT=block
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
49
+ elif [ "$outcome" = error ] && [ "$DF_BRIDGE_CODE" != bridge-spawn ] && [ -n "$DF_BRIDGE_POINT" ] && [ "$profile" = compat-1 ]; then
50
+ case "$harness:$event" in
51
+ claude:PreToolUse|codex:PreToolUse|copilot:PreToolUse|pi:tool_call) DF_BRIDGE_EFFECT=block ;;
52
+ antigravity:PreToolUse|antigravity:Stop) case "$DF_BRIDGE_CODE" in signal-*) DF_BRIDGE_EFFECT=proceed;; *) DF_BRIDGE_EFFECT=block;; esac ;;
53
+ kiro:PreToolUse) [ "$DF_BRIDGE_CODE" = exit-2-unmarked ] && DF_BRIDGE_EFFECT=block ;;
54
+ claude:Stop) [ "$DF_BRIDGE_CODE" = exit-2-unmarked ] && DF_BRIDGE_EFFECT=block ;;
55
+ codex:Stop|codex:stop|copilot:Stop|kiro:Stop|kiro:stop) [ "$DF_BRIDGE_CODE" = exit-2-unmarked ] && DF_BRIDGE_EFFECT=block || DF_BRIDGE_EFFECT=proceed ;;
56
+ esac
57
+ fi
58
+ # Copilot CLI: a guarded preToolUse policy that errors or cannot decide (jq or the policy script
59
+ # missing, an edit with no decodable target) denies whatever the fault profile; only a policy that
60
+ # answered allow or advisory lets the call through. Copilot-only: every other harness keeps the
61
+ # profile rules above byte for byte.
62
+ if [ "$block" -eq 1 ] && [ "$DF_BRIDGE_EFFECT" = proceed ] && [ "$harness:$event" = copilot:PreToolUse ] && [ "$policy" != stop-check ]; then
63
+ case "$outcome" in error|unsupported) DF_BRIDGE_EFFECT=block ;; esac
64
+ fi
65
+ }
66
+
67
+ doflow_bridge_drops_tool_streams() {
68
+ case "$1" in
69
+ pre-implementation-gate|pre-bash-guard|mcp-tool-guard) ;;
70
+ *) return 1 ;;
71
+ esac
72
+ case "$2:$3" in
73
+ claude:PreToolUse|codex:PreToolUse|copilot:PreToolUse|kiro:PreToolUse|antigravity:PreToolUse|antigravity:Stop|pi:tool_call) return 0 ;;
74
+ *) return 1 ;;
75
+ esac
76
+ }
77
+
78
+ doflow_bridge_drops_tool_stderr() {
79
+ case "$1:$2:$3" in
80
+ pre-implementation-gate:kiro:PreToolUse|pre-bash-guard:kiro:PreToolUse|mcp-tool-guard:kiro:PreToolUse) return 1 ;;
81
+ esac
82
+ doflow_bridge_drops_tool_streams "$1" "$2" "$3"
83
+ }
84
+
85
+ # One hook line (IC-004) for an allowlisted surface, from the encode tuple in DF_TUPLE, appended to
86
+ # <config>/state/runs/telemetry/<UTC date>.jsonl. Builtins only on the path that writes; every step
87
+ # returns 0, and nothing reaches stdout or stderr. Args: harness, normalised event, policy, and the
88
+ # policy's emit record (rider R1, user-prompt-submit only): its reason, byte count and digest are
89
+ # written only when each passes its pattern (a vocabulary member, digits, 8 lowercase hex or null),
90
+ # else all three are null, as they are on every other line.
91
+ doflow_bridge_hook_line() {
92
+ local d="" f="" day="" rest="" duration=null t1="" er=null eb=null eg=null r="" b="" g=""
93
+ [ "${DOFLOW_TELEMETRY:-}" != off ] || return 0
94
+ case "$DF_TUPLE" in ''|'{"dft":1}') return 0 ;; esac
95
+ case "$1:$3:$2" in
96
+ claude:pre-bash-guard:PreToolUse|codex:pre-bash-guard:PreToolUse|kiro:pre-bash-guard:PreToolUse|antigravity:pre-bash-guard:PreToolUse|pi:pre-bash-guard:tool_call|claude:user-prompt-submit:UserPromptSubmit|codex:user-prompt-submit:UserPromptSubmit) ;;
97
+ *) return 0 ;;
98
+ esac
99
+ if [ -n "${DOFLOW_CONFIG_DIR:-}" ]; then
100
+ d=$DOFLOW_CONFIG_DIR
101
+ else
102
+ d=${PWD:-}
103
+ case "$d" in /*) ;; *) return 0 ;; esac
104
+ while :; do
105
+ if [ -d "$d/.doflow" ]; then
106
+ case "$d/" in
107
+ */.doflow/*) ;;
108
+ *) d=${d%/}/.doflow; break ;;
109
+ esac
110
+ fi
111
+ [ -n "$d" ] && [ "$d" != "/" ] || return 0
112
+ d=${d%/*}
113
+ done
114
+ fi
115
+ [ -d "$d/state" ] || return 0
116
+ day=${DF_TUPLE:17:10}
117
+ case "$day" in [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ;; *) return 0 ;; esac
118
+ rest=${DF_TUPLE#\{\"dft\":1,\"date\":\"??????????\",}
119
+ case "$rest" in \"timestamp\":*\}) ;; *) return 0 ;; esac
120
+ if [ -n "$_df_t0" ]; then
121
+ t1=${EPOCHREALTIME:-}; t1=${t1/[.,]/}; _df_t0=${_df_t0/[.,]/}
122
+ case "$t1$_df_t0" in ''|*[!0-9]*) ;; *) duration=$(( (t1 - _df_t0) / 1000 )); [ "$duration" -ge 0 ] || duration=null ;; esac
123
+ fi
124
+ if [ "$3" = user-prompt-submit ] && [ -n "${4:-}" ]; then
125
+ r=${4#*\"reason\":\"}; r=${r%%\"*}
126
+ b=${4#*\"bytes\":}; b=${b%%[,\}]*}
127
+ g=${4#*\"digest\":}; g=${g%%[,\}]*}
128
+ case "$r" in
129
+ 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) ;;
130
+ *) r="" ;;
131
+ esac
132
+ # Explicit character lists: a locale's collation can put capitals inside a range such as [a-f].
133
+ case "$b" in ''|*[!0123456789]*|0?*|???????????*) b="" ;; esac
134
+ case "$g" in
135
+ null|\"[0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef][0123456789abcdef]\") ;;
136
+ *) g="" ;;
137
+ esac
138
+ if [ -n "$r" ] && [ -n "$b" ] && [ -n "$g" ]; then er=\"$r\"; eb=$b; eg=$g; fi
139
+ fi
140
+ [ -d "$d/state/runs/telemetry" ] || mkdir "$d/state/runs/telemetry" 2>/dev/null || return 0
141
+ f=$d/state/runs/telemetry/$day.jsonl
142
+ [ ! -e "$f" ] || [ -f "$f" ] || return 0
143
+ { 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
144
+ return 0
145
+ }
146
+
147
+ doflow_bridge() {
148
+ 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="" line="" spawn_failed=0 encode_failed=0 _df_t0=""
149
+ DF_TUPLE=""
150
+ if [ "${BASH_VERSINFO[0]:-0}" -ge 5 ] 2>/dev/null; then _df_t0=${EPOCHREALTIME:-}; fi
151
+ . "$_DOFLOW_BRIDGE_DIR/respond.sh"
152
+ doflow_bridge_native_event_var "$harness" "$event"; response_event=$DF_NE
153
+ if [ "${4:-}" = --emit ]; then emit="${5:-native}"; fi
154
+ payload="$(cat)"
155
+ if command -v jq >/dev/null 2>&1; then
156
+ 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
157
+ # The telemetry tuple is the first line; without an envelope line after it there is no envelope.
158
+ case "$encoded" in
159
+ '{"dft"'*)
160
+ DF_TUPLE=${encoded%%$'\n'*}
161
+ case "$encoded" in *$'\n'*) encoded=${encoded#*$'\n'} ;; *) encoded="" ;; esac
162
+ ;;
163
+ esac
164
+ if [ "$encode_failed" -eq 0 ]; then
165
+ case "$encoded" in \{*) payload="$encoded" ;; *) encode_failed=1 ;; esac
166
+ fi
167
+ if [ "$encode_failed" -eq 1 ]; then
168
+ 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=""
169
+ case "$encoded" in \{*) payload="$encoded" ;; *) payload="{\"doflow_event\":{\"version\":1,\"harness\":\"$harness\",\"event\":\"$event\",\"operation\":\"tool\"}}" ;; esac
170
+ doflow_bridge_failure "$policy" envelope-encode
171
+ else
172
+ # Step observe-model (row 120 IC-005): an envelope whose identity names a model is recorded
173
+ # under the config home. It never changes the decision, the exit code or the streams.
174
+ case "$payload" in
175
+ *'"doflow_event":{'*'"model":"'*)
176
+ [ ! -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
177
+ ;;
178
+ esac
179
+ fi
180
+ else
181
+ doflow_bridge_failure "$policy" dependency-missing:jq
182
+ fi
183
+ case "$policy" in
184
+ pre-implementation-gate|pre-bash-guard|mcp-tool-guard|stop-check|session-context|user-prompt-submit|subagent-audit) ;;
185
+ *) spawn_failed=1 ;;
186
+ esac
187
+ policy_path="$_DOFLOW_BRIDGE_DIR/../policies/$policy.sh"
188
+ if [ "$spawn_failed" -eq 1 ] || [ ! -f "$policy_path" ]; then
189
+ code=127; err=""; spawn_failed=1
190
+ else
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
192
+ captured="$( {
193
+ if DOFLOW_AGENT="${DOFLOW_AGENT:-$harness}" DOFLOW_DECISION_FD=3 bash "$policy_path" 2>&1 3>&1 1>&5 5>&- <<<"$payload"; then policy_code=0; else policy_code=$?; fi
194
+ printf '\037%s' "$policy_code"
195
+ } )"
196
+ exec 5>&-
197
+ code="${captured##*$'\037'}"
198
+ captured="${captured%$'\037'*}"
199
+ fi
200
+ while IFS= read -r line || [ -n "$line" ]; do
201
+ case "$line" in
202
+ *$'\036'*)
203
+ local prefix="${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
209
+ [ -z "$prefix" ] || err="$err$prefix"$'\n'
210
+ ;;
211
+ *) err="$err$line"$'\n' ;;
212
+ esac
213
+ done < <(printf '%s' "$captured")
214
+ reason="${err%$'\n'}"
215
+ doflow_bridge_classify "$code" "$record" "$reason"
216
+ if [ "$encode_failed" -eq 1 ] && [ "$DF_BRIDGE_OUTCOME" != deny ]; then DF_BRIDGE_CODE=envelope-encode; DF_BRIDGE_POINT=envelope-encode; fi
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
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
219
+ doflow_bridge_effect "$harness" "$event" "$policy" "$DF_BRIDGE_OUTCOME"
220
+ doflow_bridge_hook_line "$harness" "$response_event" "$policy" "$emit_record"
221
+ if [ "$DF_BRIDGE_EFFECT" = block ] && [ "$DF_BRIDGE_OUTCOME" != deny ]; then reason="[$policy] DoFlow policy error; details: doflow-run failure list"; fi
222
+ if [ "$DF_BRIDGE_OUTCOME" != deny ] && [ "$DF_BRIDGE_EFFECT" = proceed ]; then
223
+ case "$harness:$response_event:$DF_BRIDGE_OUTCOME" in
224
+ kiro:PreToolUse:error|claude:Stop:error)
225
+ case "$DF_BRIDGE_CODE" in
226
+ exit-*|signal-*)
227
+ reason="[$policy] DoFlow policy error; details: doflow-run failure list"
228
+ if [ "$harness:$response_event" = claude:Stop ]; then reason="$reason"$'\n'; fi
229
+ ;;
230
+ esac
231
+ ;;
232
+ *) reason="$DF_BRIDGE_CODE" ;;
233
+ esac
234
+ fi
235
+ decision_reason="$DF_BRIDGE_CODE"
236
+ if [ "$DF_BRIDGE_OUTCOME" = deny ]; then decision_reason="$reason"; fi
237
+ if [ "$emit" = decision ] || [ -n "${DOFLOW_BRIDGE_TRACE:-}" ]; then
238
+ decision="$(jq -cn --arg harness "$harness" --arg event "$event" --arg policy "$policy" --arg outcome "$DF_BRIDGE_OUTCOME" --arg code "$DF_BRIDGE_CODE" --arg reason "$decision_reason" --arg profile "$DF_BRIDGE_PROFILE" --arg effect "$DF_BRIDGE_EFFECT" --argjson version "$DF_BRIDGE_VERSION" '{v:1,harness:$harness,event:$event,policy:$policy,policyVersion:$version,outcome:$outcome,code:$code,reason:$reason,faultProfile:$profile,effect:$effect}')"
239
+ fi
240
+ if [ -n "${DOFLOW_BRIDGE_TRACE:-}" ]; then printf '%s\n' "$decision" >>"$DOFLOW_BRIDGE_TRACE" 2>/dev/null || true; fi
241
+ if [ "$emit" = decision ]; then
242
+ printf '%s\n' "$decision"
243
+ return 0
244
+ fi
245
+ if [ "$DF_BRIDGE_EFFECT" = block ]; then
246
+ status=2
247
+ else
248
+ status=0
249
+ if [ "$DF_BRIDGE_OUTCOME" = error ]; then
250
+ case "$policy:$harness:$response_event" in
251
+ session-context:*:*|user-prompt-submit:*:*|subagent-audit:*:*|*:kiro:PreToolUse|*:claude:Stop) status="$code" ;;
252
+ esac
253
+ fi
254
+ fi
255
+ if [ "$spawn_failed" -eq 1 ] && [ "$DF_BRIDGE_EFFECT" = proceed ]; then status=0; fi
256
+ if [ "$DF_BRIDGE_EFFECT" = block ]; then
257
+ doflow_render_response "$harness" "$event" deny "$reason" "$status"
258
+ local render_status=$?
259
+ return "$render_status"
260
+ fi
261
+ case "$policy:$DF_BRIDGE_OUTCOME:$harness:$response_event:$DF_BRIDGE_CODE" in
262
+ session-context:error:*:*:*|user-prompt-submit:error:*:*:*|subagent-audit:error:*:*:*|session-context:unsupported:*:*:*|user-prompt-submit:unsupported:*:*:*|subagent-audit:unsupported:*:*:*) ;;
263
+ *: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-*) ;;
264
+ *)
265
+ if ! doflow_bridge_drops_tool_stderr "$policy" "$harness" "$response_event" && [ -n "$err" ]; then printf '%s' "$err" >&2; fi
266
+ ;;
267
+ esac
268
+ doflow_render_response "$harness" "$event" "$DF_BRIDGE_OUTCOME" "$reason" "$status"
269
+ local render_status=$?
270
+ return "$render_status"
271
+ }
272
+
273
+ if [ "${BASH_SOURCE[0]}" = "$0" ]; then
274
+ . "$_DOFLOW_BRIDGE_DIR/respond.sh"
275
+ doflow_bridge "${1:-}" "${2:-}" "${3:-}" "${4:-}" "${5:-}"
276
+ exit $?
277
+ fi