@khoavu882/doflow 2.0.0-beta.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (497) hide show
  1. package/README.md +12 -11
  2. package/bin/doflow.js +21 -11
  3. package/core/.antigravity-plugin/plugin.json +1 -3
  4. package/core/.claude-plugin/plugin.json +1 -1
  5. package/core/.codex-plugin/plugin.json +1 -1
  6. package/core/.plugin/plugin.json +1 -1
  7. package/core/harnesses/claude/hooks/lib.sh +43 -24
  8. package/core/harnesses/claude/hooks/mcp-tool-guard.sh +7 -17
  9. package/core/harnesses/claude/hooks/permission-audit.sh +3 -0
  10. package/core/harnesses/claude/hooks/post-compact.sh +35 -32
  11. package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
  12. package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
  13. package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
  14. package/core/harnesses/claude/hooks/pre-bash-guard.sh +7 -17
  15. package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
  16. package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
  17. package/core/harnesses/claude/hooks/session-end.sh +23 -10
  18. package/core/harnesses/claude/hooks/session-start.sh +5 -3
  19. package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
  20. package/core/harnesses/claude/hooks/stop-check.sh +5 -3
  21. package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
  22. package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
  23. package/core/harnesses/claude/settings/settings.json +18 -0
  24. package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
  25. package/core/harnesses/codex/agents/core-implementer.toml +1 -0
  26. package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
  27. package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
  28. package/core/harnesses/codex/agents/research-writer.toml +1 -1
  29. package/core/harnesses/codex/agents/reviewer.toml +10 -0
  30. package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
  31. package/core/harnesses/codex/agents/system-architect.toml +1 -1
  32. package/core/harnesses/codex/hooks/lib.sh +44 -25
  33. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +7 -15
  34. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
  35. package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
  36. package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
  37. package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
  38. package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
  39. package/core/harnesses/codex/hooks/session-start.sh +5 -3
  40. package/core/harnesses/codex/hooks/stop-check.sh +6 -5
  41. package/core/harnesses/codex/hooks/subagent-audit.sh +18 -6
  42. package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
  43. package/core/harnesses/copilot/hooks/doflow-lib.sh +93 -0
  44. package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
  45. package/core/harnesses/copilot/hooks/doflow-pre-bash-guard.sh +9 -0
  46. package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
  47. package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
  48. package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
  49. package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
  50. package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
  51. package/core/harnesses/copilot/hooks/doflow.json +57 -0
  52. package/core/harnesses/kiro/agents/doflow.json +1 -1
  53. package/core/harnesses/kiro/hooks/lib.sh +26 -6
  54. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +21 -5
  55. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +21 -5
  56. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +21 -5
  57. package/core/harnesses/kiro/hooks/session-start.sh +12 -5
  58. package/core/harnesses/kiro/hooks/stop-check.sh +22 -30
  59. package/core/harnesses/pi/extensions/doflow-guard.js +167 -0
  60. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -12
  61. package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
  62. package/core/harnesses/shared/hooks/bridge/bridge.sh +277 -0
  63. package/core/harnesses/shared/hooks/bridge/envelope.jq +129 -0
  64. package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
  65. package/core/harnesses/shared/hooks/bridge/respond.sh +70 -0
  66. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
  67. package/core/harnesses/shared/hooks/policies/capture-failure.sh +51 -16
  68. package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
  69. package/core/harnesses/shared/hooks/policies/contract.sh +78 -0
  70. package/core/harnesses/shared/hooks/policies/deny-json.sh +35 -9
  71. package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
  72. package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
  73. package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
  74. package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
  75. package/core/harnesses/shared/hooks/policies/lib.sh +65 -40
  76. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +48 -35
  77. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +284 -33
  78. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +180 -110
  79. package/core/harnesses/shared/hooks/policies/session-context.sh +66 -7
  80. package/core/harnesses/shared/hooks/policies/stop-check.sh +61 -23
  81. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +39 -6
  82. package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
  83. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +97 -159
  84. package/core/harnesses/shared/hooks/stream-hook-runner.js +114 -187
  85. package/core/harnesses/shared/locator/doflow-run +2 -3
  86. package/core/registry/advice.json +3 -3
  87. package/core/registry/assets.json +72 -80
  88. package/core/registry/capabilities.json +12 -0
  89. package/core/registry/contracts.json +60 -33
  90. package/core/registry/contribution-points.json +32 -0
  91. package/core/registry/gates.json +32 -0
  92. package/core/registry/guidance-caps.json +40 -0
  93. package/core/registry/harnesses.json +1542 -277
  94. package/core/registry/lifecycle.json +2837 -37
  95. package/core/registry/mcp.json +5 -1
  96. package/core/registry/models.json +7 -1
  97. package/core/registry/package-templates/README.md +19 -0
  98. package/core/registry/package-templates/agent/files/agent.md +9 -0
  99. package/core/registry/package-templates/agent/template.json +4 -0
  100. package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
  101. package/core/registry/package-templates/capability-provider/template.json +11 -0
  102. package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
  103. package/core/registry/package-templates/debate-preset/template.json +4 -0
  104. package/core/registry/package-templates/review-preset/files/preset.json +30 -0
  105. package/core/registry/package-templates/review-preset/template.json +4 -0
  106. package/core/registry/package-templates/skill/files/SKILL.md +8 -0
  107. package/core/registry/package-templates/skill/template.json +4 -0
  108. package/core/registry/package-templates/worker/files/worker.json +92 -0
  109. package/core/registry/package-templates/worker/template.json +11 -0
  110. package/core/registry/packages/doflow/doflow-package.json +15 -0
  111. package/core/registry/packages/doflow/presets/debate-3.json +26 -0
  112. package/core/registry/protocols.json +61 -0
  113. package/core/registry/routes.json +17 -0
  114. package/core/registry/rules.json +431 -0
  115. package/core/registry/settings.json +276 -0
  116. package/core/registry/storage.json +701 -30
  117. package/core/registry/telemetry.json +236 -0
  118. package/core/registry/transcripts.json +142 -0
  119. package/core/registry/verification.json +76 -1
  120. package/core/registry/workflows.json +55 -0
  121. package/core/shared/agent-specs/core-implementer.md +3 -0
  122. package/core/shared/agent-specs/delivery-lead.md +68 -0
  123. package/core/shared/agent-specs/quality-guardian.md +5 -1
  124. package/core/shared/agent-specs/research-writer.md +10 -3
  125. package/core/shared/agent-specs/reviewer.md +53 -0
  126. package/core/shared/agent-specs/spec-analyst.md +5 -6
  127. package/core/shared/agent-specs/system-architect.md +5 -1
  128. package/core/shared/guidance/DOFLOW_CORE.md +1 -5
  129. package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
  130. package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
  131. package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
  132. package/core/shared/guidance/pointers/codex.md +1 -4
  133. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
  134. package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
  135. package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
  136. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
  137. package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
  138. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
  139. package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
  140. package/core/shared/guidance/references/ORCHESTRATION.md +1 -2
  141. package/core/shared/guidance/rules/RULES.md +45 -0
  142. package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
  143. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
  144. package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
  145. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
  146. package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
  147. package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
  148. package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
  149. package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
  150. package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
  151. package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
  152. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
  153. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +48 -4
  154. package/core/shared/scripts/doflow/bin/doflow-run +154 -35
  155. package/core/shared/skills/do/SKILL.md +12 -10
  156. package/core/shared/skills/do/references/advice_calls.md +26 -0
  157. package/core/shared/skills/do/references/pm_routing.md +1 -2
  158. package/core/shared/skills/do/references/program_mode.md +31 -0
  159. package/core/shared/skills/do-brainstorm/SKILL.md +20 -74
  160. package/core/shared/skills/do-brainstorm/references/handoff_branches.md +35 -0
  161. package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
  162. package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
  163. package/core/shared/skills/do-code-review/SKILL.md +41 -144
  164. package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
  165. package/core/shared/skills/do-code-review/references/tools.md +90 -0
  166. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
  167. package/core/shared/skills/do-design/SKILL.md +24 -23
  168. package/core/shared/skills/do-diagnose/SKILL.md +14 -4
  169. package/core/shared/skills/do-document/SKILL.md +11 -1
  170. package/core/shared/skills/do-document/references/deep_research.md +1 -2
  171. package/core/shared/skills/do-document/references/embedded-research.md +18 -6
  172. package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
  173. package/core/shared/skills/do-execute-plan/SKILL.md +17 -59
  174. package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
  175. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
  176. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +28 -1
  177. package/core/shared/skills/do-execute-plan/references/run_position.md +13 -1
  178. package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
  179. package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
  180. package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
  181. package/core/shared/skills/do-flow/SKILL.md +8 -9
  182. package/core/shared/skills/do-flow/references/task_classes.md +2 -2
  183. package/core/shared/skills/do-git/SKILL.md +4 -0
  184. package/core/shared/skills/do-implement/SKILL.md +7 -9
  185. package/core/shared/skills/do-plan/SKILL.md +29 -19
  186. package/core/shared/skills/do-test/SKILL.md +7 -4
  187. package/core/shared/templates/doflow/constitution-template.md +9 -3
  188. package/core/shared/templates/doflow/data-model-template.md +1 -1
  189. package/core/shared/templates/doflow/design-template.md +113 -16
  190. package/core/shared/templates/doflow/plan-template.md +11 -10
  191. package/core/shared/templates/doflow/question-log-template.md +14 -2
  192. package/core/shared/templates/doflow/requirement-template.md +1 -1
  193. package/core/worker-evidence/antigravity/checks.json +14 -0
  194. package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
  195. package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
  196. package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
  197. package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
  198. package/core/worker-evidence/codex/checks.json +38 -0
  199. package/package.json +10 -6
  200. package/src/adapters/antigravity/index.js +226 -113
  201. package/src/adapters/claude/index.js +39 -5
  202. package/src/adapters/codex/agents.js +25 -15
  203. package/src/adapters/codex/hooks.js +40 -5
  204. package/src/adapters/codex/index.js +100 -22
  205. package/src/adapters/codex/native-projection.js +6 -2
  206. package/src/adapters/copilot/index.js +58 -23
  207. package/src/adapters/copy-tree.js +294 -48
  208. package/src/adapters/guidance-manifest.js +71 -0
  209. package/src/adapters/guidance-pointer.js +19 -0
  210. package/src/adapters/hook-commands.js +6 -10
  211. package/src/adapters/index.js +1 -0
  212. package/src/adapters/kiro/index.js +38 -13
  213. package/src/adapters/opencode/index.js +8 -8
  214. package/src/adapters/pi/hooks.js +120 -0
  215. package/src/adapters/pi/index.js +48 -16
  216. package/src/adapters/resolve-source.js +26 -2
  217. package/src/cli/commands/install.js +3 -2
  218. package/src/cli/commands/reconcile.js +53 -9
  219. package/src/cli/commands/remove.js +2 -2
  220. package/src/cli/commands/rollback.js +6 -3
  221. package/src/cli/commands/self-update.js +18 -9
  222. package/src/cli/commands/status.js +21 -2
  223. package/src/cli/commands/ui.js +99 -0
  224. package/src/cli/commands/update.js +3 -2
  225. package/src/cli/index.js +338 -33
  226. package/src/cli/runtime-commands.js +243 -52
  227. package/src/cli/shared.js +0 -2
  228. package/src/helper/git.js +1 -1
  229. package/src/helper/guardrails.js +1 -1
  230. package/src/helper/marker-merge.js +31 -13
  231. package/src/helper/package-ids.js +37 -0
  232. package/src/helper/semver.js +94 -0
  233. package/src/install/backup.js +105 -15
  234. package/src/install/context.js +1 -1
  235. package/src/install/targets.js +31 -16
  236. package/src/lifecycle/coverage.js +74 -0
  237. package/src/lifecycle/hook-step.js +61 -0
  238. package/src/lifecycle/hook-tier.js +160 -0
  239. package/src/lifecycle/index.js +434 -86
  240. package/src/lifecycle/retired-harnesses.js +318 -0
  241. package/src/lifecycle/view.js +35 -15
  242. package/src/registry/index.js +686 -32
  243. package/src/registry/worker-ids.js +45 -0
  244. package/src/release/build-package.js +0 -3
  245. package/src/release/docs-blocks.js +492 -0
  246. package/src/release/preflight.js +425 -0
  247. package/src/release/rehearse.js +401 -0
  248. package/src/release/release-workflow.js +733 -0
  249. package/src/release/sync-plugin-versions.js +43 -7
  250. package/src/runtime/advice/bench-gate.js +25 -0
  251. package/src/runtime/advice/cli.js +59 -16
  252. package/src/runtime/advice/client.js +32 -9
  253. package/src/runtime/advice/config.js +98 -133
  254. package/src/runtime/advice/doctor.js +1 -1
  255. package/src/runtime/advice/elevation.js +97 -0
  256. package/src/runtime/advice/endpoint-guard.js +9 -3
  257. package/src/runtime/advice/mode.js +37 -0
  258. package/src/runtime/advice/record.js +18 -5
  259. package/src/runtime/advice/registry.js +4 -1
  260. package/src/runtime/advice/shadow-config.js +229 -0
  261. package/src/runtime/advice/shadow-dispatcher.js +276 -0
  262. package/src/runtime/brief-rules.js +81 -0
  263. package/src/runtime/brief-tools.js +111 -34
  264. package/src/runtime/candidate.js +514 -0
  265. package/src/runtime/capabilities/executor.js +450 -0
  266. package/src/runtime/capabilities/loopback.js +41 -0
  267. package/src/runtime/capabilities/sanitizer.js +88 -0
  268. package/src/runtime/capability-router.js +135 -3
  269. package/src/runtime/checkouts.js +73 -11
  270. package/src/runtime/claims.js +27 -12
  271. package/src/runtime/cli-result.js +11 -4
  272. package/src/runtime/cli.js +221 -277
  273. package/src/runtime/config-home.js +42 -0
  274. package/src/runtime/context/arbitrate.js +767 -0
  275. package/src/runtime/context/budget.js +203 -0
  276. package/src/runtime/context/compose.js +1367 -0
  277. package/src/runtime/context/delivery-store.js +100 -0
  278. package/src/runtime/context/emission-rules.js +118 -0
  279. package/src/runtime/context/identity.js +227 -0
  280. package/src/runtime/context/mandatory.js +594 -0
  281. package/src/runtime/context/pointer.js +142 -0
  282. package/src/runtime/context/primary-command.js +117 -0
  283. package/src/runtime/context/primary.js +344 -0
  284. package/src/runtime/context/summary-store.js +655 -0
  285. package/src/runtime/context-pack.js +1106 -245
  286. package/src/runtime/decision-register.js +13 -4
  287. package/src/runtime/dispatch/admission.js +392 -0
  288. package/src/runtime/dispatch/attempt-end.js +274 -0
  289. package/src/runtime/dispatch/command.js +628 -0
  290. package/src/runtime/dispatch/controls.js +904 -0
  291. package/src/runtime/dispatch/envelope.js +276 -0
  292. package/src/runtime/dispatch/grants.js +310 -0
  293. package/src/runtime/dispatch/integrate.js +617 -0
  294. package/src/runtime/dispatch/loop.js +1835 -0
  295. package/src/runtime/dispatch/store.js +352 -0
  296. package/src/runtime/dispatch/verify-run.js +201 -0
  297. package/src/runtime/evidence-fields.js +39 -0
  298. package/src/runtime/evidence-ledger.js +41 -7
  299. package/src/runtime/failure/capture.js +3 -1
  300. package/src/runtime/failure/cli.js +25 -9
  301. package/src/runtime/failure/home.js +57 -30
  302. package/src/runtime/failure/store.js +7 -2
  303. package/src/runtime/feature-pointer.js +174 -0
  304. package/src/runtime/feature-resolve.js +13 -2
  305. package/src/runtime/fleet/command.js +77 -0
  306. package/src/runtime/fleet/projects.js +178 -0
  307. package/src/runtime/fleet/tree.js +383 -0
  308. package/src/runtime/freshness.js +77 -10
  309. package/src/runtime/git-memo.js +46 -0
  310. package/src/runtime/guidance/ablation.js +427 -0
  311. package/src/runtime/health.js +565 -17
  312. package/src/runtime/history-compactor.js +13 -3
  313. package/src/runtime/implementation-gate.js +277 -22
  314. package/src/runtime/inventory/coverage.js +1 -1
  315. package/src/runtime/inventory/index.js +1 -1
  316. package/src/runtime/inventory/precedence.js +2 -2
  317. package/src/runtime/inventory/siblings.js +6 -4
  318. package/src/runtime/knowledge/code-corpus.js +277 -0
  319. package/src/runtime/knowledge/code-lexical.js +130 -0
  320. package/src/runtime/knowledge/code-retrieval.js +307 -0
  321. package/src/runtime/knowledge/code-validation.js +106 -0
  322. package/src/runtime/knowledge/gp3-gate.js +74 -0
  323. package/src/runtime/knowledge/graph-adapter.js +288 -0
  324. package/src/runtime/knowledge/graph-fallback.js +394 -0
  325. package/src/runtime/knowledge/hybrid.js +136 -8
  326. package/src/runtime/knowledge/retrieval.js +34 -1
  327. package/src/runtime/knowledge/rtk-compress.js +77 -0
  328. package/src/runtime/knowledge/semble-bridge.py +106 -0
  329. package/src/runtime/knowledge/semble-lifecycle.js +114 -0
  330. package/src/runtime/knowledge/semble-provider.js +365 -0
  331. package/src/runtime/lifecycle/cli.js +16 -6
  332. package/src/runtime/lifecycle/event-store.js +8 -6
  333. package/src/runtime/lifecycle/followup.js +6 -1
  334. package/src/runtime/lifecycle/overview.js +24 -1
  335. package/src/runtime/lifecycle/report-store.js +8 -10
  336. package/src/runtime/lifecycle/retention.js +95 -31
  337. package/src/runtime/lifecycle/root.js +9 -1
  338. package/src/runtime/lifecycle/status.js +34 -17
  339. package/src/runtime/lifecycle/store-upkeep.js +56 -7
  340. package/src/runtime/mask.js +134 -7
  341. package/src/runtime/mcp-consultations.js +40 -6
  342. package/src/runtime/model-router.js +79 -7
  343. package/src/runtime/models/catalogue.js +191 -0
  344. package/src/runtime/models/command.js +153 -0
  345. package/src/runtime/off-words.js +12 -0
  346. package/src/runtime/outcome.js +3 -3
  347. package/src/runtime/packages/command.js +1009 -0
  348. package/src/runtime/packages/contributions.js +116 -0
  349. package/src/runtime/packages/digest.js +132 -0
  350. package/src/runtime/packages/fetch.js +182 -0
  351. package/src/runtime/packages/grants.js +192 -0
  352. package/src/runtime/packages/index-file.js +134 -0
  353. package/src/runtime/packages/instruction.js +90 -0
  354. package/src/runtime/packages/manifest.js +331 -0
  355. package/src/runtime/packages/points.js +477 -0
  356. package/src/runtime/packages/programs.js +216 -0
  357. package/src/runtime/packages/scaffold.js +277 -0
  358. package/src/runtime/packages/source.js +90 -0
  359. package/src/runtime/packages/state.js +164 -0
  360. package/src/runtime/packages/store.js +449 -0
  361. package/src/runtime/packages/tar.js +106 -0
  362. package/src/runtime/packages/view.js +406 -0
  363. package/src/runtime/plan-check.js +59 -0
  364. package/src/runtime/plan-content.js +324 -0
  365. package/src/runtime/policy-init.js +118 -0
  366. package/src/runtime/profiles/doctor.js +96 -0
  367. package/src/runtime/profiles/resolve.js +244 -0
  368. package/src/runtime/profiles/rollback.js +254 -0
  369. package/src/runtime/profiles/sampler.js +41 -0
  370. package/src/runtime/readiness-record.js +16 -11
  371. package/src/runtime/readiness.js +127 -16
  372. package/src/runtime/research-request.js +50 -25
  373. package/src/runtime/retrieval-plan.js +402 -73
  374. package/src/runtime/retrieval-record.js +293 -0
  375. package/src/runtime/review/command.js +246 -0
  376. package/src/runtime/review/dominance.js +68 -0
  377. package/src/runtime/review/findings.js +434 -0
  378. package/src/runtime/review/identity.js +255 -0
  379. package/src/runtime/review/protocol-command.js +109 -0
  380. package/src/runtime/review/protocols.js +405 -0
  381. package/src/runtime/review/resolve-protocol.js +302 -0
  382. package/src/runtime/review/start.js +530 -0
  383. package/src/runtime/roadmap/facts.js +479 -0
  384. package/src/runtime/roadmap/gates.js +270 -0
  385. package/src/runtime/roadmap/loop.js +1636 -0
  386. package/src/runtime/roadmap/merge.js +381 -0
  387. package/src/runtime/roadmap/rows.js +1113 -0
  388. package/src/runtime/roadmap/seed.js +951 -0
  389. package/src/runtime/rules-report.js +336 -0
  390. package/src/runtime/scaffold/artifacts.js +63 -9
  391. package/src/runtime/scaffold/generate.js +21 -9
  392. package/src/runtime/settings/autopilot.js +106 -0
  393. package/src/runtime/settings/cli.js +280 -0
  394. package/src/runtime/settings/config-write.js +314 -0
  395. package/src/runtime/settings/files.js +271 -0
  396. package/src/runtime/settings/legacy.js +154 -0
  397. package/src/runtime/settings/lexical.js +56 -0
  398. package/src/runtime/settings/prepared-run.js +269 -0
  399. package/src/runtime/settings/project-layers.js +118 -0
  400. package/src/runtime/settings/refs.js +288 -0
  401. package/src/runtime/settings/registry.js +553 -0
  402. package/src/runtime/settings/resolve.js +713 -0
  403. package/src/runtime/settings/shared.js +37 -0
  404. package/src/runtime/settings/worker-billing.js +107 -0
  405. package/src/runtime/settings/write.js +269 -0
  406. package/src/runtime/slot-command.js +78 -0
  407. package/src/runtime/slots.js +671 -0
  408. package/src/runtime/source-version.js +290 -0
  409. package/src/runtime/state-root.js +217 -0
  410. package/src/runtime/storage/cli.js +12 -5
  411. package/src/runtime/storage/engine.js +9 -2
  412. package/src/runtime/storage/registry.js +14 -1
  413. package/src/runtime/storage/roots.js +66 -16
  414. package/src/runtime/storage/rules.js +82 -10
  415. package/src/runtime/storage/upkeep.js +10 -2
  416. package/src/runtime/storage/work-status.js +245 -26
  417. package/src/runtime/task-attempts.js +589 -69
  418. package/src/runtime/task-classifier.js +47 -11
  419. package/src/runtime/task-graph.js +373 -0
  420. package/src/runtime/task-run.js +778 -0
  421. package/src/runtime/task-scope.js +202 -56
  422. package/src/runtime/task-sources.js +147 -0
  423. package/src/runtime/task-state.js +440 -65
  424. package/src/runtime/team/admission.js +301 -0
  425. package/src/runtime/team/envelope.js +324 -0
  426. package/src/runtime/team/review-guard.js +156 -0
  427. package/src/runtime/trace/analyze.js +427 -0
  428. package/src/runtime/trace/baseline.js +770 -0
  429. package/src/runtime/trace/ledger.js +63 -140
  430. package/src/runtime/trace/otlp-export.js +568 -0
  431. package/src/runtime/trace/otlp-map.js +481 -0
  432. package/src/runtime/trace/spans.js +745 -0
  433. package/src/runtime/trace/telemetry.js +225 -0
  434. package/src/runtime/trace/views.js +1 -0
  435. package/src/runtime/transcripts/command.js +98 -0
  436. package/src/runtime/transcripts/cursor.js +326 -0
  437. package/src/runtime/transcripts/read.js +126 -0
  438. package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
  439. package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
  440. package/src/runtime/transcripts/readers/copilot-events.js +90 -0
  441. package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
  442. package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
  443. package/src/runtime/transcripts/registry.js +161 -0
  444. package/src/runtime/transcripts/stats.js +161 -0
  445. package/src/runtime/verification/check-key.js +628 -0
  446. package/src/runtime/verification/contract-runner.js +546 -11
  447. package/src/runtime/verification/engine.js +499 -9
  448. package/src/runtime/verification/impact.js +617 -0
  449. package/src/runtime/verification/inflight.js +205 -0
  450. package/src/runtime/verification/registry.js +176 -0
  451. package/src/runtime/verification/reuse.js +184 -0
  452. package/src/runtime/verification/telemetry-emit.js +254 -0
  453. package/src/runtime/verification/test-selection.js +67 -7
  454. package/src/runtime/worker/active.js +90 -0
  455. package/src/runtime/worker/cancel.js +222 -0
  456. package/src/runtime/worker/catalogue.js +122 -0
  457. package/src/runtime/worker/command.js +677 -0
  458. package/src/runtime/worker/evidence.js +288 -0
  459. package/src/runtime/worker/launch.js +288 -0
  460. package/src/runtime/worker/models.js +137 -0
  461. package/src/runtime/worker/parsers.js +218 -0
  462. package/src/runtime/worker/probes/index.js +706 -0
  463. package/src/runtime/worker/process-tree.js +415 -0
  464. package/src/runtime/worker/quota.js +43 -0
  465. package/src/runtime/worker/readiness.js +713 -0
  466. package/src/runtime/worker/run-store.js +166 -0
  467. package/src/runtime/worker/supervisor.js +541 -0
  468. package/src/runtime/worker/worktree-check.js +252 -0
  469. package/src/runtime/workflow-engine.js +5 -1
  470. package/src/runtime/workflow-orchestrator.js +578 -63
  471. package/src/runtime/worktree.js +149 -22
  472. package/src/state/index.js +1 -1
  473. package/src/state/lockfile.js +64 -10
  474. package/src/state/run-lock.js +1 -1
  475. package/types/node-commonjs.d.ts +106 -7
  476. package/core/.antigravity-plugin/hooks.json +0 -39
  477. package/core/harnesses/gemini/hooks/hooks.json +0 -77
  478. package/core/harnesses/gemini/hooks/lib.sh +0 -302
  479. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -21
  480. package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
  481. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -21
  482. package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
  483. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -22
  484. package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
  485. package/core/harnesses/gemini/hooks/session-end.sh +0 -5
  486. package/core/harnesses/gemini/hooks/session-start.sh +0 -5
  487. package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
  488. package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
  489. package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
  490. package/core/harnesses/shared/hooks/hooks.json +0 -47
  491. package/core/shared/guidance/FLAGS.md +0 -25
  492. package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
  493. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
  494. package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
  495. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
  496. package/src/adapters/gemini/hooks.js +0 -210
  497. package/src/adapters/gemini/index.js +0 -390
