@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
@@ -1,11 +1,12 @@
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
  # pre-implementation-gate.sh — Canonical Policy Library: PreToolUse(Edit|Write|...)
4
- # backstop for the doflow implement gate. The HARD half of the one enforced
5
- # gate (the other half is the prompt-level do-prereqs.sh inside
6
- # /do-execute-plan — defense in depth).
5
+ # advisory for the doflow implement gate (the other half is the prompt-level
6
+ # do-prereqs.sh inside /do-execute-plan). It never denies: each finding below is
7
+ # a doflow_decide advisory code plus one stderr line.
7
8
  #
8
- # Denies a SOURCE-file edit in two cases:
9
+ # Advises on a SOURCE-file edit in two cases:
9
10
  # 1. a feature has been STARTED (its feature_dir exists, in this checkout or,
10
11
  # from a linked worktree, in the main checkout) but requirement.md,
11
12
  # design.md, or plan.md is still missing: "don't write code before you've
@@ -22,20 +23,20 @@ case $0 in */*) _DOFLOW_POLDIR=${0%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
22
23
  # - edit target is under agent-docs/ -> allow (editing the artifacts themselves)
23
24
  # - edit target outside the repo -> allow
24
25
  # It reads files with jq and lists checkouts with one git call; it never runs
25
- # the DoFlow runtime. Missing or malformed v1 input is denied as out of step; other faults follow IC-011.
26
+ # the DoFlow runtime. Missing or malformed v1 input is allowed with an out-of-step line; other faults follow IC-011.
26
27
  #
27
28
  # Canonical Policy Script Contract (design.md §4):
28
29
  # env DOFLOW_PROJECT_DIR (repo root, if the front door sets it),
29
30
  # DOFLOW_AGENT (harness id, informational only here),
30
- # CLAUDE_CONFIG_DIR / CLAUDE_PROJECT_DIR / GEMINI_CONFIG_DIR / CODEX_HOME
31
+ # CLAUDE_CONFIG_DIR / CLAUDE_PROJECT_DIR / CODEX_HOME
31
32
  # (each already read by the harness-specific dispatcher this policy
32
33
  # replaces — kept so an unmodified front door still resolves its own
33
34
  # harness's do-paths.sh resolver)
34
35
  # stdin a native payload encoded as envelope v1 by the lifecycle bridge.
35
- # exit exit 2 + doflow_decide deny = deny; other faults per IC-011. A front
36
- # door translates this into its native response shape.
36
+ # exit always 0: every finding is a doflow_decide advisory code plus one stderr
37
+ # line, which the lifecycle bridge renders per harness. This policy never denies.
37
38
  #
38
- # Reconciliation note (022-normalize-hooks, Phase A): claude/gemini/codex/kiro
39
+ # Reconciliation note (022-normalize-hooks, Phase A): claude/codex/kiro
39
40
  # each shipped a separately-adapted copy of this gate; antigravity's copy
40
41
  # additionally never depended on a do-paths.sh resolver at all — it computed
41
42
  # feature_dir itself from the current branch name and checked the three
@@ -64,8 +65,7 @@ else
64
65
  else
65
66
  printf '[pre-implementation-gate] DoFlow hooks out of step; run: doflow update\n' >&2
66
67
  fi
67
- doflow_decide deny contract-missing
68
- exit 2
68
+ exit 0
69
69
  fi
70
70
  doflow_decision_init pre-implementation-gate 1
71
71
  command -v jq >/dev/null 2>&1 || {
@@ -112,8 +112,8 @@ else
112
112
  ( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure pre-implementation-gate envelope-missing ) >/dev/null 2>&1 || true
113
113
  fi
114
114
  if [[ "${DOFLOW_AGENT:-}" =~ ^[a-z]+$ ]]; then printf '[pre-implementation-gate] DoFlow hooks out of step; run: doflow update -t %s\n' "$DOFLOW_AGENT" >&2; else printf '[pre-implementation-gate] DoFlow hooks out of step; run: doflow update\n' >&2; fi
115
- doflow_decide deny "${DF_ENV_CODE:-envelope-missing}"
116
- exit 2
115
+ doflow_decide unsupported "${DF_ENV_CODE:-envelope-missing}"
116
+ exit 0
117
117
  fi
118
118
 
119
119
  # ── Resolve repo root ───────────────────────────────────────────────────────
@@ -139,13 +139,11 @@ RESOLVER_CANDIDATES=(
139
139
  "$ROOT/.doflow/scripts/doflow/bash/do-paths.sh"
140
140
  "$ROOT/.claude/scripts/doflow/bash/do-paths.sh"
141
141
  "$ROOT/.codex/scripts/doflow/bash/do-paths.sh"
142
- "$ROOT/.gemini/scripts/doflow/bash/do-paths.sh"
143
142
  "$ROOT/.kiro/scripts/doflow/bash/do-paths.sh"
144
143
  "$HOME/.doflow/scripts/doflow/bash/do-paths.sh"
145
144
  "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/scripts/doflow/bash/do-paths.sh"
146
145
  "${CLAUDE_PROJECT_DIR:-}/.claude/scripts/doflow/bash/do-paths.sh"
147
146
  "${CODEX_HOME:-$HOME/.codex}/scripts/doflow/bash/do-paths.sh"
148
- "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/scripts/doflow/bash/do-paths.sh"
149
147
  "$HOME/.kiro/scripts/doflow/bash/do-paths.sh"
150
148
  )
151
149
 
@@ -163,11 +161,14 @@ has_plan=""
163
161
  if [ -n "$RESOLVER" ]; then
164
162
  json=$("$RESOLVER" --json 2>/dev/null) || json=""
165
163
  if [ -n "$json" ]; then
166
- feature_dir=$(printf '%s' "$json" | jq -r '.feature_dir // empty' 2>/dev/null)
167
- repo_root=$(printf '%s' "$json" | jq -r '.repo_root // empty' 2>/dev/null)
168
- has_requirement=$(printf '%s' "$json" | jq -r '.has_requirement // false' 2>/dev/null)
169
- has_design=$(printf '%s' "$json" | jq -r '.has_design // false' 2>/dev/null)
170
- has_plan=$(printf '%s' "$json" | jq -r '.has_plan // false' 2>/dev/null)
164
+ # One jq run for all five fields, one per line (none of them can hold a newline).
165
+ {
166
+ IFS= read -r feature_dir
167
+ IFS= read -r repo_root
168
+ IFS= read -r has_requirement
169
+ IFS= read -r has_design
170
+ IFS= read -r has_plan
171
+ } < <(printf '%s' "$json" | jq -r '(.feature_dir // ""), (.repo_root // ""), (.has_requirement // false), (.has_design // false), (.has_plan // false)' 2>/dev/null) || true
171
172
  fi
172
173
  fi
173
174
 
@@ -247,18 +248,41 @@ real_path() {
247
248
  repo_real=$(cd -P "$repo_root" 2>/dev/null && pwd) || repo_real="$repo_root"
248
249
 
249
250
  # Only source files inside this repo are gated: edits to doflow artifacts are
250
- # always allowed, and an absolute path elsewhere is not this repo's.
251
+ # always allowed, an absolute path elsewhere is not this repo's, and neither is a
252
+ # path git ignores.
251
253
  GATED=false
252
254
  while IFS= read -r file; do
253
255
  [ -z "$file" ] && continue
254
- case "$file" in *"/agent-docs/"*|agent-docs/*) continue ;; esac
256
+ # A ".." segment can lead out of agent-docs (agent-docs/../src/x), so such a path is judged by
257
+ # its real path below, never by the text before the "..".
258
+ case "/$file/" in
259
+ */../*) ;;
260
+ *) case "$file" in *"/agent-docs/"*|agent-docs/*) continue ;; esac ;;
261
+ esac
262
+ check="$file"
255
263
  case "$file" in
256
264
  /*)
257
265
  real=$(real_path "$file") || real="$file"
258
- case "$real" in *"/agent-docs/"*) continue ;; esac
266
+ case "/$real/" in */../*) ;; *) case "$real" in *"/agent-docs/"*) continue ;; esac ;; esac
259
267
  case "$real" in "$repo_real"/*) ;; *) continue ;; esac
268
+ check="$real"
269
+ ;;
270
+ *)
271
+ real=$(real_path "$repo_root/$file") || real="$repo_root/$file"
272
+ # real_path folds a ".." only through directories that exist, so one left in it is not folded.
273
+ case "/$file/" in */../*) case "/$real/" in */../*) ;; *) case "${real#"$repo_real"}/" in */agent-docs/*) continue ;; esac ;; esac ;; esac
260
274
  ;;
261
275
  esac
276
+ # A path git ignores (a local config file such as .mcp.json) is not source. check-ignore
277
+ # without --no-index answers "not ignored" for a tracked file, so tracked source stays gated.
278
+ # The skip never applies to DoFlow's own state or gate artifacts: .doflow/ is gitignored, and
279
+ # skipping it would let an edit forge a readiness record. Any `.doflow` or `agent-docs/doflow`
280
+ # segment of the real path, or of the path as written (a `..` the resolver could not fold), keeps it gated.
281
+ # The same holds for the do-paths.sh resolver the gate runs (any RESOLVER_CANDIDATES path, whichever
282
+ # harness directory holds it, ignored or not): rewriting it can make the gate find no feature.
283
+ case "/$file/" in */.doflow/*|*/agent-docs/doflow/*|*/../*|*/scripts/doflow/bash/do-paths.sh/) GATED=true; break ;; esac
284
+ case "${real#"$repo_real"}/" in */.doflow/*|*/agent-docs/doflow/*|*/scripts/doflow/bash/do-paths.sh/) GATED=true; break ;; esac
285
+ git -C "$repo_root" check-ignore -q -- "$check" 2>/dev/null && continue
262
286
  GATED=true
