@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
@@ -1,13 +1,16 @@
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 the Canonical Policy Library
3
4
  #
4
- # Usage: source "$(dirname "$0")/lib.sh"
5
+ # Usage: source "<policy-dir>/lib.sh"
5
6
  #
6
7
  # All hooks must:
7
8
  # 1. source this file at the top
8
9
  # 2. call require_jq immediately after
9
10
  # 3. capture stdin once: INPUT=$(cat)
10
11
  # 4. use: json_field "$INPUT" ".field_name"
12
+
13
+ _DOFLOW_SRC=${BASH_SOURCE[0]//\\//}; case $_DOFLOW_SRC in */*) _DOFLOW_LIB_DIR=${_DOFLOW_SRC%/*} ;; *) _DOFLOW_LIB_DIR=. ;; esac
11
14
  #
12
15
  # Deployment:
13
16
  # This file is installed by the doflow CLI and overwritten on update — do
@@ -15,7 +18,7 @@
15
18
  #
16
19
  # Consolidation note (022-normalize-hooks, Phase B): this is the single
17
20
  # canonical copy every front door's dispatched policy script sources — the
18
- # claude/gemini/kiro/codex copies it replaces were already byte-identical
21
+ # claude/kiro/codex copies it replaces were already byte-identical
19
22
  # except for one Claude-only default (see DOFLOW_AGENT below), confirmed via
20
23
  # diff before consolidating.
21
24
 
@@ -23,16 +26,33 @@ set -euo pipefail
23
26
 
24
27
  # ── State directories ────────────────────────────────────────────────────────
25
28
 
26
- # XDG-compliant, agent-agnostic store shared by every harness DoFlow supports.
27
- DOFLOW_HOME="${XDG_CONFIG_HOME:-$HOME/.config}/doflow"
28
- STATE_DIR="$DOFLOW_HOME/session-env"
29
- SESSION_DIR="$STATE_DIR/sessions"
30
- PROJECTS_DIR="$STATE_DIR/projects"
29
+ # XDG-compliant, agent-agnostic store shared by every harness DoFlow supports, under the config home
30
+ # (doflow_config_home: an absolute XDG_CONFIG_HOME, else an absolute HOME + /.config, else none). With
31
+ # no config home every state path below is empty, sourcing this file still never exits, and each state
32
+ # function returns 0 at once: session work is skipped and a guard reaches its own decision (086 IC-010).
33
+ # BEGIN doflow-config-home v1 (rule: src/runtime/config-home.js; checked by test/guards/settings.test.js)
34
+ doflow_config_home() {
35
+ DOFLOW_HOME=""
36
+ case "${XDG_CONFIG_HOME:-}" in
37
+ /*) DOFLOW_HOME="${XDG_CONFIG_HOME}/doflow"; return 0 ;;
38
+ [A-Za-z]:[\\/]*) case "${OSTYPE:-}" in msys*|cygwin*|win32*) DOFLOW_HOME="${XDG_CONFIG_HOME}/doflow"; return 0 ;; esac ;;
39
+ esac
40
+ case "${HOME:-}" in
41
+ /*) DOFLOW_HOME="${HOME}/.config/doflow" ;;
42
+ [A-Za-z]:[\\/]*) case "${OSTYPE:-}" in msys*|cygwin*|win32*) DOFLOW_HOME="${HOME}/.config/doflow" ;; esac ;;
43
+ esac
44
+ return 0
45
+ }
46
+ # END doflow-config-home v1
47
+ doflow_config_home
48
+ STATE_DIR="${DOFLOW_HOME:+$DOFLOW_HOME/session-env}"
49
+ SESSION_DIR="${STATE_DIR:+$STATE_DIR/sessions}"
50
+ PROJECTS_DIR="${STATE_DIR:+$STATE_DIR/projects}"
31
51
  # shellcheck disable=SC2034 # used by session-context.sh and stop-check.sh which source this file
32
- SESSIONS_LOG="$DOFLOW_HOME/sessions.log"
52
+ SESSIONS_LOG="${DOFLOW_HOME:+$DOFLOW_HOME/sessions.log}"
33
53
 
34
54
  # Identifies which harness is running. A front door sets this before sourcing
35
- # this file (e.g. `export DOFLOW_AGENT=gemini; exec bash .../policies/...sh`);
55
+ # this file (e.g. `export DOFLOW_AGENT=codex; exec bash .../policies/...sh`);
36
56
  # "unknown" here — not any one harness's name — is the honest fallback when a
37
57
  # front door omits it, since every prior per-harness copy of this file
38
58
  # defaulted to "claude-code" regardless of which harness actually shipped it.
@@ -251,18 +271,22 @@ has_uncommitted_changes() {
251
271
  # ── Directory helpers ─────────────────────────────────────────────────────────
252
272
 
253
273
  # Create and return the session-scoped state directory for a given session_id.
254
- # Safe to call multiple times (mkdir -p is idempotent).
274
+ # Safe to call multiple times (mkdir -p is idempotent). Prints nothing and creates nothing when
275
+ # there is no config home (SESSION_DIR empty).
255
276
  ensure_session_dir() {
256
277
  local session_id="$1"
278
+ [ -n "$SESSION_DIR" ] || return 0
257
279
  mkdir -p "$SESSION_DIR/$session_id"
258
280
  echo "$SESSION_DIR/$session_id"
259
281
  }
260
282
 
261
283
  # Create and return the project-scoped state directory for a given cwd.
262
- # Shared across all sessions in the same directory.
284
+ # Shared across all sessions in the same directory. Prints nothing and creates nothing when there
285
+ # is no config home (PROJECTS_DIR empty).
263
286
  ensure_project_dir() {
264
287
  local cwd="$1"
265
288
  local hash
289
+ [ -n "$PROJECTS_DIR" ] || return 0
266
290
  hash=$(cwd_hash "$cwd")
267
291
  mkdir -p "$PROJECTS_DIR/$hash"
268
292
  echo "$PROJECTS_DIR/$hash"
@@ -291,30 +315,16 @@ require_jq() {
291
315
  fi
292
316
  }
293
317
 
294
- # ── Session role ──────────────────────────────────────────────────────────────
295
-
296
- # Print `main` or `worker` for this session, read from DOFLOW_SESSION_ROLE (matched
297
- # case-insensitively). Unset or empty is `main`; a value that is neither `main` nor
298
- # `worker` is `worker` and writes one line to stderr. A worker never writes or claims the
299
- # project's compact summary or warning. Always returns 0. bash 3.2 safe (no ${var,,}).
300
- doflow_session_role() {
301
- local role
302
- role=$(printf '%s' "${DOFLOW_SESSION_ROLE:-}" | tr '[:upper:]' '[:lower:]') || role=""
303
- case "$role" in
304
- ""|main) printf 'main\n' ;;
305
- worker) printf 'worker\n' ;;
306
- *)
307
- echo "[doflow] unknown DOFLOW_SESSION_ROLE; treating session as worker" >&2
308
- printf 'worker\n'
309
- ;;
310
- esac
311
- return 0
312
- }
318
+ # ── Session role and identity ─────────────────────────────────────────────────
319
+
320
+ # doflow_session_role and doflow_identity live in identity.sh, their only definition (IC-009).
321
+ . "$_DOFLOW_LIB_DIR/identity.sh"
313
322
 
314
323
  # Start storage cleanup without changing the hook's output, status, or latency.
315
324
  storage_upkeep_async() {
316
- local cwd="${1:-}" root run home config_dir
325
+ local cwd="${1:-}" root run home config_dir detach=""
317
326
  [ -n "$cwd" ] || return 0
327
+ command -v setsid >/dev/null 2>&1 && detach="setsid"
318
328
  home="${HOME:-}"
319
329
  config_dir="${CLAUDE_CONFIG_DIR:-$home/.claude}"
320
330
  root=$(nudge_repo_root "$cwd" 2>/dev/null) || root="$cwd"
@@ -327,7 +337,9 @@ storage_upkeep_async() {
327
337
  # Background the fully redirected subshell; an inner `&` leaves this shell
328
338
  # holding the hook's captured stdout open until the dispatcher exits. The
329
339
  # storage verb takes its project from the working directory: run it at the root.
330
- ( cd "$root" 2>/dev/null && nohup "$run" storage --action upkeep </dev/null >/dev/null 2>&1 ) >/dev/null 2>&1 &
340
+ # setsid (absent on macOS) moves the upkeep out of the hook's session, so a harness that
341
+ # signals the hook's process group when the hook exits does not take the upkeep with it.
342
+ ( cd "$root" 2>/dev/null && nohup $detach "$run" storage --action upkeep </dev/null >/dev/null 2>&1 ) >/dev/null 2>&1 3>&- 5>&- &
331
343
  return 0
332
344
  done
333
345
  return 0
@@ -377,7 +389,7 @@ nudge_repo_root() {
377
389
  # file that cannot be read, is empty or holds anything else is `off`.
378
390
  nudge_setting() {
379
391
  local root="${1:-}" file line=""
380
- for file in "${root:+$root/.doflow/prompt-nudge}" "$DOFLOW_HOME/prompt-nudge"; do
392
+ for file in "${root:+$root/.doflow/prompt-nudge}" "${DOFLOW_HOME:+$DOFLOW_HOME/prompt-nudge}"; do
381
393
  [ -n "$file" ] && [ -e "$file" ] || continue
382
394
  line=""
383
395
  { IFS= read -r line || true; } 2>/dev/null < "$file" || line=""
@@ -404,17 +416,20 @@ nudge_safe_id() {
404
416
  return 0
405
417
  }
406
418
 
407
- # Print the marker path for a session id. The caller checks nudge_safe_id first.
419
+ # Print the marker path for a session id. The caller checks nudge_safe_id first. With no config
420
+ # home there is no marker path and nothing is printed.
408
421
  nudge_marker_file() {
422
+ [ -n "$STATE_DIR" ] || return 0
409
423
  printf '%s\n' "$STATE_DIR/nudge/$1"
410
424
  }
411
425
 
412
426
  # Create the marker for <id> holding <nudged|suppressed>. Succeeds only when this call
413
427
  # created it: the create is exclusive, so a second call for the same id fails and
414
428
  # leaves the first content. After a create, markers untouched for over 30 days are
415
- # removed. Silent on every failure.
429
+ # removed. Silent on every failure. With no config home it creates nothing and returns 0 at once.
416
430
  nudge_mark() {
417
- local id="${1:-}" word="${2:-}" dir="$STATE_DIR/nudge" file
431
+ local id="${1:-}" word="${2:-}" dir="${STATE_DIR:+$STATE_DIR/nudge}" file
432
+ [ -n "$dir" ] || return 0
418
433
  nudge_safe_id "$id" || return 1
419
434
  case "$word" in nudged|suppressed) ;; *) return 1 ;; esac
420
435
  file="$dir/$id"
@@ -450,7 +465,8 @@ nudge_feature_active() {
450
465
  # S3: succeed when a `/do-*` skill already ran this session, read from the run ledger:
451
466
  # the lexically last <config>/state/runs/*.jsonl, whose last line's timestamp is not
452
467
  # earlier than the session's captured_at (both YYYY-MM-DDTHH:MM:SSZ). Config dir:
453
- # $DOFLOW_CONFIG_DIR, else the nearest `.doflow` at or above <cwd>, else $HOME/.doflow.
468
+ # $DOFLOW_CONFIG_DIR, else the nearest non-nested `.doflow` at or above <cwd>, else $HOME/.doflow
469
+ # (none when HOME is unset or empty).
454
470
  # Without a captured_at the ledger counts when it is named for today's UTC date; a last
455
471
  # line without a usable timestamp counts too. No ledger, or an empty one, does not.
456
472
  nudge_ledger_active() {
@@ -460,10 +476,19 @@ nudge_ledger_active() {
460
476
  if [ -n "${DOFLOW_CONFIG_DIR:-}" ]; then
461
477
  config="$DOFLOW_CONFIG_DIR"
462
478
  else
463
- config="$HOME/.doflow"
479
+ config="${HOME:+$HOME/.doflow}"
464
480
  # The ancestor in the walk's own spelling (`\` read as `/`), the form its test succeeded on.
465
- if dir=$(nudge_find_up "$cwd" .doflow -d); then config="${dir//\\//}/.doflow"; fi
481
+ if dir=$(nudge_find_up "$cwd" .doflow -d); then
482
+ while :; do
483
+ dir="${dir//\\//}"
484
+ case "$dir/" in
485
+ */.doflow/*) dir=$(nudge_find_up "${dir%/*}" .doflow -d) || break ;;
486
+ *) config="$dir/.doflow"; break ;;
487
+ esac
488
+ done
489
+ fi
466
490
  fi
491
+ [ -n "$config" ] || return 1
467
492
  for f in "$config"/state/runs/*.jsonl; do
468
493
  [ -f "$f" ] && ledger="$f"
469
494
  done
@@ -491,7 +516,7 @@ nudge_registry() {
491
516
  "${policy_dir:+$policy_dir/../../../runtime/core/registry/workflows.json}" \
492
517
  "${policy_dir:+$policy_dir/../../../../registry/workflows.json}" \
493
518
  "${root:+$root/.doflow/runtime/core/registry/workflows.json}" \
494
- "$HOME/.doflow/runtime/core/registry/workflows.json"; do
519
+ "${HOME:+$HOME/.doflow/runtime/core/registry/workflows.json}"; do
495
520
  if [ -n "$candidate" ] && [ -f "$candidate" ]; then
496
521
  printf '%s\n' "$candidate"
497
522
  return 0
@@ -1,4 +1,6 @@
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
3
+ _DOFLOW_SRC=${0//\\//}; case $_DOFLOW_SRC in */*) _DOFLOW_POLDIR=${_DOFLOW_SRC%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
2
4
  # mcp-tool-guard.sh — Canonical Policy Library: PreToolUse(mcp_*) hook
3
5
  #
4
6
  # Intercepts every MCP tool call and blocks matches against mcp-policy.conf, the
@@ -13,57 +15,67 @@
13
15
  # Canonical Policy Script Contract (design.md §4):
14
16
  # env DOFLOW_PROJECT_DIR, DOFLOW_AGENT (both optional; not required to
15
17
  # evaluate this policy)
16
- # stdin a PreToolUse-shaped JSON payload; tool name is read from the union
17
- # of field names harnesses use (tool_name/tool/toolName/name), since
18
- # a native front door (Claude/Codex/Kiro) execs this script directly
19
- # with no payload translation of its own.
20
- # exit 0 = allow, non-zero = deny with the reason on stderr.
21
- #
22
- # Reconciliation note (022-normalize-hooks, Phase A): MCP tool-name
23
- # vocabularies differ per harness — Claude/Codex/Kiro use a double-underscore
24
- # "mcp__<server>__<tool>" convention, Gemini documents a single-underscore
25
- # "mcp_<server>_<tool>" convention. A single-underscore prefix check ("^mcp_")
26
- # matches both conventions (the double-underscore form is a superset match of
27
- # the single-underscore prefix), so this script uses that one generic check
28
- # instead of hardcoding either harness's exact convention.
18
+ # stdin a native payload with envelope v1 under doflow_event; only the
19
+ # envelope's operation and tool fields are used.
20
+ # exit exit 2 + doflow_decide deny = deny; other faults per IC-011.
29
21
  #
30
22
  # mcp-policy.conf's shape (TAB-separated regex<TAB>reason, '#'-comments,
31
23
  # blank lines skipped) is identical across every harness that ships one today
32
- # (claude/codex/gemini/kiro) — reconciliation found no divergence to resolve
24
+ # (claude/codex/kiro) — reconciliation found no divergence to resolve
33
25
  # there.
34
26
 
35
27
  set -uo pipefail
36
28
 
37
- command -v jq >/dev/null 2>&1 || exit 0 # no jq -> cannot evaluate -> allow
38
-
39
29
  INPUT=$(cat)
30
+ if [ -f "$_DOFLOW_POLDIR/contract.sh" ]; then
31
+ . "$_DOFLOW_POLDIR/contract.sh"
32
+ else
33
+ doflow_decision_init() { :; }
34
+ doflow_decide() { :; }
35
+ doflow_read_envelope() { DF_ENV_CLASS=missing; DF_ENV_CODE=contract-missing; }
36
+ ( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure mcp-tool-guard contract-missing ) >/dev/null 2>&1 || true
37
+ if [[ "${DOFLOW_AGENT:-}" =~ ^[a-z]+$ ]]; then
38
+ printf '[mcp-tool-guard] DoFlow hooks out of step; run: doflow update -t %s\n' "$DOFLOW_AGENT" >&2
39
+ else
40
+ printf '[mcp-tool-guard] DoFlow hooks out of step; run: doflow update\n' >&2
41
+ fi
42
+ doflow_decide deny contract-missing
43
+ exit 2
44
+ fi
45
+ doflow_decision_init mcp-tool-guard 1
46
+ command -v jq >/dev/null 2>&1 || {
47
+ doflow_decide error dependency-missing:jq
48
+ ( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure mcp-tool-guard dependency-missing:jq ) >/dev/null 2>&1 || true
49
+ exit 0
50
+ }
51
+ DF_ENV_CLASS=missing DF_ENV_CODE=envelope-missing
52
+ doflow_read_envelope || true
40
53
 
41
54
  TOOL_NAME=""
42
- for field in '.tool_name' '.tool' '.toolName' '.name'; do
43
- TOOL_NAME=$(printf '%s' "$INPUT" | jq -r "${field} // empty" 2>/dev/null)
44
- [ -n "$TOOL_NAME" ] && break
45
- done
46
-
47
- # Fast exit for non-MCP tool events (also covers "tool name unresolved").
48
- # "mcp_" (single underscore) matches both Claude/Codex/Kiro's "mcp__" and
49
- # Gemini's "mcp_" naming conventions. Matched case-insensitively: the caller
50
- # (stream-hook-runner.js's MCP_TOOL_PATTERN) classifies case-insensitively
51
- # before ever routing here, so this check must not be stricter than the
52
- # classification that decided to invoke it (022-code-review finding).
53
- shopt -s nocasematch 2>/dev/null || true
54
- case "$TOOL_NAME" in
55
- mcp_*) ;;
56
- *) exit 0 ;;
57
- esac
58
- shopt -u nocasematch 2>/dev/null || true
55
+ if [ "$DF_ENV_CLASS" = v1 ]; then
56
+ [ "$DF_ENV_OP" = mcp ] || exit 0
57
+ TOOL_NAME=$DF_ENV_TOOL
58
+ elif [ "$DF_ENV_CLASS" = unsupported ]; then
59
+ doflow_decide unsupported envelope-version
60
+ ( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure mcp-tool-guard unsupported:envelope-version ) >/dev/null 2>&1 || true
61
+ exit 0
62
+ else
63
+ if [ "${DF_ENV_CODE:-envelope-missing}" != contract-missing ]; then
64
+ ( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure mcp-tool-guard envelope-missing ) >/dev/null 2>&1 || true
65
+ fi
66
+ if [[ "${DOFLOW_AGENT:-}" =~ ^[a-z]+$ ]]; then printf '[mcp-tool-guard] DoFlow hooks out of step; run: doflow update -t %s\n' "$DOFLOW_AGENT" >&2; else printf '[mcp-tool-guard] DoFlow hooks out of step; run: doflow update\n' >&2; fi
67
+ doflow_decide deny "${DF_ENV_CODE:-envelope-missing}"
68
+ exit 2
69
+ fi
59
70
 