@@ -1,17 +1,18 @@
1
1
  #!/usr/bin/env bash
2
+ case "${OSTYPE:-}" in msys*|cygwin*|win32*) if command -v jq >/dev/null 2>&1; then jq() { command jq -b "$@"; }; fi ;; esac # native jq.exe ends lines with CRLF unless -b
3
+ _DOFLOW_SRC=${0//\\//}; case $_DOFLOW_SRC in */*) _DOFLOW_POLDIR=${_DOFLOW_SRC%/*} ;; *) _DOFLOW_POLDIR=. ;; esac
2
4
  # user-prompt-submit.sh — Canonical Policy Library: UserPromptSubmit hook
3
5
  #
4
6
  # 022-hooks-remaining-duplication: claude and codex's UserPromptSubmit policies share the same
5
- # context-gathering behavior. Gemini has no UserPromptSubmit-equivalent event in its native hook set.
7
+ # context-gathering behavior.
6
8
  #
7
- # On the FIRST prompt of a session: injects lightweight git context into the harness's LLM
8
- # context. Claude and Codex receive one nested envelope,
9
+ # Emission (078 IC-004): this policy reads the payload, records its decisions and runs the nudge
10
+ # classifier; doflow_emit_prompt (emission.sh) decides and renders the response. On the first
11
+ # prompt of a bootstrap unit that is git context, the scoped prior summary and the prior warning
12
+ # in one nested envelope,
9
13
  # {"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":...}}
10
- # because Claude Code ignores a top-level additionalContext. Claude's object also carries
11
- # sessionTitle for window identification, unless the payload's session_title shows the user
12
- # already titled the session; Codex rejects unknown fields, so its object never does.
13
- #
14
- # On subsequent prompts: prints {} (clean, no token waste), unless the nudge below is earned.
14
+ # with sessionTitle on every harness but Codex unless the payload already carries session_title
15
+ # (DEC-030). Later prompts print {} unless the nudge below is earned.
15
16
  #
16
17
  # Once per session, the first prompt that reads as a plain code-change request (decided by
17
18
  # prompt-nudge.jq against the rules in the workflow registry's `promptNudge` key) also carries a
@@ -21,32 +22,71 @@
21
22
  # opt-out file, a subagent prompt, a /do-flow already in progress) resolves to silence; see the
22
23
  # once-per-session marker in lib.sh. The nudge starts no node or doflow-run process.
23
24
  #
24
- # Multi-session safe: uses session_id-scoped `injected` flag — no shared state.
25
+ # Multi-session safe: the adapter's one-shot slot is per bootstrap unit (DEC-007).
25
26
  # Must complete in <100ms. Must NEVER output "decision: block".
26
27
 
27
28
  set -euo pipefail
28
29
  # shellcheck source=lib.sh
29
- source "$(dirname "$0")/lib.sh"
30
- require_jq
31
-
30
+ source "$_DOFLOW_POLDIR/lib.sh"
32
31
  INPUT=$(cat)
32
+ POLICY_DIR=$_DOFLOW_POLDIR
33
+ if [ -f "$POLICY_DIR/contract.sh" ]; then
34
+ # shellcheck source=contract.sh
35
+ source "$POLICY_DIR/contract.sh"
36
+ doflow_decision_init user-prompt-submit 1
37
+ else
38
+ doflow_decision_init() { :; }
39
+ doflow_decide() { :; }
40
+ ( . "$POLICY_DIR/capture-failure.sh"; doflow_capture_failure user-prompt-submit contract-missing ) >/dev/null 2>&1 || true
41
+ printf '{}'
42
+ exit 0
43
+ fi
44
+ if ! command -v jq >/dev/null 2>&1; then
45
+ doflow_decide error dependency-missing:jq
46
+ ( . "$POLICY_DIR/capture-failure.sh"; doflow_capture_failure user-prompt-submit dependency-missing:jq ) >/dev/null 2>&1 || true
47
+ fi
48
+ require_jq
49
+ # The emission authority (feature 078): the scoped summary store, the compiled rule table and the
50
+ # adapter. A missing file leaves its functions
51
+ # undefined, which the adapter (or the check below) answers with the silent response and an
52
+ # emission-deps capture.
53
+ # shellcheck source=summary-store.sh
54
+ [ ! -f "$_DOFLOW_POLDIR/summary-store.sh" ] || . "$_DOFLOW_POLDIR/summary-store.sh"
55
+ # shellcheck source=emission-rules.sh
56
+ [ ! -f "$_DOFLOW_POLDIR/emission-rules.sh" ] || . "$_DOFLOW_POLDIR/emission-rules.sh"
57
+ # shellcheck source=emission.sh
58
+ [ ! -f "$_DOFLOW_POLDIR/emission.sh" ] || . "$_DOFLOW_POLDIR/emission.sh"
33
59
  # One jq pass over the payload for every field this hook reads (each pass costs about 8 ms on a
34
60
  # 20 KB prompt, and the budget is 100 ms), NUL-separated: session_id, cwd and session_title, null
35
61
  # and false read as empty as json_field does, with any NUL inside a value dropped so no field can
36
62
  # shift into the next; then `subagent` when agent_id or agent_type holds anything but null or "".
37
- SESSION_ID="" CWD="" PAYLOAD_TITLE="" SUBAGENT=""
38
- { IFS= read -r -d '' SESSION_ID; IFS= read -r -d '' CWD; IFS= read -r -d '' PAYLOAD_TITLE; IFS= read -r -d '' SUBAGENT; } < <(
63
+ SESSION_ID="" CWD="" PAYLOAD_TITLE="" SUBAGENT="" ENVELOPE_CLASS=missing
64
+ { IFS= read -r -d '' SESSION_ID; IFS= read -r -d '' CWD; IFS= read -r -d '' PAYLOAD_TITLE; IFS= read -r -d '' SUBAGENT; IFS= read -r -d '' ENVELOPE_CLASS; } < <(
39
65
  printf '%s' "$INPUT" | jq -j '. as $p
40
- | [$p.session_id, $p.cwd, $p.session_title]
66
+ | [if ($p.session_id | type) == "string" then ($p.session_id | rtrimstr("\n")) else $p.session_id end, $p.cwd, $p.session_title]
41
67
  | map(if . == null or . == false then "" elif type == "string" then . else tojson end | split("\u0000") | join(""))
42
68
  | . + [if any($p.agent_id, $p.agent_type; . != null and . != "") then "subagent" else "" end]
69
+ | . + [if (($p | type) != "object") or (($p.doflow_event | type) != "object") or (($p.doflow_event | has("version")) | not) then "missing" elif (($p.doflow_event.version | type) == "number") and $p.doflow_event.version == 1 then "v1" else "unsupported" end]
43
70
  | join("\u0000") + "\u0000"' 2>/dev/null
44
71
  ) || true
72
+ ENVELOPE_CLASS=${ENVELOPE_CLASS:-missing}
73
+ if [ ! -f "$POLICY_DIR/contract.sh" ]; then ENVELOPE_CLASS=missing; fi
74
+
75
+ if [[ "$ENVELOPE_CLASS" == unsupported || "$ENVELOPE_CLASS" == missing ]]; then
76
+ code=envelope-version
77
+ [[ "$ENVELOPE_CLASS" == missing ]] && code=envelope-missing
78
+ [[ -f "$POLICY_DIR/contract.sh" ]] || code=contract-missing
79
+ doflow_decide unsupported "$code"
80
+ if [[ -f "$POLICY_DIR/contract.sh" ]]; then
81
+ ( . "$_DOFLOW_POLDIR/capture-failure.sh"; doflow_capture_failure user-prompt-submit "$code" ) >/dev/null 2>&1 || true
82
+ fi
83
+ printf '{}'
84
+ exit 0
85
+ fi
45
86
 
46
87
  [[ -z "$SESSION_ID" ]] && exit 0
47
88
 
48
89
  SESSION_PATH="$SESSION_DIR/$SESSION_ID"
49
- INJECTED_FLAG="$SESSION_PATH/injected"
50
90
 
51
91
  # ── Prompt nudge (IC-004 N1-N8) ───────────────────────────────────────────────
52
92
 
@@ -55,17 +95,26 @@ INJECTED_FLAG="$SESSION_PATH/injected"
55
95
  # here can change the exit status or the first-prompt output. The prompt only ever travels to jq
56
96
  # on stdin, with stderr discarded, and is never copied out of INPUT.
57
97
  nudge_message() {
58
- local root policy_dir here registry decision message
98
+ local root policy_dir here registry decision message role
59
99
  [[ "${DOFLOW_AGENT:-}" == "claude" || "${DOFLOW_AGENT:-}" == "codex" ]] || return 0 # N1
60
- [[ "$(doflow_session_role 2>/dev/null || echo main)" != "worker" ]] || return 0 # a worker is never nudged
100
+ # The role gate is the rule table's: a role whose prompt.nudge action is skip (a worker) is never
101
+ # nudged, and returning here keeps the classifier from running or marking it (L2-15).
102
+ role=$(doflow_session_role 2>/dev/null) || role=main
103
+ DF_ACTION=skip
104
+ declare -F doflow_emission_rule >/dev/null 2>&1 && doflow_emission_rule prompt.nudge "$role:nudge" 2>/dev/null || DF_ACTION=skip
105
+ [[ "$DF_ACTION" != "skip" ]] || return 0
61
106
  nudge_safe_id "$SESSION_ID" || return 0 # N2
62
107
  root=$(nudge_repo_root "$CWD") || return 0
63
108
  [[ "$(nudge_setting "$root")" == "on" ]] || return 0 # N3
64
109
  [[ ! -e "$STATE_DIR/nudge/$SESSION_ID" ]] || return 0 # N4 (IC-008's path, no process)
110
+ # The marker is written after the render (DEC-041), so a folder it cannot be written to would
111
+ # nudge every prompt: an unwritable marker folder (or state folder, before it exists) is silent.
112
+ if [[ -e "$STATE_DIR/nudge" ]]; then [[ -d "$STATE_DIR/nudge" && -w "$STATE_DIR/nudge" ]] || return 0
113
+ elif [[ -e "$STATE_DIR" ]]; then [[ -w "$STATE_DIR" ]] || return 0; fi
65
114
  # N5: a subagent prompt carries agent_id or agent_type (read with the other fields above).
66
115
  [[ -z "$SUBAGENT" ]] || return 0
67
116
  # N6: the policy script's physical directory, found with built-ins (a subshell costs about 4 ms).
68
- case "$0" in */*) policy_dir="${0%/*}" ;; *) policy_dir="." ;; esac
117
+ policy_dir=$_DOFLOW_POLDIR
69
118
  here="$PWD"
70
119
  cd -P -- "$policy_dir" 2>/dev/null || return 0
71
120
  policy_dir="$PWD"
@@ -81,155 +130,44 @@ nudge_message() {
81
130
  nudge_mark "$SESSION_ID" suppressed || true
82
131
  return 0
83
132
  fi
84
- # N8: the message is read and checked before the marker is created, so a registry without a
85
- # usable message leaves no marker; a failed create (unwritable folder, a racing prompt) is silent.
133
+ # N8: a registry without a usable message leaves no marker. The `nudged` marker is written by
134
+ # doflow_emit_prompt once the nudge rendered, so a nudge the budget dropped stays unmarked (DEC-041).
86
135
  message=$(jq -r '.promptNudge.message | strings' "$registry" 2>/dev/null) || return 0
87
136
  [[ -n "$message" ]] || return 0
88
- nudge_mark "$SESSION_ID" nudged || return 0
89
137
  printf '%s' "$message"
90
138
  return 0
91
139
  }
92
140
 
93
- # One nested envelope for both harnesses (IC-002): $1 is the additionalContext; $2 the session
94
- # title, omitted when empty.
95
- emit_envelope() {
96
- jq -n --arg ctx "$1" --arg title "$2" \
97
- '{"hookSpecificOutput": ({"hookEventName": "UserPromptSubmit", "additionalContext": $ctx}
98
- + (if $title != "" then {"sessionTitle": $title} else {} end))}'
141
+ # ── Emission: every prompt, handed to the authority (IC-004) ──────────────────
142
+ # The classifier runs first, where its gates allow, and returns the message unmarked.
143
+ # doflow_emit_prompt decides everything else (the bootstrap slot, git context, the
144
+ # scoped summary, the warning, a grant, the nudge's place in the budget), prints the response and
145
+ # marks the session nudged and records `advisory prompt-nudge` itself when the nudge was rendered.
146
+
147
+ # Rider R1 (091): the emission metadata for the bridge's hook line, as one record on the decision
148
+ # fd after the decision records: the reason, the byte count and the digest, never a response byte. The
149
+ # bridge validates each value before it writes it. Telemetry off or no fd writes nothing.
150
+ doflow_emit_record() {
151
+ local fd="${DOFLOW_DECISION_FD:-}" digest=null
152
+ [ "${DOFLOW_TELEMETRY:-}" != off ] && [ -n "${DF_EMIT_REASON:-}" ] || return 0
153
+ [ -z "${DF_EMIT_DIGEST:-}" ] || digest="\"$DF_EMIT_DIGEST\""
154
+ case "$fd" in
155
+ 3|4|5|6|7|8|9)
156
+ { printf '\036{"v":1,"emit":{"reason":"%s","bytes":%s,"digest":%s}}\n' "$DF_EMIT_REASON" "${DF_EMIT_BYTES:-0}" "$digest" >&"$fd"; } 2>/dev/null || :
157
+ ;;
158
+ esac
159
+ return 0
99
160
  }
100
161
 
101
- # ── Subsequent prompts: no injection, unless the nudge is earned ──────────────
102
-
103
- if [[ -f "$INJECTED_FLAG" ]]; then
104
- NUDGE=$(nudge_message 2>/dev/null) || NUDGE=""
105
- if [[ -n "$NUDGE" ]]; then
106
- emit_envelope "$NUDGE" ""
107
- else
108
- echo "{}"
109
- fi
110
- exit 0
111
- fi
112
-
113
- # ── Worker session: no bootstrap, nothing claimed ─────────────────────────────
114
- # A worker never receives the git context, the prior compact summary or the prior warning, and
115
- # leaves both files for the main session. It is marked injected so later prompts stay silent.
116
-
117
- if [[ "$(doflow_session_role || echo main)" == "worker" ]]; then
118
- ensure_session_dir "$SESSION_ID" >/dev/null || true
119
- touch "$INJECTED_FLAG" 2>/dev/null || true
120
- echo "{}"
121
- exit 0
122
- fi
123
-
124
- # ── First prompt: build context ───────────────────────────────────────────────
125
-
126
- GIT_CONTEXT_FILE="$SESSION_PATH/git-context.json"
127
-
128
- # Fallback if session-start.sh didn't run or failed
129
- if [[ ! -f "$GIT_CONTEXT_FILE" ]]; then
130
- ensure_session_dir "$SESSION_ID" >/dev/null
131
- touch "$INJECTED_FLAG"
132
- CONTEXT="Git context unavailable for this session."
133
- SESSION_TITLE=""
134
- else
135
- GIT_JSON=$(cat "$GIT_CONTEXT_FILE")
136
- IS_GIT=$(json_field "$GIT_JSON" ".is_git_repo")
137
-
138
- if [[ "$IS_GIT" == "true" ]]; then
139
- BRANCH=$(json_field "$GIT_JSON" ".branch")
140
- SHA=$(json_field "$GIT_JSON" ".sha")
141
- UNCOMMITTED=$(json_field "$GIT_JSON" ".uncommitted_count")
142
- STASH=$(json_field "$GIT_JSON" ".stash_count")
143
-
144
- # Build commit list as a single line (· separated)
145
- COMMITS=$(echo "$GIT_JSON" | jq -r '.commits[]? // empty' | head -5 | paste -sd ' · ' -)
146
-
147
- CONTEXT="Git context — branch: ${BRANCH:-unknown} | ${SHA:-unknown}"$'\n'
148
- CONTEXT+="Last commits: ${COMMITS:-none}"$'\n'
149
- CONTEXT+="Uncommitted files: ${UNCOMMITTED:-0}"
150
- [[ "${STASH:-0}" -gt 0 ]] && CONTEXT+=" | Stashed: ${STASH}"
151
-
152
- SESSION_TITLE="${BRANCH:-unknown} — ${SHA:-unknown}"
153
- else
154
- CONTEXT="Not a git repository."
155
- SESSION_TITLE="no-git"
156
- fi
157
-
158
- # ── Prior compact summary: injected once into the next session, then consumed ─
159
- # post-compact.sh writes this file for the session that follows a compaction. The session
160
- # that compacted already holds the summary, so it skips the file and leaves it in place.
161
- # Any other session claims the file with an atomic rename first (a summary written meanwhile
162
- # is a new file and survives), reads a bounded prefix of the claimed copy and removes it. No
163
- # step here may fail the hook: on any error the summary is simply not injected.
164
-
165
- PROJECT_DIR=$(ensure_project_dir "$CWD")
166
- COMPACT_FILE="$PROJECT_DIR/last-compact-summary.md"
167
- COMPACT_CLAIM="$PROJECT_DIR/.last-compact-summary.claimed.$SESSION_ID"
168
- COMPACT_CAP=4000
169
- COMPACT_READ=65536 # bytes: enough for the cap even at four bytes per character
170
- compact_field() {
171
- printf '%s\n' "$COMPACT_HEAD" | awk -v k="$1:" '/^---$/{n++; if (n == 2) exit; next} n == 1 && index($0, k) == 1 {sub(/^[^:]*:[ ]*/, ""); print; exit}' || true
172
- }
173
- # A native subagent payload (agent_id or agent_type) never claims the summary or the warning.
174
- if [[ -z "$SUBAGENT" && -f "$COMPACT_FILE" && ! -L "$COMPACT_FILE" ]]; then
175
- COMPACT_HEAD=$(head -c "$COMPACT_READ" "$COMPACT_FILE" 2>/dev/null | tr -d '\r') || COMPACT_HEAD=''
176
- if [[ "$(compact_field session_id)" != "$SESSION_ID" ]] && mv "$COMPACT_FILE" "$COMPACT_CLAIM" 2>/dev/null; then
177
- COMPACT_SIZE=$(wc -c < "$COMPACT_CLAIM" 2>/dev/null) || COMPACT_SIZE=0
178
- COMPACT_HEAD=$(head -c "$COMPACT_READ" "$COMPACT_CLAIM" 2>/dev/null | tr -d '\r') || COMPACT_HEAD=''
179
- rm -f "$COMPACT_CLAIM"
180
- # Strip the YAML frontmatter (between the first two `---` lines) and the blank line after it;
181
- # keep the summary body only.
182
- COMPACT_BODY=$(printf '%s\n' "$COMPACT_HEAD" | awk '/^---$/ && n < 2 {n++; next} n >= 2 && (started || $0 != "") {started = 1; print}') || COMPACT_BODY=''
183
- COMPACT_LEN=''
184
- if [[ -n "$COMPACT_BODY" ]]; then
185
- # --rawfile, not stdin or --arg: jq 1.7's raw stdin reader miscounts multibyte text across
186
- # buffer boundaries, and --arg would hit the per-argument size limit on a large summary.
187
- COMPACT_LEN=$(jq -n --rawfile b <(printf '%s' "$COMPACT_BODY") '$b | length' 2>/dev/null) || COMPACT_BODY=''
188
- fi
189
- if [[ -n "$COMPACT_BODY" && "$COMPACT_LEN" -gt "$COMPACT_CAP" ]]; then
190
- COMPACT_BODY=$(jq -nr --rawfile b <(printf '%s' "$COMPACT_BODY") "\$b[0:$COMPACT_CAP]" 2>/dev/null) || COMPACT_BODY=''
191
- COMPACT_MORE=''
192
- [[ "$COMPACT_SIZE" -gt "$COMPACT_READ" ]] && COMPACT_MORE='at least '
193
- [[ -n "$COMPACT_BODY" ]] && COMPACT_BODY+=$'\n'"[summary truncated: first ${COMPACT_CAP} of ${COMPACT_MORE}${COMPACT_LEN} characters]"
194
- fi
195
- if [[ -n "$COMPACT_BODY" ]]; then
196
- COMPACT_AT=$(compact_field compacted_at); COMPACT_AT=${COMPACT_AT//]/}
197
- COMPACT_BRANCH=$(compact_field branch); COMPACT_BRANCH=${COMPACT_BRANCH//]/}
198
- COMPACT_HEADER="Prior session summary"
199
- [[ -n "$COMPACT_AT" && "$COMPACT_AT" != "unknown" ]] && COMPACT_HEADER+=", compacted ${COMPACT_AT}"
200
- [[ -n "$COMPACT_BRANCH" && "$COMPACT_BRANCH" != "unknown" ]] && COMPACT_HEADER+=" on branch ${COMPACT_BRANCH}"
201
- CONTEXT+=$'\n\n'"[${COMPACT_HEADER}]"$'\n'"$COMPACT_BODY"
202
- fi
203
- fi
204
- fi
205
-
206
- # Check for uncommitted warning from prior session (one-time: delete after read —
207
- # nothing else in the framework reassigns this cleanup, so it happens here)
208
- if [[ -z "$SUBAGENT" && -f "$PROJECT_DIR/uncommitted-warning.txt" ]]; then
209
- WARNING=$(cat "$PROJECT_DIR/uncommitted-warning.txt")
210
- CONTEXT+=$'\n'"[Prior session warning: ${WARNING}]"
211
- rm -f "$PROJECT_DIR/uncommitted-warning.txt"
212
- fi
213
- fi
214
-
215
- # ── Write injected flag ────────────────────────────────────────────────────────
216
-
217
- touch "$INJECTED_FLAG"
218
-
219
- # ── Output JSON ───────────────────────────────────────────────────────────────
220
-
221
- # The nudge, when earned, follows the context after a blank line.
222
162
  NUDGE=$(nudge_message 2>/dev/null) || NUDGE=""
223
- if [[ -n "$NUDGE" ]]; then
224
- CONTEXT+=$'\n\n'"$NUDGE"
225
- fi
226
-
227
- # sessionTitle: not on Codex, only when a title was built, and only when the user has not already
228
- # titled the session.
229
- TITLE_ARG=""
230
- if [[ "${DOFLOW_AGENT:-}" != "codex" && -n "${SESSION_TITLE:-}" && -z "$PAYLOAD_TITLE" ]]; then
231
- TITLE_ARG="$SESSION_TITLE"
163
+ if ! declare -F doflow_emit_prompt >/dev/null 2>&1; then
164
+ ( . "$POLICY_DIR/capture-failure.sh"; doflow_capture_failure user-prompt-submit emission-deps ) >/dev/null 2>&1 || true
165
+ printf '{}\n'
166
+ DF_EMIT_REASON=fault:deps DF_EMIT_BYTES=0 DF_EMIT_DIGEST=""
167
+ doflow_emit_record
168
+ exit 0
232
169
  fi
233
- emit_envelope "$CONTEXT" "$TITLE_ARG"
170
+ doflow_emit_prompt "$SESSION_ID" "$CWD" "$PAYLOAD_TITLE" "$SUBAGENT" "$NUDGE"
171
+ doflow_emit_record
234
172
 
235
173
  exit 0