263
287
  break
264
288
  done <<< "$FILES"
@@ -304,25 +328,71 @@ checkouts() {
304
328
  return 0
305
329
  }
306
330
 
307
- # A state file under this checkout, else under exactly one other checkout, at
308
- # the first of the given paths that exists in each; held in two or more others,
309
- # it cannot be told which is meant -> allow.
331
+ # Whether two files hold the same bytes.
332
+ same_bytes() {
333
+ if command -v cmp >/dev/null 2>&1; then cmp -s "$1" "$2"; else [ "$(cat "$1")" = "$(cat "$2")" ]; fi
334
+ }
335
+
336
+ # Whether the flat record $1 of a namespaced task may be read as feature $2's
337
+ # (115 D-3): it names that feature (featureSlug on a run, slug on a readiness
338
+ # record) or none. A file that does not parse names nobody.
339
+ flat_is_ours() {
340
+ local named
341
+ named=$(jq -r '[.featureSlug, .slug] | map(select(type == "string" and . != "")) | first // empty' "$1" 2>/dev/null) || return 1
342
+ [ -z "$named" ] || [ "$named" = "$2" ]
343
+ }
344
+
345
+ # The task's record of store $2 (readiness | orchestration) under checkout $1,
346
+ # keyed by feature $3 as the runtime keys it (115 C-1): <store>/<feature>/<id>.json
347
+ # for a task id other than the feature's slug, else the flat file; the flat file
348
+ # of a namespaced task only when it is this feature's or names none. Sets HIT.
349
+ HIT=""
350
+ record_in() {
351
+ local store="$1/.doflow/state/$2"
352
+ HIT=""
353
+ if [ -n "$3" ] && [ "$3" != "$task_id" ]; then
354
+ if [ -f "$store/$3/$task_id.json" ]; then HIT="$store/$3/$task_id.json"; return 0; fi
355
+ [ -f "$store/$task_id.json" ] && flat_is_ours "$store/$task_id.json" "$3" && HIT="$store/$task_id.json"
356
+ return 0
357
+ fi
358
+ [ -f "$store/$task_id.json" ] && HIT="$store/$task_id.json"
359
+ return 0
360
+ }
361
+
362
+ # The task's readiness record, keyed by feature $1. From a linked worktree the
363
+ # main checkout's comes first, since every record lives there (115 IC-004), and
364
+ # a copy at the same path here with other bytes refuses (C-3). Else this
365
+ # checkout's, else exactly one other checkout's; held in two or more others it
366
+ # cannot be told which is meant -> allow.
310
367
  FOUND=""