60
- POLICY_FILE="$(dirname "$0")/mcp-policy.conf"
71
+ POLICY_FILE="$_DOFLOW_POLDIR/mcp-policy.conf"
61
72
 
62
73
  # If policy file is missing, allow everything (fail open — don't block the agent).
63
74
  if [ ! -f "$POLICY_FILE" ]; then
64
75
  # The policy file ships with DoFlow, so a missing one means a broken install: record it on this
65
76
  # machine (feature 046, IC-018) and fail open exactly as before. Subshell, output discarded.
66
- ( . "$(dirname "$0")/capture-failure.sh"; doflow_capture_failure mcp-tool-guard policy-file-missing ) >/dev/null 2>&1 || true
77
+ ( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure mcp-tool-guard policy-file-missing ) >/dev/null 2>&1 || true
78
+ doflow_decide error mcp-policy-missing
67
79
  exit 0
68
80
  fi
69
81
 
@@ -83,6 +95,7 @@ while IFS=$'\t' read -r pattern reason || [ -n "$pattern" ]; do
83
95
 
84
96
  if [ "$matched" = "true" ]; then
85
97
  echo "[mcp-tool-guard] ${reason:-MCP tool call blocked by mcp-tool-guard} (tool: $TOOL_NAME)" >&2
98
+ doflow_decide deny blocked-pattern
86
99
  exit 2
87
100
  fi
88
101
  done < "$POLICY_FILE"