@khoavu882/doflow 2.0.0-beta.5 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/README.md +16 -16
  2. package/bin/doflow.js +22 -12
  3. package/core/.antigravity-plugin/plugin.json +1 -2
  4. package/core/.claude-plugin/plugin.json +1 -1
  5. package/core/.codex-plugin/plugin.json +1 -1
  6. package/core/.plugin/plugin.json +1 -1
  7. package/core/harnesses/claude/hooks/lib.sh +43 -24
  8. package/core/harnesses/claude/hooks/mcp-tool-guard.sh +4 -1
  9. package/core/harnesses/claude/hooks/permission-audit.sh +3 -0
  10. package/core/harnesses/claude/hooks/post-compact.sh +35 -32
  11. package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
  12. package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
  13. package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
  14. package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
  15. package/core/harnesses/claude/hooks/pre-implement-gate.sh +4 -1
  16. package/core/harnesses/claude/hooks/session-end.sh +23 -10
  17. package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
  18. package/core/harnesses/claude/settings/settings.json +26 -9
  19. package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
  20. package/core/harnesses/codex/agents/core-implementer.toml +1 -0
  21. package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
  22. package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
  23. package/core/harnesses/codex/agents/research-writer.toml +1 -1
  24. package/core/harnesses/codex/agents/reviewer.toml +10 -0
  25. package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
  26. package/core/harnesses/codex/agents/system-architect.toml +1 -1
  27. package/core/harnesses/codex/hooks/hooks.json +0 -10
  28. package/core/harnesses/codex/hooks/lib.sh +44 -25
  29. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +4 -1
  30. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
  31. package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
  32. package/core/harnesses/codex/hooks/pre-implement-gate.sh +4 -1
  33. package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
  34. package/core/harnesses/codex/hooks/subagent-audit.sh +1 -0
  35. package/core/harnesses/copilot/hooks/doflow-lib.sh +94 -0
  36. package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
  37. package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
  38. package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
  39. package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
  40. package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
  41. package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
  42. package/core/harnesses/copilot/hooks/doflow.json +51 -0
  43. package/core/harnesses/kiro/agents/doflow.json +1 -11
  44. package/core/harnesses/kiro/hooks/doflow.json +0 -10
  45. package/core/harnesses/kiro/hooks/lib.sh +26 -6
  46. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +8 -3
  47. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +8 -3
  48. package/core/harnesses/kiro/hooks/session-start.sh +1 -0
  49. package/core/harnesses/kiro/hooks/stop-check.sh +1 -0
  50. package/core/harnesses/pi/extensions/doflow-guard.js +11 -2
  51. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +1 -2
  52. package/core/harnesses/shared/hooks/adapters/antigravity.js +1 -1
  53. package/core/harnesses/shared/hooks/bridge/bridge.sh +126 -23
  54. package/core/harnesses/shared/hooks/bridge/envelope.jq +87 -18
  55. package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
  56. package/core/harnesses/shared/hooks/bridge/respond.sh +16 -2
  57. package/core/harnesses/shared/hooks/policies/capture-failure.sh +49 -16
  58. package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
  59. package/core/harnesses/shared/hooks/policies/contract.sh +3 -0
  60. package/core/harnesses/shared/hooks/policies/deny-json.sh +20 -7
  61. package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
  62. package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
  63. package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
  64. package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
  65. package/core/harnesses/shared/hooks/policies/lib.sh +63 -40
  66. package/core/harnesses/shared/hooks/policies/mcp-policy.conf +1 -1
  67. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +7 -8
  68. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +132 -57
  69. package/core/harnesses/shared/hooks/policies/session-context.sh +30 -1
  70. package/core/harnesses/shared/hooks/policies/stop-check.sh +27 -15
  71. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +6 -3
  72. package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
  73. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +60 -155
  74. package/core/harnesses/shared/hooks/stream-hook-runner.js +58 -20
  75. package/core/harnesses/shared/locator/doflow-run +2 -3
  76. package/core/registry/advice.json +3 -3
  77. package/core/registry/assets.json +55 -82
  78. package/core/registry/capabilities.json +12 -0
  79. package/core/registry/contracts.json +58 -31
  80. package/core/registry/contribution-points.json +35 -0
  81. package/core/registry/gates.json +32 -0
  82. package/core/registry/guidance-caps.json +40 -0
  83. package/core/registry/harnesses.json +1445 -366
  84. package/core/registry/intake.json +53 -0
  85. package/core/registry/lifecycle.json +599 -996
  86. package/core/registry/mcp.json +5 -1
  87. package/core/registry/models.json +7 -1
  88. package/core/registry/package-templates/README.md +19 -0
  89. package/core/registry/package-templates/agent/files/agent.md +9 -0
  90. package/core/registry/package-templates/agent/template.json +4 -0
  91. package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
  92. package/core/registry/package-templates/capability-provider/template.json +11 -0
  93. package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
  94. package/core/registry/package-templates/debate-preset/template.json +4 -0
  95. package/core/registry/package-templates/intake-category/files/category.json +8 -0
  96. package/core/registry/package-templates/intake-category/template.json +4 -0
  97. package/core/registry/package-templates/review-preset/files/preset.json +30 -0
  98. package/core/registry/package-templates/review-preset/template.json +4 -0
  99. package/core/registry/package-templates/skill/files/SKILL.md +8 -0
  100. package/core/registry/package-templates/skill/template.json +4 -0
  101. package/core/registry/package-templates/worker/files/worker.json +92 -0
  102. package/core/registry/package-templates/worker/template.json +11 -0
  103. package/core/registry/packages/doflow/doflow-package.json +15 -0
  104. package/core/registry/packages/doflow/presets/debate-3.json +26 -0
  105. package/core/registry/protocols.json +61 -0
  106. package/core/registry/routes.json +17 -0
  107. package/core/registry/rules.json +431 -0
  108. package/core/registry/settings.json +272 -0
  109. package/core/registry/storage.json +687 -31
  110. package/core/registry/telemetry.json +236 -0
  111. package/core/registry/transcripts.json +142 -0
  112. package/core/registry/verification.json +76 -6
  113. package/core/registry/workflows.json +55 -0
  114. package/core/shared/agent-specs/core-implementer.md +3 -0
  115. package/core/shared/agent-specs/delivery-lead.md +68 -0
  116. package/core/shared/agent-specs/quality-guardian.md +5 -1
  117. package/core/shared/agent-specs/research-writer.md +10 -3
  118. package/core/shared/agent-specs/reviewer.md +53 -0
  119. package/core/shared/agent-specs/spec-analyst.md +5 -6
  120. package/core/shared/agent-specs/system-architect.md +5 -1
  121. package/core/shared/guidance/DOFLOW_CORE.md +1 -5
  122. package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
  123. package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
  124. package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
  125. package/core/shared/guidance/pointers/codex.md +1 -4
  126. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
  127. package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
  128. package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
  129. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
  130. package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
  131. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
  132. package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
  133. package/core/shared/guidance/references/ORCHESTRATION.md +3 -2
  134. package/core/shared/guidance/references/WORKFLOW_HANDOFF.md +19 -1
  135. package/core/shared/guidance/rules/RULES.md +45 -0
  136. package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
  137. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
  138. package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
  139. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
  140. package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
  141. package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
  142. package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
  143. package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
  144. package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
  145. package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
  146. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
  147. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +49 -5
  148. package/core/shared/scripts/doflow/bin/doflow-run +152 -34
  149. package/core/shared/skills/do/SKILL.md +14 -12
  150. package/core/shared/skills/do/references/advice_calls.md +26 -0
  151. package/core/shared/skills/do/references/pm_routing.md +1 -2
  152. package/core/shared/skills/do/references/program_mode.md +31 -0
  153. package/core/shared/skills/do-brainstorm/SKILL.md +45 -97
  154. package/core/shared/skills/do-brainstorm/references/handoff_branches.md +36 -0
  155. package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
  156. package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
  157. package/core/shared/skills/do-code-review/SKILL.md +48 -148
  158. package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
  159. package/core/shared/skills/do-code-review/references/tools.md +90 -0
  160. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
  161. package/core/shared/skills/do-design/SKILL.md +23 -20
  162. package/core/shared/skills/do-diagnose/SKILL.md +18 -6
  163. package/core/shared/skills/do-document/SKILL.md +12 -1
  164. package/core/shared/skills/do-document/references/deep_research.md +1 -2
  165. package/core/shared/skills/do-document/references/embedded-research.md +19 -7
  166. package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
  167. package/core/shared/skills/do-execute-plan/SKILL.md +19 -60
  168. package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
  169. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
  170. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +26 -1
  171. package/core/shared/skills/do-execute-plan/references/run_position.md +16 -2
  172. package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
  173. package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
  174. package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
  175. package/core/shared/skills/do-flow/SKILL.md +10 -11
  176. package/core/shared/skills/do-flow/references/task_classes.md +5 -5
  177. package/core/shared/skills/do-git/SKILL.md +4 -0
  178. package/core/shared/skills/do-implement/SKILL.md +13 -14
  179. package/core/shared/skills/do-plan/SKILL.md +34 -20
  180. package/core/shared/skills/do-test/SKILL.md +7 -4
  181. package/core/shared/templates/doflow/constitution-template.md +9 -3
  182. package/core/shared/templates/doflow/data-model-template.md +1 -1
  183. package/core/shared/templates/doflow/design-template.md +113 -16
  184. package/core/shared/templates/doflow/plan-template.md +11 -10
  185. package/core/shared/templates/doflow/question-log-template.md +14 -2
  186. package/core/shared/templates/doflow/requirement-template.md +1 -1
  187. package/core/shared/workflows/do-flow-chain.md +2 -0
  188. package/core/worker-evidence/antigravity/checks.json +14 -0
  189. package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
  190. package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
  191. package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
  192. package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
  193. package/core/worker-evidence/codex/checks.json +38 -0
  194. package/package.json +10 -6
  195. package/src/adapters/antigravity/index.js +143 -66
  196. package/src/adapters/claude/index.js +46 -5
  197. package/src/adapters/codex/agents.js +25 -15
  198. package/src/adapters/codex/hooks.js +39 -3
  199. package/src/adapters/codex/index.js +61 -13
  200. package/src/adapters/codex/native-projection.js +6 -2
  201. package/src/adapters/copilot/index.js +58 -23
  202. package/src/adapters/copy-tree.js +291 -46
  203. package/src/adapters/guidance-manifest.js +71 -0
  204. package/src/adapters/guidance-pointer.js +19 -0
  205. package/src/adapters/hook-commands.js +6 -10
  206. package/src/adapters/index.js +1 -0
  207. package/src/adapters/kiro/index.js +23 -12
  208. package/src/adapters/opencode/index.js +8 -8
  209. package/src/adapters/pi/hooks.js +2 -1
  210. package/src/adapters/pi/index.js +14 -7
  211. package/src/adapters/resolve-source.js +26 -2
  212. package/src/cli/commands/install.js +2 -1
  213. package/src/cli/commands/reconcile.js +53 -9
  214. package/src/cli/commands/remove.js +2 -2
  215. package/src/cli/commands/rollback.js +6 -3
  216. package/src/cli/commands/self-update.js +18 -9
  217. package/src/cli/commands/status.js +22 -3
  218. package/src/cli/commands/ui.js +99 -0
  219. package/src/cli/commands/update.js +2 -1
  220. package/src/cli/index.js +337 -32
  221. package/src/cli/runtime-commands.js +220 -60
  222. package/src/cli/shared.js +0 -2
  223. package/src/helper/git.js +1 -1
  224. package/src/helper/guardrails.js +1 -1
  225. package/src/helper/marker-merge.js +31 -13
  226. package/src/helper/package-ids.js +37 -0
  227. package/src/helper/semver.js +94 -0
  228. package/src/install/backup.js +105 -15
  229. package/src/install/context.js +1 -1
  230. package/src/install/targets.js +31 -16
  231. package/src/lifecycle/coverage.js +4 -16
  232. package/src/lifecycle/hook-tier.js +160 -0
  233. package/src/lifecycle/index.js +412 -78
  234. package/src/lifecycle/retired-harnesses.js +318 -0
  235. package/src/lifecycle/view.js +35 -15
  236. package/src/registry/index.js +551 -26
  237. package/src/registry/worker-ids.js +45 -0
  238. package/src/release/build-package.js +0 -3
  239. package/src/release/docs-blocks.js +472 -0
  240. package/src/release/preflight.js +425 -0
  241. package/src/release/rehearse.js +401 -0
  242. package/src/release/release-workflow.js +733 -0
  243. package/src/release/sync-plugin-versions.js +43 -7
  244. package/src/runtime/advice/bench-gate.js +25 -0
  245. package/src/runtime/advice/cli.js +59 -16
  246. package/src/runtime/advice/client.js +32 -9
  247. package/src/runtime/advice/config.js +98 -133
  248. package/src/runtime/advice/doctor.js +1 -1
  249. package/src/runtime/advice/elevation.js +97 -0
  250. package/src/runtime/advice/endpoint-guard.js +9 -3
  251. package/src/runtime/advice/mode.js +37 -0
  252. package/src/runtime/advice/record.js +18 -5
  253. package/src/runtime/advice/registry.js +4 -1
  254. package/src/runtime/advice/shadow-config.js +229 -0
  255. package/src/runtime/advice/shadow-dispatcher.js +276 -0
  256. package/src/runtime/brief-rules.js +81 -0
  257. package/src/runtime/brief-tools.js +111 -34
  258. package/src/runtime/candidate.js +20 -11
  259. package/src/runtime/capabilities/executor.js +450 -0
  260. package/src/runtime/capabilities/loopback.js +41 -0
  261. package/src/runtime/capabilities/sanitizer.js +88 -0
  262. package/src/runtime/capability-router.js +135 -3
  263. package/src/runtime/checkouts.js +73 -11
  264. package/src/runtime/claims.js +13 -7
  265. package/src/runtime/cli.js +196 -19
  266. package/src/runtime/config-home.js +42 -0
  267. package/src/runtime/context/arbitrate.js +767 -0
  268. package/src/runtime/context/delivery-store.js +4 -6
  269. package/src/runtime/context/emission-rules.js +118 -0
  270. package/src/runtime/context/identity.js +227 -0
  271. package/src/runtime/context/pointer.js +67 -12
  272. package/src/runtime/context/primary-command.js +117 -0
  273. package/src/runtime/context/primary.js +344 -0
  274. package/src/runtime/context/summary-store.js +655 -0
  275. package/src/runtime/context-pack.js +158 -79
  276. package/src/runtime/decision-register.js +13 -4
  277. package/src/runtime/dispatch/admission.js +392 -0
  278. package/src/runtime/dispatch/attempt-end.js +274 -0
  279. package/src/runtime/dispatch/command.js +628 -0
  280. package/src/runtime/dispatch/controls.js +904 -0
  281. package/src/runtime/dispatch/envelope.js +276 -0
  282. package/src/runtime/dispatch/grants.js +310 -0
  283. package/src/runtime/dispatch/integrate.js +617 -0
  284. package/src/runtime/dispatch/loop.js +1835 -0
  285. package/src/runtime/dispatch/store.js +352 -0
  286. package/src/runtime/dispatch/verify-run.js +201 -0
  287. package/src/runtime/evidence-ledger.js +52 -7
  288. package/src/runtime/failure/capture.js +3 -1
  289. package/src/runtime/failure/cli.js +25 -9
  290. package/src/runtime/failure/home.js +57 -30
  291. package/src/runtime/failure/store.js +7 -2
  292. package/src/runtime/feature-pointer.js +174 -0
  293. package/src/runtime/feature-resolve.js +13 -2
  294. package/src/runtime/fleet/command.js +77 -0
  295. package/src/runtime/fleet/projects.js +178 -0
  296. package/src/runtime/fleet/tree.js +383 -0
  297. package/src/runtime/freshness.js +33 -3
  298. package/src/runtime/git-memo.js +46 -0
  299. package/src/runtime/guidance/ablation.js +427 -0
  300. package/src/runtime/health.js +624 -18
  301. package/src/runtime/history-compactor.js +13 -3
  302. package/src/runtime/implementation-gate.js +281 -26
  303. package/src/runtime/intake/engine.js +677 -0
  304. package/src/runtime/intake/index.js +136 -0
  305. package/src/runtime/intake/manifest.js +140 -0
  306. package/src/runtime/intake/taxonomy.js +206 -0
  307. package/src/runtime/inventory/coverage.js +1 -1
  308. package/src/runtime/inventory/index.js +1 -1
  309. package/src/runtime/inventory/precedence.js +2 -2
  310. package/src/runtime/inventory/siblings.js +6 -4
  311. package/src/runtime/knowledge/code-corpus.js +277 -0
  312. package/src/runtime/knowledge/code-lexical.js +130 -0
  313. package/src/runtime/knowledge/code-retrieval.js +307 -0
  314. package/src/runtime/knowledge/code-validation.js +106 -0
  315. package/src/runtime/knowledge/gp3-gate.js +74 -0
  316. package/src/runtime/knowledge/graph-adapter.js +288 -0
  317. package/src/runtime/knowledge/graph-fallback.js +394 -0
  318. package/src/runtime/knowledge/hybrid.js +136 -8
  319. package/src/runtime/knowledge/retrieval.js +34 -1
  320. package/src/runtime/knowledge/rtk-compress.js +77 -0
  321. package/src/runtime/knowledge/semble-bridge.py +106 -0
  322. package/src/runtime/knowledge/semble-lifecycle.js +114 -0
  323. package/src/runtime/knowledge/semble-provider.js +365 -0
  324. package/src/runtime/lifecycle/cli.js +88 -10
  325. package/src/runtime/lifecycle/event-store.js +8 -6
  326. package/src/runtime/lifecycle/followup.js +38 -7
  327. package/src/runtime/lifecycle/overview.js +26 -2
  328. package/src/runtime/lifecycle/report-store.js +8 -10
  329. package/src/runtime/lifecycle/retention.js +95 -31
  330. package/src/runtime/lifecycle/root.js +9 -1
  331. package/src/runtime/lifecycle/status.js +34 -17
  332. package/src/runtime/lifecycle/store-upkeep.js +56 -7
  333. package/src/runtime/mask.js +134 -7
  334. package/src/runtime/mcp-consultations.js +40 -6
  335. package/src/runtime/model-router.js +79 -7
  336. package/src/runtime/models/catalogue.js +191 -0
  337. package/src/runtime/models/command.js +153 -0
  338. package/src/runtime/off-words.js +12 -0
  339. package/src/runtime/outcome.js +2 -2
  340. package/src/runtime/packages/command.js +1009 -0
  341. package/src/runtime/packages/contributions.js +116 -0
  342. package/src/runtime/packages/digest.js +132 -0
  343. package/src/runtime/packages/fetch.js +182 -0
  344. package/src/runtime/packages/grants.js +192 -0
  345. package/src/runtime/packages/index-file.js +134 -0
  346. package/src/runtime/packages/instruction.js +90 -0
  347. package/src/runtime/packages/manifest.js +331 -0
  348. package/src/runtime/packages/points.js +487 -0
  349. package/src/runtime/packages/programs.js +216 -0
  350. package/src/runtime/packages/scaffold.js +277 -0
  351. package/src/runtime/packages/source.js +90 -0
  352. package/src/runtime/packages/state.js +164 -0
  353. package/src/runtime/packages/store.js +449 -0
  354. package/src/runtime/packages/tar.js +106 -0
  355. package/src/runtime/packages/view.js +406 -0
  356. package/src/runtime/plan-check.js +59 -0
  357. package/src/runtime/plan-content.js +324 -0
  358. package/src/runtime/policy-init.js +118 -0
  359. package/src/runtime/profiles/doctor.js +96 -0
  360. package/src/runtime/profiles/resolve.js +244 -0
  361. package/src/runtime/profiles/rollback.js +254 -0
  362. package/src/runtime/profiles/sampler.js +41 -0
  363. package/src/runtime/readiness-record.js +16 -11
  364. package/src/runtime/readiness.js +46 -5
  365. package/src/runtime/research-request.js +50 -25
  366. package/src/runtime/retrieval-plan.js +10 -30
  367. package/src/runtime/retrieval-record.js +75 -5
  368. package/src/runtime/review/command.js +246 -0
  369. package/src/runtime/review/dominance.js +68 -0
  370. package/src/runtime/review/findings.js +434 -0
  371. package/src/runtime/review/identity.js +255 -0
  372. package/src/runtime/review/protocol-command.js +109 -0
  373. package/src/runtime/review/protocols.js +405 -0
  374. package/src/runtime/review/resolve-protocol.js +302 -0
  375. package/src/runtime/review/start.js +530 -0
  376. package/src/runtime/roadmap/attendance.js +137 -0
  377. package/src/runtime/roadmap/facts.js +479 -0
  378. package/src/runtime/roadmap/gates.js +273 -0
  379. package/src/runtime/roadmap/loop.js +1719 -0
  380. package/src/runtime/roadmap/merge.js +390 -0
  381. package/src/runtime/roadmap/rows.js +1122 -0
  382. package/src/runtime/roadmap/seed.js +1063 -0
  383. package/src/runtime/roadmap/worktree-cleanup.js +147 -0
  384. package/src/runtime/rules-report.js +336 -0
  385. package/src/runtime/scaffold/artifacts.js +60 -9
  386. package/src/runtime/scaffold/generate.js +21 -9
  387. package/src/runtime/settings/autopilot.js +106 -0
  388. package/src/runtime/settings/cli.js +280 -0
  389. package/src/runtime/settings/config-write.js +314 -0
  390. package/src/runtime/settings/files.js +271 -0
  391. package/src/runtime/settings/legacy.js +154 -0
  392. package/src/runtime/settings/lexical.js +56 -0
  393. package/src/runtime/settings/prepared-run.js +269 -0
  394. package/src/runtime/settings/project-layers.js +118 -0
  395. package/src/runtime/settings/refs.js +288 -0
  396. package/src/runtime/settings/registry.js +553 -0
  397. package/src/runtime/settings/resolve.js +713 -0
  398. package/src/runtime/settings/shared.js +37 -0
  399. package/src/runtime/settings/worker-billing.js +107 -0
  400. package/src/runtime/settings/write.js +269 -0
  401. package/src/runtime/slot-command.js +78 -0
  402. package/src/runtime/slots.js +671 -0
  403. package/src/runtime/source-version.js +1 -0
  404. package/src/runtime/state-root.js +217 -0
  405. package/src/runtime/storage/cli.js +12 -5
  406. package/src/runtime/storage/engine.js +9 -2
  407. package/src/runtime/storage/registry.js +14 -1
  408. package/src/runtime/storage/roots.js +66 -16
  409. package/src/runtime/storage/rules.js +82 -10
  410. package/src/runtime/storage/upkeep.js +10 -2
  411. package/src/runtime/storage/work-status.js +245 -26
  412. package/src/runtime/task-attempts.js +589 -69
  413. package/src/runtime/task-classifier.js +85 -14
  414. package/src/runtime/task-graph.js +373 -0
  415. package/src/runtime/task-run.js +778 -0
  416. package/src/runtime/task-scope.js +176 -55
  417. package/src/runtime/task-sources.js +147 -0
  418. package/src/runtime/task-state.js +373 -64
  419. package/src/runtime/team/admission.js +301 -0
  420. package/src/runtime/team/envelope.js +324 -0
  421. package/src/runtime/team/review-guard.js +156 -0
  422. package/src/runtime/trace/analyze.js +427 -0
  423. package/src/runtime/trace/baseline.js +770 -0
  424. package/src/runtime/trace/ledger.js +63 -140
  425. package/src/runtime/trace/otlp-export.js +568 -0
  426. package/src/runtime/trace/otlp-map.js +481 -0
  427. package/src/runtime/trace/spans.js +745 -0
  428. package/src/runtime/trace/telemetry.js +225 -0
  429. package/src/runtime/trace/views.js +1 -0
  430. package/src/runtime/transcripts/command.js +98 -0
  431. package/src/runtime/transcripts/cursor.js +326 -0
  432. package/src/runtime/transcripts/read.js +126 -0
  433. package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
  434. package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
  435. package/src/runtime/transcripts/readers/copilot-events.js +90 -0
  436. package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
  437. package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
  438. package/src/runtime/transcripts/registry.js +161 -0
  439. package/src/runtime/transcripts/stats.js +161 -0
  440. package/src/runtime/verb-view.js +267 -0
  441. package/src/runtime/verification/check-key.js +628 -0
  442. package/src/runtime/verification/contract-runner.js +546 -11
  443. package/src/runtime/verification/engine.js +499 -54
  444. package/src/runtime/verification/impact.js +617 -0
  445. package/src/runtime/verification/inflight.js +205 -0
  446. package/src/runtime/verification/registry.js +176 -0
  447. package/src/runtime/verification/reuse.js +184 -0
  448. package/src/runtime/verification/telemetry-emit.js +254 -0
  449. package/src/runtime/verification/test-selection.js +67 -7
  450. package/src/runtime/worker/active.js +90 -0
  451. package/src/runtime/worker/cancel.js +222 -0
  452. package/src/runtime/worker/catalogue.js +122 -0
  453. package/src/runtime/worker/command.js +677 -0
  454. package/src/runtime/worker/evidence.js +288 -0
  455. package/src/runtime/worker/launch.js +256 -0
  456. package/src/runtime/worker/models.js +137 -0
  457. package/src/runtime/worker/parsers.js +218 -0
  458. package/src/runtime/worker/probes/index.js +706 -0
  459. package/src/runtime/worker/process-tree.js +415 -0
  460. package/src/runtime/worker/quota.js +43 -0
  461. package/src/runtime/worker/readiness.js +713 -0
  462. package/src/runtime/worker/run-store.js +166 -0
  463. package/src/runtime/worker/supervisor.js +541 -0
  464. package/src/runtime/worker/worktree-check.js +252 -0
  465. package/src/runtime/workflow-engine.js +5 -1
  466. package/src/runtime/workflow-orchestrator.js +610 -67
  467. package/src/runtime/worktree.js +149 -22
  468. package/src/state/index.js +1 -1
  469. package/src/state/lockfile.js +64 -10
  470. package/src/state/run-lock.js +1 -1
  471. package/types/node-commonjs.d.ts +106 -7
  472. package/core/harnesses/claude/hooks/pre-bash-guard.sh +0 -10
  473. package/core/harnesses/codex/hooks/pre-bash-guard.sh +0 -10
  474. package/core/harnesses/gemini/hooks/hooks.json +0 -77
  475. package/core/harnesses/gemini/hooks/lib.sh +0 -302
  476. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -10
  477. package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
  478. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -10
  479. package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
  480. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -10
  481. package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
  482. package/core/harnesses/gemini/hooks/session-end.sh +0 -5
  483. package/core/harnesses/gemini/hooks/session-start.sh +0 -7
  484. package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
  485. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +0 -24
  486. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +0 -91
  487. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +0 -378
  488. package/core/shared/guidance/FLAGS.md +0 -25
  489. package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
  490. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
  491. package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
  492. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
  493. package/src/adapters/gemini/hooks.js +0 -251
  494. package/src/adapters/gemini/index.js +0 -429
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env bash
2
+ # identity.sh — Canonical Policy Library: session role and identity (feature 078, IC-007, IC-009)
3
+ #
4
+ # The only definition of doflow_session_role and doflow_identity (DEC-011). policies/lib.sh sources
5
+ # it from its own directory; the Claude and Codex hooks/lib.sh copies source it through
6
+ # ../../.doflow/shared/hooks/policies/identity.sh.
7
+ #
8
+ # Sourcing this file defines functions only: it sets no shell option, no variable and no trap, and
9
+ # prints nothing. Every function is bash 3.2 safe (no ${var,,}, no associative arrays) and safe
10
+ # under the caller's `set -euo pipefail`.
11
+
12
+ # Sets _DF_ROLE to `main` or `worker` from DOFLOW_SESSION_ROLE, matched case-insensitively, without
13
+ # a subshell. Unset or empty is `main`; any other value is `worker` and writes one stderr line, once
14
+ # per process (a call inside $(...) cannot mark the parent, so each such call still warns).
15
+ _doflow_role_resolve() {
16
+ case "${DOFLOW_SESSION_ROLE:-}" in
17
+ ""|[Mm][Aa][Ii][Nn]) _DF_ROLE=main ;;
18
+ [Ww][Oo][Rr][Kk][Ee][Rr]) _DF_ROLE=worker ;;
19
+ *)
20
+ _DF_ROLE=worker
21
+ if [ -z "${_DF_ROLE_WARNED:-}" ]; then
22
+ echo "[doflow] unknown DOFLOW_SESSION_ROLE; treating session as worker" >&2
23
+ _DF_ROLE_WARNED=1
24
+ fi
25
+ ;;
26
+ esac
27
+ return 0
28
+ }
29
+
30
+ # Print `main` or `worker` for this session, read from DOFLOW_SESSION_ROLE (matched
31
+ # case-insensitively). Unset or empty is `main`; a value that is neither `main` nor
32
+ # `worker` is `worker` and writes one line to stderr. A worker never writes or claims the
33
+ # project's compact summary or warning. Always returns 0. bash 3.2 safe (no ${var,,}).
34
+ doflow_session_role() {
35
+ _doflow_role_resolve
36
+ printf '%s\n' "$_DF_ROLE"
37
+ return 0
38
+ }
39
+
40
+ # Record one failure-capture point for the calling policy, never on stdout or stderr. The policy
41
+ # name is the running script's name without `.sh` or `.impl.sh`; capture-failure.sh replaces a name
42
+ # outside its pattern with `unknown`.
43
+ _doflow_identity_capture() {
44
+ local point="$1" policy="${0##*/}" dir
45
+ policy="${policy%.sh}"
46
+ policy="${policy%.impl}"
47
+ # Inside a function, BASH_SOURCE[0] is the file that defined it: this file's directory.
48
+ _DOFLOW_SRC=${BASH_SOURCE[0]//\\//}; case $_DOFLOW_SRC in */*) dir=${_DOFLOW_SRC%/*} ;; *) dir=. ;; esac
49
+ if declare -F doflow_capture_failure >/dev/null 2>&1; then
50
+ ( doflow_capture_failure "$policy" "$point" ) >/dev/null 2>&1 || true
51
+ else
52
+ ( . "$dir/capture-failure.sh" && doflow_capture_failure "$policy" "$point" ) >/dev/null 2>&1 || true
53
+ fi
54
+ return 0
55
+ }
56
+
57
+ # doflow_identity <session_id> <cwd>
58
+ # Sets DF_ID_RUN, DF_ID_ATTEMPT, DF_ID_LINEAGE, DF_ID_ROLE, DF_ID_WORKTREE, DF_ID_KIND and
59
+ # DF_ID_UNIT per IC-007. Reads only the launcher variables, the payload session_id and cwd; never
60
+ # git or the harness's idea of a main session. Built-ins only, except `pwd -P` in a `cd` subshell
61
+ # when DOFLOW_WORKTREE is set and `mkdir -p` when a launched unit binds. An invalid run or lineage
62
+ # is captured as `identity-invalid` and never reaches a path. Always returns 0.
63
+ doflow_identity() {
64
+ local session_id="${1:-}" cwd="${2:-}" LC_ALL=C
65
+ local run="${DOFLOW_RUN_ID:-}" attempt="${DOFLOW_ATTEMPT:-}" lineage="${DOFLOW_LINEAGE_ID:-}"
66
+ local worktree="${DOFLOW_WORKTREE:-}" invalid=0 run_ok=0 lineage_ok=0 attempt_ok=0
67
+ local sessions dir bound="" had_c=0 mine=0 tries
68
+
69
+ _doflow_role_resolve
70
+ DF_ID_ROLE=$_DF_ROLE
71
+
72
+ # run: id pattern and not `local`; unset is `local`; invalid is unlaunched with lineage solo.
73
+ if [ -z "$run" ]; then
74
+ DF_ID_RUN=local
75
+ elif [ "$run" != local ] && [[ $run =~ ^[A-Za-z0-9][A-Za-z0-9_-]{0,55}$ ]]; then
76
+ DF_ID_RUN=$run
77
+ run_ok=1
78
+ else
79
+ DF_ID_RUN=local
80
+ invalid=1
81
+ fi
82
+
83
+ # attempt: integer 1 to 9999; invalid is as unset.
84
+ DF_ID_ATTEMPT=""
85
+ if [[ $attempt =~ ^[1-9][0-9]{0,3}$ ]]; then
86
+ DF_ID_ATTEMPT=$attempt
87
+ attempt_ok=1
88
+ fi
89
+
90
+ # lineage: id pattern; unset is `main` for main and `solo` for worker; invalid is `solo`.
91
+ if [ -z "$lineage" ]; then
92
+ if [ "$DF_ID_ROLE" = main ]; then DF_ID_LINEAGE=main; else DF_ID_LINEAGE=solo; fi
93
+ elif [[ $lineage =~ ^[A-Za-z0-9][A-Za-z0-9_-]{0,55}$ ]]; then
94
+ DF_ID_LINEAGE=$lineage
95
+ lineage_ok=1
96
+ else
97
+ DF_ID_LINEAGE=solo
98
+ invalid=1
99
+ fi
100
+ if [ -n "$run" ] && [ "$run_ok" = 0 ]; then
101
+ DF_ID_LINEAGE=solo
102
+ lineage_ok=0
103
+ fi
104
+ [ "$invalid" = 0 ] || _doflow_identity_capture identity-invalid
105
+
106
+ # worktree: an absolute path to an existing directory, canonicalised; otherwise the payload cwd.
107
+ DF_ID_WORKTREE=$cwd
108
+ case "$worktree" in
109
+ /*)
110
+ if [ -d "$worktree" ]; then
111
+ worktree=$(CDPATH= cd -P -- "$worktree" 2>/dev/null && pwd -P) || worktree=""
112
+ [ -z "$worktree" ] || DF_ID_WORKTREE=$worktree
113
+ fi
114
+ ;;
115
+ esac
116
+
117
+ if [ "$run_ok" = 1 ] && [ "$lineage_ok" = 1 ] && [ "$attempt_ok" = 1 ]; then
118
+ DF_ID_KIND=launched
119
+ DF_ID_UNIT="L.$DF_ID_RUN.$DF_ID_LINEAGE.$DF_ID_ATTEMPT"
120
+ elif [ "$DF_ID_RUN" = local ] && [ "$DF_ID_LINEAGE" = main ]; then
121
+ # default-main: run unset and lineage main, whether main was defaulted or set explicitly.
122
+ DF_ID_KIND=default-main
123
+ DF_ID_UNIT=$session_id
124
+ else
125
+ DF_ID_KIND=solo
126
+ DF_ID_UNIT=$session_id
127
+ fi
128
+
129
+ # Binding (DEC-008, DEC-044): the first session to present a launched unit creates `bound`
130
+ # exclusively; a session whose id differs from the bound one is inherited and gets its own solo
131
+ # unit. A unit that cannot be bound with a session id (store unwritable, `bound` a symlink, which is
132
+ # never followed, or `bound` still empty after one retry) is inherited too. With no session id the
133
+ # unit is solo with an empty unit id and no capture.
134
+ if [ "$DF_ID_KIND" = launched ]; then
135
+ # The store is lib.sh's SESSION_DIR. Sourced without lib.sh, the config-home rule of
136
+ # src/runtime/config-home.js is applied inline (an absolute XDG_CONFIG_HOME, else an absolute
137
+ # HOME + /.config); with no config home there is no store and the unit is not bound (086 IC-010).
138
+ sessions="${SESSION_DIR:-}"
139
+ # doflow-config-home v1 inline copy: no marked block here, identity.sh defines only its four functions (086 B.2).
140
+ if [ -z "$sessions" ]; then
141
+ case "${XDG_CONFIG_HOME:-}" in
142
+ /*) sessions="$XDG_CONFIG_HOME/doflow/session-env/sessions" ;;
143
+ [A-Za-z]:[\\/]*) case "${OSTYPE:-}" in msys*|cygwin*|win32*) sessions="$XDG_CONFIG_HOME/doflow/session-env/sessions" ;; esac ;;
144
+ esac
145
+ case "${HOME:-}" in
146
+ /*) [ -n "$sessions" ] || sessions="$HOME/.config/doflow/session-env/sessions" ;;
147
+ [A-Za-z]:[\\/]*) case "${OSTYPE:-}" in msys*|cygwin*|win32*) [ -n "$sessions" ] || sessions="$HOME/.config/doflow/session-env/sessions" ;; esac ;;
148
+ esac
149
+ fi
150
+ dir="${sessions:+$sessions/$DF_ID_UNIT}"
151
+ if [ -n "$session_id" ] && [ -n "$dir" ] && mkdir -p "$dir" 2>/dev/null; then
152
+ case $- in *C*) had_c=1 ;; esac
153
+ set -C
154
+ { printf '%s\n' "$session_id" >"$dir/bound"; } 2>/dev/null && mine=1
155
+ [ "$had_c" = 1 ] || set +C
156
+ if [ "$mine" = 0 ]; then
157
+ # An empty first line may be a concurrent binder between its create and its write.
158
+ for tries in 1 2; do
159
+ [ -f "$dir/bound" ] && [ ! -L "$dir/bound" ] || break
160
+ IFS= read -r bound 2>/dev/null <"$dir/bound" || true
161
+ [ -z "$bound" ] || break
162
+ done
163
+ [ -z "$bound" ] || [ "$bound" != "$session_id" ] || mine=1
164
+ fi
165
+ fi
166
+ if [ "$mine" = 0 ]; then
167
+ DF_ID_KIND=solo
168
+ DF_ID_LINEAGE=solo
169
+ DF_ID_UNIT=$session_id
170
+ if [ -n "$session_id" ] && [ -z "${_DF_ID_INHERITED_CAPTURED:-}" ]; then
171
+ _doflow_identity_capture identity-inherited
172
+ _DF_ID_INHERITED_CAPTURED=1
173
+ fi
174
+ fi
175
+ fi
176
+ return 0
177
+ }
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bash
2
+ case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
2
3
  # lib.sh — shared constants and helpers for the Canonical Policy Library
3
4
  #
4
5
  # Usage: source "<policy-dir>/lib.sh"
@@ -9,7 +10,7 @@
9
10
  # 3. capture stdin once: INPUT=$(cat)
10
11
  # 4. use: json_field "$INPUT" ".field_name"
11
12
 
12
- case ${BASH_SOURCE[0]} in */*) _DOFLOW_LIB_DIR=${BASH_SOURCE[0]%/*} ;; *) _DOFLOW_LIB_DIR=. ;; esac
13
+ _DOFLOW_SRC=${BASH_SOURCE[0]//\\//}; case $_DOFLOW_SRC in */*) _DOFLOW_LIB_DIR=${_DOFLOW_SRC%/*} ;; *) _DOFLOW_LIB_DIR=. ;; esac
13
14
  #
14
15
  # Deployment:
15
16
  # This file is installed by the doflow CLI and overwritten on update — do
@@ -17,7 +18,7 @@ case ${BASH_SOURCE[0]} in */*) _DOFLOW_LIB_DIR=${BASH_SOURCE[0]%/*} ;; *) _DOFLO
17
18
  #
18
19
  # Consolidation note (022-normalize-hooks, Phase B): this is the single
19
20
  # canonical copy every front door's dispatched policy script sources — the
20
- # claude/gemini/kiro/codex copies it replaces were already byte-identical
21
+ # claude/kiro/codex copies it replaces were already byte-identical
21
22
  # except for one Claude-only default (see DOFLOW_AGENT below), confirmed via
22
23
  # diff before consolidating.
23
24
 
@@ -25,16 +26,33 @@ set -euo pipefail
25
26
 
26
27
  # ── State directories ────────────────────────────────────────────────────────
27
28
 
28
- # XDG-compliant, agent-agnostic store shared by every harness DoFlow supports.
29
- DOFLOW_HOME="${XDG_CONFIG_HOME:-$HOME/.config}/doflow"
30
- STATE_DIR="$DOFLOW_HOME/session-env"
31
- SESSION_DIR="$STATE_DIR/sessions"
32
- 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}"
33
51
  # shellcheck disable=SC2034 # used by session-context.sh and stop-check.sh which source this file
34
- SESSIONS_LOG="$DOFLOW_HOME/sessions.log"
52
+ SESSIONS_LOG="${DOFLOW_HOME:+$DOFLOW_HOME/sessions.log}"
35
53
 
36
54
  # Identifies which harness is running. A front door sets this before sourcing
37
- # 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`);
38
56
  # "unknown" here — not any one harness's name — is the honest fallback when a
39
57
  # front door omits it, since every prior per-harness copy of this file
40
58
  # defaulted to "claude-code" regardless of which harness actually shipped it.
@@ -253,18 +271,22 @@ has_uncommitted_changes() {
253
271
  # ── Directory helpers ─────────────────────────────────────────────────────────
254
272
 
255
273
  # Create and return the session-scoped state directory for a given session_id.
256
- # 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).
257
276
  ensure_session_dir() {
258
277
  local session_id="$1"
278
+ [ -n "$SESSION_DIR" ] || return 0
259
279
  mkdir -p "$SESSION_DIR/$session_id"
260
280
  echo "$SESSION_DIR/$session_id"
261
281
  }
262
282
 
263
283
  # Create and return the project-scoped state directory for a given cwd.
264
- # 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).
265
286
  ensure_project_dir() {
266
287
  local cwd="$1"
267
288
  local hash
289
+ [ -n "$PROJECTS_DIR" ] || return 0
268
290
  hash=$(cwd_hash "$cwd")
269
291
  mkdir -p "$PROJECTS_DIR/$hash"
270
292
  echo "$PROJECTS_DIR/$hash"
@@ -293,30 +315,16 @@ require_jq() {
293
315
  fi
294
316
  }
295
317
 
296
- # ── Session role ──────────────────────────────────────────────────────────────
297
-
298
- # Print `main` or `worker` for this session, read from DOFLOW_SESSION_ROLE (matched
299
- # case-insensitively). Unset or empty is `main`; a value that is neither `main` nor
300
- # `worker` is `worker` and writes one line to stderr. A worker never writes or claims the
301
- # project's compact summary or warning. Always returns 0. bash 3.2 safe (no ${var,,}).
302
- doflow_session_role() {
303
- local role
304
- role=$(printf '%s' "${DOFLOW_SESSION_ROLE:-}" | tr '[:upper:]' '[:lower:]') || role=""
305
- case "$role" in
306
- ""|main) printf 'main\n' ;;
307
- worker) printf 'worker\n' ;;
308
- *)
309
- echo "[doflow] unknown DOFLOW_SESSION_ROLE; treating session as worker" >&2
310
- printf 'worker\n'
311
- ;;
312
- esac
313
- return 0
314
- }
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"
315
322
 
316
323
  # Start storage cleanup without changing the hook's output, status, or latency.
317
324
  storage_upkeep_async() {
318
- local cwd="${1:-}" root run home config_dir
325
+ local cwd="${1:-}" root run home config_dir detach=""
319
326
  [ -n "$cwd" ] || return 0
327
+ command -v setsid >/dev/null 2>&1 && detach="setsid"
320
328
  home="${HOME:-}"
321
329
  config_dir="${CLAUDE_CONFIG_DIR:-$home/.claude}"
322
330
  root=$(nudge_repo_root "$cwd" 2>/dev/null) || root="$cwd"
@@ -329,7 +337,9 @@ storage_upkeep_async() {
329
337
  # Background the fully redirected subshell; an inner `&` leaves this shell
330
338
  # holding the hook's captured stdout open until the dispatcher exits. The
331
339
  # storage verb takes its project from the working directory: run it at the root.
332
- ( cd "$root" 2>/dev/null && nohup "$run" storage --action upkeep </dev/null >/dev/null 2>&1 ) >/dev/null 2>&1 3>&- 5>&- &
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>&- &
333
343
  return 0
334
344
  done
335
345
  return 0
@@ -379,7 +389,7 @@ nudge_repo_root() {
379
389
  # file that cannot be read, is empty or holds anything else is `off`.
380
390
  nudge_setting() {
381
391
  local root="${1:-}" file line=""
382
- 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
383
393
  [ -n "$file" ] && [ -e "$file" ] || continue
384
394
  line=""
385
395
  { IFS= read -r line || true; } 2>/dev/null < "$file" || line=""
@@ -406,17 +416,20 @@ nudge_safe_id() {
406
416
  return 0
407
417
  }
408
418
 
409
- # 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.
410
421
  nudge_marker_file() {
422
+ [ -n "$STATE_DIR" ] || return 0
411
423
  printf '%s\n' "$STATE_DIR/nudge/$1"
412
424
  }
413
425
 
414
426
  # Create the marker for <id> holding <nudged|suppressed>. Succeeds only when this call
415
427
  # created it: the create is exclusive, so a second call for the same id fails and
416
428
  # leaves the first content. After a create, markers untouched for over 30 days are
417
- # removed. Silent on every failure.
429
+ # removed. Silent on every failure. With no config home it creates nothing and returns 0 at once.
418
430
  nudge_mark() {
419
- 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
420
433
  nudge_safe_id "$id" || return 1
421
434
  case "$word" in nudged|suppressed) ;; *) return 1 ;; esac
422
435
  file="$dir/$id"
@@ -452,7 +465,8 @@ nudge_feature_active() {
452
465
  # S3: succeed when a `/do-*` skill already ran this session, read from the run ledger:
453
466
  # the lexically last <config>/state/runs/*.jsonl, whose last line's timestamp is not
454
467
  # earlier than the session's captured_at (both YYYY-MM-DDTHH:MM:SSZ). Config dir:
455
- # $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).
456
470
  # Without a captured_at the ledger counts when it is named for today's UTC date; a last
457
471
  # line without a usable timestamp counts too. No ledger, or an empty one, does not.
458
472
  nudge_ledger_active() {
@@ -462,10 +476,19 @@ nudge_ledger_active() {
462
476
  if [ -n "${DOFLOW_CONFIG_DIR:-}" ]; then
463
477
  config="$DOFLOW_CONFIG_DIR"
464
478
  else
465
- config="$HOME/.doflow"
479
+ config="${HOME:+$HOME/.doflow}"
466
480
  # The ancestor in the walk's own spelling (`\` read as `/`), the form its test succeeded on.
467
- 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
468
490
  fi
491
+ [ -n "$config" ] || return 1
469
492
  for f in "$config"/state/runs/*.jsonl; do
470
493
  [ -f "$f" ] && ledger="$f"
471
494
  done
@@ -493,7 +516,7 @@ nudge_registry() {
493
516
  "${policy_dir:+$policy_dir/../../../runtime/core/registry/workflows.json}" \
494
517
  "${policy_dir:+$policy_dir/../../../../registry/workflows.json}" \
495
518
  "${root:+$root/.doflow/runtime/core/registry/workflows.json}" \
496
- "$HOME/.doflow/runtime/core/registry/workflows.json"; do
519
+ "${HOME:+$HOME/.doflow/runtime/core/registry/workflows.json}"; do
497
520
  if [ -n "$candidate" ] && [ -f "$candidate" ]; then
498
521
  printf '%s\n' "$candidate"
499
522
  return 0
@@ -1,6 +1,6 @@
1
1
  # mcp-policy.conf — MCP tool deny patterns for mcp-tool-guard.sh
2
2
  #
3
- # Format (TAB-separated), identical convention to blocked-patterns.conf:
3
+ # Format (TAB-separated):
4
4
  # regex<TAB>reason shown to the harness
5
5
  #
6
6
  # Rules:
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env bash
2
- case $0 in */*) _DOFLOW_POLDIR=${0%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
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
3
4
  # mcp-tool-guard.sh — Canonical Policy Library: PreToolUse(mcp_*) hook
4
5
  #
5
6
  # Intercepts every MCP tool call and blocks matches against mcp-policy.conf, the
6
- # same TAB-separated pattern<TAB>reason convention pre-bash-guard.sh uses for
7
- # shell commands. Ships with mcp-policy.conf carrying zero active patterns, so
7
+ # TAB-separated pattern<TAB>reason format. Ships with mcp-policy.conf carrying zero active patterns, so
8
8
  # this is pure infrastructure until real usage data justifies specific deny
9
9
  # rules — see agent-docs/research/hook-governance-agent-tool-mcp-skill.md §3.2.
10
10
  #
@@ -20,7 +20,7 @@ case $0 in */*) _DOFLOW_POLDIR=${0%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
20
20
  #
21
21
  # mcp-policy.conf's shape (TAB-separated regex<TAB>reason, '#'-comments,
22
22
  # blank lines skipped) is identical across every harness that ships one today
23
- # (claude/codex/gemini/kiro) — reconciliation found no divergence to resolve
23
+ # (claude/codex/kiro) — reconciliation found no divergence to resolve
24
24
  # there.
25
25
 
26
26
  set -uo pipefail
@@ -38,8 +38,7 @@ else
38
38
  else
39
39
  printf '[mcp-tool-guard] DoFlow hooks out of step; run: doflow update\n' >&2
40
40
  fi
41
- doflow_decide deny contract-missing
42
- exit 2
41
+ exit 0
43
42
  fi
44
43
  doflow_decision_init mcp-tool-guard 1
45
44
  command -v jq >/dev/null 2>&1 || {
@@ -63,8 +62,8 @@ else
63
62
  ( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure mcp-tool-guard envelope-missing ) >/dev/null 2>&1 || true
64
63
  fi
65
64
  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
66
- doflow_decide deny "${DF_ENV_CODE:-envelope-missing}"
67
- exit 2
65
+ doflow_decide unsupported "${DF_ENV_CODE:-envelope-missing}"
66
+ exit 0
68
67
  fi
69
68
 
70
69
  POLICY_FILE="$_DOFLOW_POLDIR/mcp-policy.conf"