311
368
  find_state() {
312
- local rel root count=0 hit
369
+ local root count=0 copy
313
370
  FOUND=""
314
- for rel in "$@"; do
315
- if [ -f "$repo_root/$rel" ]; then FOUND="$repo_root/$rel"; return 0; fi
316
- done
371
+ if [ -f "$repo_root/.git" ]; then
372
+ checkouts
373
+ if [ -n "$MAIN" ]; then
374
+ record_in "$MAIN" readiness "$1"
375
+ if [ -n "$HIT" ]; then
376
+ copy="$repo_root${HIT#"$MAIN"}"
377
+ if [ -f "$copy" ] && ! same_bytes "$copy" "$HIT"; then
378
+ printf "doflow gate readiness-before-implementation: task '%s' has a readiness record in this worktree (%s) that differs from the main checkout's (%s). Next: keep one of the two and remove the other, then re-run. Nothing was changed.\n" "$task_id" "$copy" "$HIT" >&2
379
+ doflow_decide advisory readiness-store-conflict
380
+ exit 0
381
+ fi
382
+ FOUND="$HIT"
383
+ return 0
384
+ fi
385
+ fi
386
+ fi
387
+ record_in "$repo_root" readiness "$1"
388
+ if [ -n "$HIT" ]; then FOUND="$HIT"; return 0; fi
317
389
  checkouts
318
390
  for root in ${OTHERS[@]+"${OTHERS[@]}"}; do
319
- hit=""
320
- for rel in "$@"; do
321
- [ -f "$root/$rel" ] && { hit="$root/$rel"; break; }
322
- done
323
- [ -n "$hit" ] || continue
391
+ [ "$root" = "$MAIN" ] && continue
392
+ record_in "$root" readiness "$1"
393
+ [ -n "$HIT" ] || continue
324
394
  count=$((count + 1))
325
- FOUND="$hit"
395
+ FOUND="$HIT"
326
396
  done
327
397
  [ "$count" -le 1 ] || exit 0
328
398
  }
@@ -338,18 +408,26 @@ run_feature() {
338
408
  return 0
339
409
  }
340
410
 
411
+ # The feature the task's records are keyed by, as the runtime keys them
412
+ # (featureSlugFor): a task id that names a feature folder in this checkout is
413
+ # its own feature, else the branch's.
414
+ run_key="$slug"
415
+ [ -d "$repo_root/agent-docs/doflow/$task_id" ] && run_key="$task_id"
416
+
341
417
  # The task's run: this checkout's, else the one other checkout's run of the same
342
418
  # feature. A run with the same id for another feature is a different task.
343
419
  find_run() {
344
- local rel=".doflow/state/orchestration/$task_id.json" root count=0
420
+ local root count=0
345
421
  FOUND=""
346
- if [ -f "$repo_root/$rel" ]; then FOUND="$repo_root/$rel"; return 0; fi
422
+ record_in "$repo_root" orchestration "$run_key"
423
+ if [ -n "$HIT" ]; then FOUND="$HIT"; return 0; fi
347
424
  checkouts
348
425
  for root in ${OTHERS[@]+"${OTHERS[@]}"}; do
349
- [ -f "$root/$rel" ] || continue
350
- [ "$(run_feature "$root/$rel")" = "$slug" ] || continue
426
+ record_in "$root" orchestration "$run_key"
427
+ [ -n "$HIT" ] || continue
428
+ [ "$(run_feature "$HIT")" = "$run_key" ] || continue
351
429
  count=$((count + 1))
352
- FOUND="$root/$rel"
430
+ FOUND="$HIT"
353
431
  done
354
432
  [ "$count" -le 1 ] || exit 0
355
433
  }
@@ -374,8 +452,8 @@ PLANNED=false
374
452
  # plan.md all exist. Classes that cannot be a feature skip this check.
375
453
  if [ "$exempt" = false ] && [ -n "$FEATURE_ROOT" ] && [ "$PLANNED" = false ]; then
376
454
  echo "[pre-implementation-gate] doflow gate: feature $feature_dir is missing requirement.md, design.md, or plan.md — run /do-brainstorm, /do-design, then /do-plan before editing source. (Edits under agent-docs/ are always allowed; skip the flow by removing the feature dir.)" >&2
377
- doflow_decide deny missing-artifacts
378
- exit 2
455
+ doflow_decide advisory missing-artifacts
456
+ exit 0
379
457
  fi
380
458
 
381
459
  # ── Readiness ────────────────────────────────────────────────────────────────
@@ -443,13 +521,10 @@ if [ -n "$RUN" ]; then
443
521
  fi
444
522
 
445
523
  # The record, where the runtime looks: under the feature's namespace (the run's
446
- # own feature when it recorded one), then flat; this checkout first.
447
- record_slug="${run_slug:-$slug}"
448
- if [ -n "$record_slug" ] && [ "$record_slug" != "$task_id" ]; then
449
- find_state ".doflow/state/readiness/$record_slug/$task_id.json" ".doflow/state/readiness/$task_id.json"
450
- else
451
- find_state ".doflow/state/readiness/$task_id.json"
452
- fi
524
+ # own feature when it recorded one), then flat; the main checkout first from a
525
+ # linked worktree, else this checkout first.
526
+ record_slug="${run_slug:-$run_key}"
527
+ find_state "$record_slug"
453
528
  record_state=""; record_class=""; record_at=""
454
529
  if [ -n "$FOUND" ]; then
455
530
  record_info=$(jq -r '(.state // ""), (.taskClass // ""), (.evaluatedAt // "")' "$FOUND" 2>/dev/null) || exit 0
@@ -471,20 +546,20 @@ gate="doflow gate readiness-before-implementation: task '$task_id'"
471
546
  rest="Next: $next, then gather what it lists until it reports READY. Nothing was changed."
472
547
  if [ -z "$FOUND" ]; then
473
548
  printf "%s has no readiness record for the '%s' template. %s\n" "$gate" "$STAGE_TEMPLATE" "$rest" >&2
474
- doflow_decide deny readiness-missing
475
- exit 2
549
+ doflow_decide advisory readiness-missing
550
+ exit 0
476
551
  fi
477
552
  if [ "$record_state" != READY ]; then
478
553
  printf "%s was last evaluated %s at %s against the '%s' template, not READY. %s\n" \
479
554
  "$gate" "$record_state" "$record_at" "$STAGE_TEMPLATE" "$rest" >&2
480
- doflow_decide deny readiness-not-ready
481
- exit 2
555
+ doflow_decide advisory readiness-not-ready
556
+ exit 0
482
557
  fi
483
558
  if [ "$record_class" != "$STAGE_TEMPLATE" ]; then
484
559
  printf "%s has a READY record for the '%s' template, and this stage needs '%s'. %s\n" \
485
560
  "$gate" "$record_class" "$STAGE_TEMPLATE" "$rest" >&2
486
- doflow_decide deny readiness-wrong-template
487
- exit 2
561
+ doflow_decide advisory readiness-wrong-template
562
+ exit 0
488
563
  fi
489
564
 
490
565
  exit 0
@@ -1,5 +1,6 @@
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
  # session-context.sh — Canonical Policy Library: SessionStart guard policy
4
5
  #
5
6
  # Fires when a harness starts a new session. Captures git state into a
@@ -61,9 +62,36 @@ if [ "$ENVELOPE_CLASS" = unsupported ] || [ "$ENVELOPE_CLASS" = missing ]; then
61
62
  fi
62
63
  CWD=$(json_field "$INPUT" ".cwd")
63
64
 
65
+ package_verify_async() {
66
+ local home="${HOME:-}" lock run config_dir detach=""
67
+ [ -n "$home" ] || return 0
68
+ lock="$home/.doflow/doflow.lock"
69
+ [ -f "$lock" ] || return 0
70
+ jq -e '(.packages // []) | length > 0' "$lock" >/dev/null 2>&1 || return 0
71
+ config_dir="${CLAUDE_CONFIG_DIR:-$home/.claude}"
72
+ command -v setsid >/dev/null 2>&1 && detach="setsid"
73
+ for run in \
74
+ "$home/.doflow/scripts/doflow/bin/doflow-run" \
75
+ "$config_dir/scripts/doflow/bin/doflow-run"
76
+ do
77
+ [ -x "$run" ] || continue
78
+ ( cd "$home/.doflow" 2>/dev/null && nohup $detach "$run" package --action verify </dev/null >/dev/null 2>&1 ) >/dev/null 2>&1 3>&- 5>&- &
79
+ return 0
80
+ done
81
+ return 0
82
+ }
83
+
64
84
  # Guard: if we can't determine the session, nothing to do
65
85
  [[ -z "$SESSION_ID" ]] && exit 0
66
86
 
87
+ # No config home (lib.sh leaves the state paths empty): no session store to write, but the
88
+ # storage upkeep still starts (086 IC-010).
89
+ if [[ -z "$SESSION_DIR" ]]; then
90
+ package_verify_async
91
+ storage_upkeep_async "$CWD"
92
+ exit 0
93
+ fi
94
+
67
95
  SESSION_PATH=$(ensure_session_dir "$SESSION_ID")
68
96
 
69
97
  # Clean up stale injected flag from a prior crashed session
@@ -167,5 +195,6 @@ fi
167
195
  mkdir -p "$(dirname "$SESSIONS_LOG")"
168
196
  echo "$TIMESTAMP START $SESSION_ID ${CWD:-unknown}" >> "$SESSIONS_LOG"
169
197
 
198
+ package_verify_async
170
199
  storage_upkeep_async "$CWD"
171
200
  exit 0
@@ -1,5 +1,6 @@
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
  # stop-check.sh — Canonical Policy Library: Stop hook
4
5
  #
5
6
  # Two responsibilities:
@@ -12,10 +13,11 @@ case $0 in */*) _DOFLOW_POLDIR=${0%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
12
13
  # 2. Stub detection: takes the payload's last_assistant_message, or else the
13
14
  # last assistant message in the JSONL transcript (Claude Code, Codex and
14
15
  # flat {role,content} shapes), then checks for unfinished-work markers.
15
- # Exits non-zero if stubs are found (blocks the session from stopping).
16
+ # Records an advisory and prints one warning line when stubs are found; it never
17
+ # blocks the session from stopping.
16
18
  # Runs independently of (1) — it needs only the payload field or a
17
19
  # transcript path, not a session_id, so it still fires for a harness that
18
- # has no edited-files queue. A given message blocks once: harnesses without
20
+ # has no edited-files queue. A given message is warned about once: harnesses without
19
21
  # stop_hook_active (Antigravity, Kiro) have no other loop guard.
20
22
  # 3. Process-leak scan: DoFlow's own identifiers (FR-###, agent-docs/, chain
21
23
  # artifact names) reaching files that ship. Warns, never blocks.
@@ -26,7 +28,7 @@ case $0 in */*) _DOFLOW_POLDIR=${0%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
26
28
  # Canonical Policy Script Contract (design.md §4):
27
29
  # env DOFLOW_PROJECT_DIR, DOFLOW_AGENT (both optional here)
28
30
  # stdin envelope v1 from a native front door via the shared lifecycle bridge.
29
- # exit exit 2 + doflow_decide deny = deny; other faults per IC-011.
31
+ # exit always 0; a finding is a doflow_decide advisory code plus one stderr line.
30
32
  #
31
33
  # Depends on lib.sh (require_jq, json_field, ensure_session_dir,
32
34
  # run_with_timeout) being discoverable next to this script when it runs — see
@@ -84,7 +86,8 @@ TRANSCRIPT_PATH=$(json_field "$INPUT" ".transcript_path")
84
86
 
85
87
  # ── 1. Lint dispatch (only when we have a session-scoped edited-files queue) ──
86
88
 
87
- if [ -n "$SESSION_ID" ]; then
89
+ # With no config home (SESSION_DIR empty) there is no queue to read; the stub check below still runs.
90
+ if [ -n "$SESSION_ID" ] && [ -n "$SESSION_DIR" ]; then
88
91
  SESSION_PATH=$(ensure_session_dir "$SESSION_ID")
89
92
  EDITED_FILES="$SESSION_PATH/edited-files.txt"
90
93
  PROC_FILE="$SESSION_PATH/edited-files.txt.proc"
@@ -104,12 +107,14 @@ if [ -n "$SESSION_ID" ]; then
104
107
  # The resolver for the leak-scan verb. Absent install -> the scan is
105
108
  # skipped, like every other tool below: this hook has never required
106
109
  # anything to be present.
110
+ # HOME may be unset (an absolute XDG_CONFIG_HOME alone gives a config home): its candidates drop out.
107
111
  DOFLOW_RUN=""
112
+ claude_dir="${CLAUDE_CONFIG_DIR:-${HOME:+$HOME/.claude}}"
108
113
  for candidate in \
109
- "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/scripts/doflow/bin/doflow-run" \
110
- "$HOME/.doflow/scripts/doflow/bin/doflow-run"
114
+ "${claude_dir:+$claude_dir/scripts/doflow/bin/doflow-run}" \
115
+ "${HOME:+$HOME/.doflow/scripts/doflow/bin/doflow-run}"
111
116
  do
112
- [ -x "$candidate" ] && { DOFLOW_RUN="$candidate"; break; }
117
+ [ -n "$candidate" ] && [ -x "$candidate" ] && { DOFLOW_RUN="$candidate"; break; }
113
118
  done
114
119
 
115
120
  while IFS= read -r path; do
@@ -187,9 +192,10 @@ fi
187
192
 
188
193
  # The payload's own last_assistant_message is the response being stopped on. A present key
189
194
  # (even null or empty) is authoritative: the transcript is only read when the key is absent.
190
- # jq filter for the transcript fallback: one JSON object per line, assistant text from three
195
+ # jq filter for the transcript fallback: one JSON object per line, assistant text from four
191
196
  # shapes — Claude Code (.message with text blocks), Codex rollout (response_item .payload with
192
- # output_text blocks) and the flat {role,content} line. A partial or foreign line yields "".
197
+ # output_text blocks), Copilot CLI events.jsonl (type assistant.message, .data.content a string) and
198
+ # the flat {role,content} line. A partial or foreign line yields "".
193
199
  read -r -d '' LAST_ASSISTANT_JQ <<'JQ' || true
194
200
  def text: if type == "string" then .
195
201
  elif type == "array" then [ .[]? | objects | select(.type == "text" or .type == "output_text") | .text | strings ] | join("\n")
@@ -197,6 +203,7 @@ def text: if type == "string" then .
197
203
  [ inputs | fromjson? | objects
198
204
  | if ((.message | objects | .role) // null) == "assistant" then .message.content
199
205
  elif .type == "response_item" and ((.payload | objects | .role) // null) == "assistant" then .payload.content
206
+ elif .type == "assistant.message" then .data.content
200
207
  elif .role == "assistant" then .content
201
208
  else empty end
202
209
  | text | select(length > 0) ] | last // ""
@@ -271,21 +278,26 @@ BEGIN {
271
278
  STUB_PATTERN='(#|//)[[:space:]]*(TODO|FIXME)([^[:alnum:]_]|$)|raise NotImplementedError|throw new Error\(.*[Nn]ot [Ii]mplemented|(#|//)[[:space:]]*stub([^[:alnum:]_]|$)'
272
279
 
273
280
  if grep -qiE -- "$STUB_PATTERN" <<<"$STUB_TEXT" 2>/dev/null; then
274
- # Block a given message once: the continuation that follows is judged on new text, and a
281
+ # Warn about a given message once: the continuation that follows is judged on new text, and a
275
282
  # harness with no stop_hook_active would otherwise be blocked on this one forever. State is
276
283
  # per session, or per transcript when the harness sends no session_id; any failure here
277
- # leaves the block in force only for this call.
284
+ # leaves the block in force only for this call. With no config home there is no state store, so
285
+ # this policy cannot remember a block and allows the stop.
286
+ [ -n "$SESSION_DIR" ] || exit 0
278
287
  GUARD_KEY="$SESSION_ID"
279
288
  [ -z "$GUARD_KEY" ] && GUARD_KEY="t$(printf '%s' "$TRANSCRIPT_PATH" | cksum | cut -d' ' -f1)"
280
- GUARD_FILE="$(ensure_session_dir "$GUARD_KEY" 2>/dev/null)/stop-last-blocked" || GUARD_FILE=""
289
+ GUARD_FILE=""
290
+ if [ -n "$SESSION_DIR" ]; then
291
+ GUARD_FILE="$(ensure_session_dir "$GUARD_KEY" 2>/dev/null)/stop-last-blocked" || GUARD_FILE=""
292
+ fi
281
293
  MESSAGE_SUM=$(printf '%s' "$LAST_ASSISTANT_CONTENT" | cksum 2>/dev/null) || MESSAGE_SUM=""
282
294
  if [ -n "$MESSAGE_SUM" ] && [ -n "$GUARD_FILE" ] && [ "$(cat "$GUARD_FILE" 2>/dev/null)" = "$MESSAGE_SUM" ]; then
283
295
  exit 0
284
296
  fi
285
297
  [ -n "$MESSAGE_SUM" ] && [ -n "$GUARD_FILE" ] && { printf '%s\n' "$MESSAGE_SUM" > "$GUARD_FILE"; } 2>/dev/null || true
286
298
  echo "[stop-check] The last response contains an unfinished-work marker (TODO/FIXME/stub comment or a not-implemented raise/throw)." >&2
287
- doflow_decide deny unfinished-work
288
- exit 2
299
+ doflow_decide advisory unfinished-work
300
+ exit 0
289
301
  fi
290
302
 
291
303
  exit 0
@@ -1,16 +1,17 @@
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
  # subagent-audit.sh — Canonical Policy Library: SubagentStart + SubagentStop hook
4
5
  # (pure observability, no deny path)
5
6
  #
6
7
  # 022-hooks-remaining-duplication: claude and codex's copies were byte-identical — moved here as
7
- # the single canonical copy. Gemini has no SubagentStart/SubagentStop-equivalent event.
8
+ # the single canonical copy.
8
9
  #
9
10
  # Appends {timestamp, session_id, event, agent_type, agent_id} to a session-scoped audit log.
10
11
  # Today there is zero record of which of the installed agents/ specialists actually run, how often, or
11
12
  # whether one is invoked outside its intended use (e.g. everything routing through general-purpose
12
13
  # instead of do-code-review/security-engineer) — this hook is the evidence base a future policy
13
- # hook (e.g. an agent-aware pre-bash-guard extension) would need before writing rules on a guess.
14
+ # hook (e.g. an agent-aware tool guard) would need before writing rules on a guess.
14
15
  # Per agent-docs/research/hook-governance-agent-tool-mcp-skill.md §3.1: pure logging, no deny path,
15
16
  # safe to ship immediately, and the recommended first step before any tighter agent governance.
16
17
  #
@@ -56,6 +57,8 @@ fi
56
57
 
57
58
  # Guard: if we can't determine the session, nothing to do
58
59
  [[ -z "$SESSION_ID" ]] && exit 0
60
+ # No config home (lib.sh leaves the state paths empty): no session store to write (086 IC-010).
61
+ [[ -n "$SESSION_DIR" ]] || exit 0
59
62
 
60
63
  EVENT=$(json_field "$INPUT" ".hook_event_name")
61
64
  AGENT_TYPE=$(json_field "$INPUT" ".agent_type")