@khoavu882/doflow 2.0.0-beta.5 → 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 (471) hide show
  1. package/README.md +12 -11
  2. package/bin/doflow.js +21 -11
  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/permission-audit.sh +3 -0
  9. package/core/harnesses/claude/hooks/post-compact.sh +35 -32
  10. package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
  11. package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
  12. package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
  13. package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
  14. package/core/harnesses/claude/hooks/session-end.sh +23 -10
  15. package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
  16. package/core/harnesses/claude/settings/settings.json +18 -0
  17. package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
  18. package/core/harnesses/codex/agents/core-implementer.toml +1 -0
  19. package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
  20. package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
  21. package/core/harnesses/codex/agents/research-writer.toml +1 -1
  22. package/core/harnesses/codex/agents/reviewer.toml +10 -0
  23. package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
  24. package/core/harnesses/codex/agents/system-architect.toml +1 -1
  25. package/core/harnesses/codex/hooks/lib.sh +44 -25
  26. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
  27. package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
  28. package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
  29. package/core/harnesses/codex/hooks/subagent-audit.sh +1 -0
  30. package/core/harnesses/copilot/hooks/doflow-lib.sh +93 -0
  31. package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
  32. package/core/harnesses/copilot/hooks/doflow-pre-bash-guard.sh +9 -0
  33. package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
  34. package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
  35. package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
  36. package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
  37. package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
  38. package/core/harnesses/copilot/hooks/doflow.json +57 -0
  39. package/core/harnesses/kiro/agents/doflow.json +1 -1
  40. package/core/harnesses/kiro/hooks/lib.sh +26 -6
  41. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +1 -0
  42. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +1 -0
  43. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +1 -0
  44. package/core/harnesses/kiro/hooks/session-start.sh +1 -0
  45. package/core/harnesses/kiro/hooks/stop-check.sh +1 -0
  46. package/core/harnesses/pi/extensions/doflow-guard.js +8 -0
  47. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +0 -1
  48. package/core/harnesses/shared/hooks/bridge/bridge.sh +102 -9
  49. package/core/harnesses/shared/hooks/bridge/envelope.jq +87 -18
  50. package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
  51. package/core/harnesses/shared/hooks/bridge/respond.sh +10 -2
  52. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
  53. package/core/harnesses/shared/hooks/policies/capture-failure.sh +48 -15
  54. package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
  55. package/core/harnesses/shared/hooks/policies/contract.sh +3 -0
  56. package/core/harnesses/shared/hooks/policies/deny-json.sh +2 -11
  57. package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
  58. package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
  59. package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
  60. package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
  61. package/core/harnesses/shared/hooks/policies/lib.sh +63 -40
  62. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +3 -2
  63. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +213 -12
  64. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +114 -38
  65. package/core/harnesses/shared/hooks/policies/session-context.sh +30 -1
  66. package/core/harnesses/shared/hooks/policies/stop-check.sh +20 -9
  67. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +5 -2
  68. package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
  69. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +60 -155
  70. package/core/harnesses/shared/hooks/stream-hook-runner.js +47 -8
  71. package/core/harnesses/shared/locator/doflow-run +2 -3
  72. package/core/registry/advice.json +3 -3
  73. package/core/registry/assets.json +55 -82
  74. package/core/registry/capabilities.json +12 -0
  75. package/core/registry/contracts.json +58 -31
  76. package/core/registry/contribution-points.json +32 -0
  77. package/core/registry/gates.json +32 -0
  78. package/core/registry/guidance-caps.json +40 -0
  79. package/core/registry/harnesses.json +1442 -363
  80. package/core/registry/lifecycle.json +485 -304
  81. package/core/registry/mcp.json +5 -1
  82. package/core/registry/models.json +7 -1
  83. package/core/registry/package-templates/README.md +19 -0
  84. package/core/registry/package-templates/agent/files/agent.md +9 -0
  85. package/core/registry/package-templates/agent/template.json +4 -0
  86. package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
  87. package/core/registry/package-templates/capability-provider/template.json +11 -0
  88. package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
  89. package/core/registry/package-templates/debate-preset/template.json +4 -0
  90. package/core/registry/package-templates/review-preset/files/preset.json +30 -0
  91. package/core/registry/package-templates/review-preset/template.json +4 -0
  92. package/core/registry/package-templates/skill/files/SKILL.md +8 -0
  93. package/core/registry/package-templates/skill/template.json +4 -0
  94. package/core/registry/package-templates/worker/files/worker.json +92 -0
  95. package/core/registry/package-templates/worker/template.json +11 -0
  96. package/core/registry/packages/doflow/doflow-package.json +15 -0
  97. package/core/registry/packages/doflow/presets/debate-3.json +26 -0
  98. package/core/registry/protocols.json +61 -0
  99. package/core/registry/routes.json +17 -0
  100. package/core/registry/rules.json +431 -0
  101. package/core/registry/settings.json +276 -0
  102. package/core/registry/storage.json +679 -31
  103. package/core/registry/telemetry.json +236 -0
  104. package/core/registry/transcripts.json +142 -0
  105. package/core/registry/verification.json +76 -1
  106. package/core/registry/workflows.json +55 -0
  107. package/core/shared/agent-specs/core-implementer.md +3 -0
  108. package/core/shared/agent-specs/delivery-lead.md +68 -0
  109. package/core/shared/agent-specs/quality-guardian.md +5 -1
  110. package/core/shared/agent-specs/research-writer.md +10 -3
  111. package/core/shared/agent-specs/reviewer.md +53 -0
  112. package/core/shared/agent-specs/spec-analyst.md +5 -6
  113. package/core/shared/agent-specs/system-architect.md +5 -1
  114. package/core/shared/guidance/DOFLOW_CORE.md +1 -5
  115. package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
  116. package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
  117. package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
  118. package/core/shared/guidance/pointers/codex.md +1 -4
  119. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
  120. package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
  121. package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
  122. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
  123. package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
  124. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
  125. package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
  126. package/core/shared/guidance/references/ORCHESTRATION.md +1 -2
  127. package/core/shared/guidance/rules/RULES.md +45 -0
  128. package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
  129. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
  130. package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
  131. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
  132. package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
  133. package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
  134. package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
  135. package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
  136. package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
  137. package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
  138. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
  139. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +48 -4
  140. package/core/shared/scripts/doflow/bin/doflow-run +149 -34
  141. package/core/shared/skills/do/SKILL.md +12 -10
  142. package/core/shared/skills/do/references/advice_calls.md +26 -0
  143. package/core/shared/skills/do/references/pm_routing.md +1 -2
  144. package/core/shared/skills/do/references/program_mode.md +31 -0
  145. package/core/shared/skills/do-brainstorm/SKILL.md +20 -74
  146. package/core/shared/skills/do-brainstorm/references/handoff_branches.md +35 -0
  147. package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
  148. package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
  149. package/core/shared/skills/do-code-review/SKILL.md +41 -144
  150. package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
  151. package/core/shared/skills/do-code-review/references/tools.md +90 -0
  152. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
  153. package/core/shared/skills/do-design/SKILL.md +18 -17
  154. package/core/shared/skills/do-diagnose/SKILL.md +14 -4
  155. package/core/shared/skills/do-document/SKILL.md +11 -1
  156. package/core/shared/skills/do-document/references/deep_research.md +1 -2
  157. package/core/shared/skills/do-document/references/embedded-research.md +18 -6
  158. package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
  159. package/core/shared/skills/do-execute-plan/SKILL.md +15 -58
  160. package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
  161. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
  162. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +26 -1
  163. package/core/shared/skills/do-execute-plan/references/run_position.md +13 -1
  164. package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
  165. package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
  166. package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
  167. package/core/shared/skills/do-flow/SKILL.md +8 -9
  168. package/core/shared/skills/do-flow/references/task_classes.md +2 -2
  169. package/core/shared/skills/do-git/SKILL.md +4 -0
  170. package/core/shared/skills/do-implement/SKILL.md +4 -7
  171. package/core/shared/skills/do-plan/SKILL.md +26 -15
  172. package/core/shared/skills/do-test/SKILL.md +7 -4
  173. package/core/shared/templates/doflow/constitution-template.md +9 -3
  174. package/core/shared/templates/doflow/data-model-template.md +1 -1
  175. package/core/shared/templates/doflow/design-template.md +113 -16
  176. package/core/shared/templates/doflow/plan-template.md +11 -10
  177. package/core/shared/templates/doflow/question-log-template.md +14 -2
  178. package/core/shared/templates/doflow/requirement-template.md +1 -1
  179. package/core/worker-evidence/antigravity/checks.json +14 -0
  180. package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
  181. package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
  182. package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
  183. package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
  184. package/core/worker-evidence/codex/checks.json +38 -0
  185. package/package.json +10 -6
  186. package/src/adapters/antigravity/index.js +143 -66
  187. package/src/adapters/claude/index.js +24 -4
  188. package/src/adapters/codex/agents.js +25 -15
  189. package/src/adapters/codex/index.js +48 -13
  190. package/src/adapters/codex/native-projection.js +6 -2
  191. package/src/adapters/copilot/index.js +58 -23
  192. package/src/adapters/copy-tree.js +290 -44
  193. package/src/adapters/guidance-manifest.js +71 -0
  194. package/src/adapters/guidance-pointer.js +19 -0
  195. package/src/adapters/hook-commands.js +6 -10
  196. package/src/adapters/index.js +1 -0
  197. package/src/adapters/kiro/index.js +23 -12
  198. package/src/adapters/opencode/index.js +8 -8
  199. package/src/adapters/pi/hooks.js +2 -1
  200. package/src/adapters/pi/index.js +14 -7
  201. package/src/adapters/resolve-source.js +26 -2
  202. package/src/cli/commands/install.js +2 -1
  203. package/src/cli/commands/reconcile.js +53 -9
  204. package/src/cli/commands/remove.js +2 -2
  205. package/src/cli/commands/rollback.js +6 -3
  206. package/src/cli/commands/self-update.js +18 -9
  207. package/src/cli/commands/status.js +21 -2
  208. package/src/cli/commands/ui.js +99 -0
  209. package/src/cli/commands/update.js +2 -1
  210. package/src/cli/index.js +322 -29
  211. package/src/cli/runtime-commands.js +209 -57
  212. package/src/cli/shared.js +0 -2
  213. package/src/helper/git.js +1 -1
  214. package/src/helper/guardrails.js +1 -1
  215. package/src/helper/marker-merge.js +31 -13
  216. package/src/helper/package-ids.js +37 -0
  217. package/src/helper/semver.js +94 -0
  218. package/src/install/backup.js +105 -15
  219. package/src/install/context.js +1 -1
  220. package/src/install/targets.js +31 -16
  221. package/src/lifecycle/coverage.js +20 -3
  222. package/src/lifecycle/hook-tier.js +160 -0
  223. package/src/lifecycle/index.js +412 -78
  224. package/src/lifecycle/retired-harnesses.js +318 -0
  225. package/src/lifecycle/view.js +35 -15
  226. package/src/registry/index.js +551 -26
  227. package/src/registry/worker-ids.js +45 -0
  228. package/src/release/build-package.js +0 -3
  229. package/src/release/docs-blocks.js +492 -0
  230. package/src/release/preflight.js +425 -0
  231. package/src/release/rehearse.js +401 -0
  232. package/src/release/release-workflow.js +733 -0
  233. package/src/release/sync-plugin-versions.js +43 -7
  234. package/src/runtime/advice/bench-gate.js +25 -0
  235. package/src/runtime/advice/cli.js +59 -16
  236. package/src/runtime/advice/client.js +32 -9
  237. package/src/runtime/advice/config.js +98 -133
  238. package/src/runtime/advice/doctor.js +1 -1
  239. package/src/runtime/advice/elevation.js +97 -0
  240. package/src/runtime/advice/endpoint-guard.js +9 -3
  241. package/src/runtime/advice/mode.js +37 -0
  242. package/src/runtime/advice/record.js +18 -5
  243. package/src/runtime/advice/registry.js +4 -1
  244. package/src/runtime/advice/shadow-config.js +229 -0
  245. package/src/runtime/advice/shadow-dispatcher.js +276 -0
  246. package/src/runtime/brief-rules.js +81 -0
  247. package/src/runtime/brief-tools.js +111 -34
  248. package/src/runtime/candidate.js +20 -11
  249. package/src/runtime/capabilities/executor.js +450 -0
  250. package/src/runtime/capabilities/loopback.js +41 -0
  251. package/src/runtime/capabilities/sanitizer.js +88 -0
  252. package/src/runtime/capability-router.js +135 -3
  253. package/src/runtime/checkouts.js +73 -11
  254. package/src/runtime/claims.js +13 -7
  255. package/src/runtime/cli.js +196 -19
  256. package/src/runtime/config-home.js +42 -0
  257. package/src/runtime/context/arbitrate.js +767 -0
  258. package/src/runtime/context/delivery-store.js +4 -6
  259. package/src/runtime/context/emission-rules.js +118 -0
  260. package/src/runtime/context/identity.js +227 -0
  261. package/src/runtime/context/primary-command.js +117 -0
  262. package/src/runtime/context/primary.js +344 -0
  263. package/src/runtime/context/summary-store.js +655 -0
  264. package/src/runtime/context-pack.js +154 -78
  265. package/src/runtime/decision-register.js +13 -4
  266. package/src/runtime/dispatch/admission.js +392 -0
  267. package/src/runtime/dispatch/attempt-end.js +274 -0
  268. package/src/runtime/dispatch/command.js +628 -0
  269. package/src/runtime/dispatch/controls.js +904 -0
  270. package/src/runtime/dispatch/envelope.js +276 -0
  271. package/src/runtime/dispatch/grants.js +310 -0
  272. package/src/runtime/dispatch/integrate.js +617 -0
  273. package/src/runtime/dispatch/loop.js +1835 -0
  274. package/src/runtime/dispatch/store.js +352 -0
  275. package/src/runtime/dispatch/verify-run.js +201 -0
  276. package/src/runtime/evidence-ledger.js +34 -7
  277. package/src/runtime/failure/capture.js +3 -1
  278. package/src/runtime/failure/cli.js +25 -9
  279. package/src/runtime/failure/home.js +57 -30
  280. package/src/runtime/failure/store.js +7 -2
  281. package/src/runtime/feature-pointer.js +174 -0
  282. package/src/runtime/feature-resolve.js +13 -2
  283. package/src/runtime/fleet/command.js +77 -0
  284. package/src/runtime/fleet/projects.js +178 -0
  285. package/src/runtime/fleet/tree.js +383 -0
  286. package/src/runtime/freshness.js +33 -3
  287. package/src/runtime/git-memo.js +46 -0
  288. package/src/runtime/guidance/ablation.js +427 -0
  289. package/src/runtime/health.js +565 -17
  290. package/src/runtime/history-compactor.js +13 -3
  291. package/src/runtime/implementation-gate.js +277 -22
  292. package/src/runtime/inventory/coverage.js +1 -1
  293. package/src/runtime/inventory/index.js +1 -1
  294. package/src/runtime/inventory/precedence.js +2 -2
  295. package/src/runtime/inventory/siblings.js +6 -4
  296. package/src/runtime/knowledge/code-corpus.js +277 -0
  297. package/src/runtime/knowledge/code-lexical.js +130 -0
  298. package/src/runtime/knowledge/code-retrieval.js +307 -0
  299. package/src/runtime/knowledge/code-validation.js +106 -0
  300. package/src/runtime/knowledge/gp3-gate.js +74 -0
  301. package/src/runtime/knowledge/graph-adapter.js +288 -0
  302. package/src/runtime/knowledge/graph-fallback.js +394 -0
  303. package/src/runtime/knowledge/hybrid.js +136 -8
  304. package/src/runtime/knowledge/retrieval.js +34 -1
  305. package/src/runtime/knowledge/rtk-compress.js +77 -0
  306. package/src/runtime/knowledge/semble-bridge.py +106 -0
  307. package/src/runtime/knowledge/semble-lifecycle.js +114 -0
  308. package/src/runtime/knowledge/semble-provider.js +365 -0
  309. package/src/runtime/lifecycle/cli.js +16 -6
  310. package/src/runtime/lifecycle/event-store.js +8 -6
  311. package/src/runtime/lifecycle/followup.js +6 -1
  312. package/src/runtime/lifecycle/overview.js +24 -1
  313. package/src/runtime/lifecycle/report-store.js +8 -10
  314. package/src/runtime/lifecycle/retention.js +95 -31
  315. package/src/runtime/lifecycle/root.js +9 -1
  316. package/src/runtime/lifecycle/status.js +34 -17
  317. package/src/runtime/lifecycle/store-upkeep.js +56 -7
  318. package/src/runtime/mask.js +134 -7
  319. package/src/runtime/mcp-consultations.js +40 -6
  320. package/src/runtime/model-router.js +79 -7
  321. package/src/runtime/models/catalogue.js +191 -0
  322. package/src/runtime/models/command.js +153 -0
  323. package/src/runtime/off-words.js +12 -0
  324. package/src/runtime/outcome.js +2 -2
  325. package/src/runtime/packages/command.js +1009 -0
  326. package/src/runtime/packages/contributions.js +116 -0
  327. package/src/runtime/packages/digest.js +132 -0
  328. package/src/runtime/packages/fetch.js +182 -0
  329. package/src/runtime/packages/grants.js +192 -0
  330. package/src/runtime/packages/index-file.js +134 -0
  331. package/src/runtime/packages/instruction.js +90 -0
  332. package/src/runtime/packages/manifest.js +331 -0
  333. package/src/runtime/packages/points.js +477 -0
  334. package/src/runtime/packages/programs.js +216 -0
  335. package/src/runtime/packages/scaffold.js +277 -0
  336. package/src/runtime/packages/source.js +90 -0
  337. package/src/runtime/packages/state.js +164 -0
  338. package/src/runtime/packages/store.js +449 -0
  339. package/src/runtime/packages/tar.js +106 -0
  340. package/src/runtime/packages/view.js +406 -0
  341. package/src/runtime/plan-check.js +59 -0
  342. package/src/runtime/plan-content.js +324 -0
  343. package/src/runtime/policy-init.js +118 -0
  344. package/src/runtime/profiles/doctor.js +96 -0
  345. package/src/runtime/profiles/resolve.js +244 -0
  346. package/src/runtime/profiles/rollback.js +254 -0
  347. package/src/runtime/profiles/sampler.js +41 -0
  348. package/src/runtime/readiness-record.js +16 -11
  349. package/src/runtime/readiness.js +46 -5
  350. package/src/runtime/research-request.js +50 -25
  351. package/src/runtime/retrieval-plan.js +10 -30
  352. package/src/runtime/retrieval-record.js +75 -5
  353. package/src/runtime/review/command.js +246 -0
  354. package/src/runtime/review/dominance.js +68 -0
  355. package/src/runtime/review/findings.js +434 -0
  356. package/src/runtime/review/identity.js +255 -0
  357. package/src/runtime/review/protocol-command.js +109 -0
  358. package/src/runtime/review/protocols.js +405 -0
  359. package/src/runtime/review/resolve-protocol.js +302 -0
  360. package/src/runtime/review/start.js +530 -0
  361. package/src/runtime/roadmap/facts.js +479 -0
  362. package/src/runtime/roadmap/gates.js +270 -0
  363. package/src/runtime/roadmap/loop.js +1636 -0
  364. package/src/runtime/roadmap/merge.js +381 -0
  365. package/src/runtime/roadmap/rows.js +1113 -0
  366. package/src/runtime/roadmap/seed.js +951 -0
  367. package/src/runtime/rules-report.js +336 -0
  368. package/src/runtime/scaffold/artifacts.js +60 -9
  369. package/src/runtime/scaffold/generate.js +21 -9
  370. package/src/runtime/settings/autopilot.js +106 -0
  371. package/src/runtime/settings/cli.js +280 -0
  372. package/src/runtime/settings/config-write.js +314 -0
  373. package/src/runtime/settings/files.js +271 -0
  374. package/src/runtime/settings/legacy.js +154 -0
  375. package/src/runtime/settings/lexical.js +56 -0
  376. package/src/runtime/settings/prepared-run.js +269 -0
  377. package/src/runtime/settings/project-layers.js +118 -0
  378. package/src/runtime/settings/refs.js +288 -0
  379. package/src/runtime/settings/registry.js +553 -0
  380. package/src/runtime/settings/resolve.js +713 -0
  381. package/src/runtime/settings/shared.js +37 -0
  382. package/src/runtime/settings/worker-billing.js +107 -0
  383. package/src/runtime/settings/write.js +269 -0
  384. package/src/runtime/slot-command.js +78 -0
  385. package/src/runtime/slots.js +671 -0
  386. package/src/runtime/source-version.js +1 -0
  387. package/src/runtime/state-root.js +217 -0
  388. package/src/runtime/storage/cli.js +12 -5
  389. package/src/runtime/storage/engine.js +9 -2
  390. package/src/runtime/storage/registry.js +14 -1
  391. package/src/runtime/storage/roots.js +66 -16
  392. package/src/runtime/storage/rules.js +82 -10
  393. package/src/runtime/storage/upkeep.js +10 -2
  394. package/src/runtime/storage/work-status.js +245 -26
  395. package/src/runtime/task-attempts.js +589 -69
  396. package/src/runtime/task-classifier.js +47 -11
  397. package/src/runtime/task-graph.js +373 -0
  398. package/src/runtime/task-run.js +778 -0
  399. package/src/runtime/task-scope.js +176 -55
  400. package/src/runtime/task-sources.js +147 -0
  401. package/src/runtime/task-state.js +374 -64
  402. package/src/runtime/team/admission.js +301 -0
  403. package/src/runtime/team/envelope.js +324 -0
  404. package/src/runtime/team/review-guard.js +156 -0
  405. package/src/runtime/trace/analyze.js +427 -0
  406. package/src/runtime/trace/baseline.js +770 -0
  407. package/src/runtime/trace/ledger.js +63 -140
  408. package/src/runtime/trace/otlp-export.js +568 -0
  409. package/src/runtime/trace/otlp-map.js +481 -0
  410. package/src/runtime/trace/spans.js +745 -0
  411. package/src/runtime/trace/telemetry.js +225 -0
  412. package/src/runtime/trace/views.js +1 -0
  413. package/src/runtime/transcripts/command.js +98 -0
  414. package/src/runtime/transcripts/cursor.js +326 -0
  415. package/src/runtime/transcripts/read.js +126 -0
  416. package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
  417. package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
  418. package/src/runtime/transcripts/readers/copilot-events.js +90 -0
  419. package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
  420. package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
  421. package/src/runtime/transcripts/registry.js +161 -0
  422. package/src/runtime/transcripts/stats.js +161 -0
  423. package/src/runtime/verification/check-key.js +628 -0
  424. package/src/runtime/verification/contract-runner.js +546 -11
  425. package/src/runtime/verification/engine.js +499 -9
  426. package/src/runtime/verification/impact.js +617 -0
  427. package/src/runtime/verification/inflight.js +205 -0
  428. package/src/runtime/verification/registry.js +176 -0
  429. package/src/runtime/verification/reuse.js +184 -0
  430. package/src/runtime/verification/telemetry-emit.js +254 -0
  431. package/src/runtime/verification/test-selection.js +67 -7
  432. package/src/runtime/worker/active.js +90 -0
  433. package/src/runtime/worker/cancel.js +222 -0
  434. package/src/runtime/worker/catalogue.js +122 -0
  435. package/src/runtime/worker/command.js +677 -0
  436. package/src/runtime/worker/evidence.js +288 -0
  437. package/src/runtime/worker/launch.js +288 -0
  438. package/src/runtime/worker/models.js +137 -0
  439. package/src/runtime/worker/parsers.js +218 -0
  440. package/src/runtime/worker/probes/index.js +706 -0
  441. package/src/runtime/worker/process-tree.js +415 -0
  442. package/src/runtime/worker/quota.js +43 -0
  443. package/src/runtime/worker/readiness.js +713 -0
  444. package/src/runtime/worker/run-store.js +166 -0
  445. package/src/runtime/worker/supervisor.js +541 -0
  446. package/src/runtime/worker/worktree-check.js +252 -0
  447. package/src/runtime/workflow-engine.js +5 -1
  448. package/src/runtime/workflow-orchestrator.js +578 -63
  449. package/src/runtime/worktree.js +149 -22
  450. package/src/state/index.js +1 -1
  451. package/src/state/lockfile.js +64 -10
  452. package/src/state/run-lock.js +1 -1
  453. package/types/node-commonjs.d.ts +106 -7
  454. package/core/harnesses/gemini/hooks/hooks.json +0 -77
  455. package/core/harnesses/gemini/hooks/lib.sh +0 -302
  456. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -10
  457. package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
  458. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -10
  459. package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
  460. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -10
  461. package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
  462. package/core/harnesses/gemini/hooks/session-end.sh +0 -5
  463. package/core/harnesses/gemini/hooks/session-start.sh +0 -7
  464. package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
  465. package/core/shared/guidance/FLAGS.md +0 -25
  466. package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
  467. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
  468. package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
  469. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
  470. package/src/adapters/gemini/hooks.js +0 -251
  471. package/src/adapters/gemini/index.js +0 -429
@@ -9,12 +9,14 @@ const { CapabilityRouter } = require('./capability-router.js');
9
9
  const { EvidenceLedger } = require('./evidence-ledger.js');
10
10
  const { ClaimsManager } = require('./claims.js');
11
11
  const { measureTreeState } = require('./source-version.js');
12
- const { toEvidence, validateEvidenceItem, EVIDENCE_REFUSED_FIELDS } = require('./candidate.js');
12
+ const { fileRootFor } = require('./freshness.js');
13
+ const { toEvidence, parseLocator, validateEvidenceItem, EVIDENCE_REFUSED_FIELDS } = require('./candidate.js');
13
14
  const { sourceModeLookup } = require('./retrieval-plan.js');
14
15
  const { evaluateTaskReadiness } = require('./readiness.js');
15
- const { writeReadinessRecord } = require('./readiness-record.js');
16
+ const { writeReadinessRecord, readReadinessRecord } = require('./readiness-record.js');
17
+ const { resolveTaskScope } = require('./task-scope.js');
16
18
  const { parseDeclaredScope } = require('./verification/scope-bound.js');
17
- const { loadRegistry } = require('../registry/index.js');
19
+ const { loadRegistry, agentToolScopeView } = require('../registry/index.js');
18
20
  const { REPO_ROOT } = require('../helper/repo-root.js');
19
21
  // One definition of the exit and usage helpers (design §4.2); `finish` is the local spelling of `finishRuntime`.
20
22
  const { finishRuntime: finish, usageError } = require('./cli-result.js');
@@ -30,9 +32,10 @@ function handleCapabilitiesCommand({ json = false, check = false, repoRoot }
30
32
  const root = repoRoot || REPO_ROOT;
31
33
  const router = new CapabilityRouter({ repoRoot: root });
32
34
  const report = router.getAllCapabilitiesHealth(check);
35
+ const agentToolScope = agentToolScopeView(loadRegistry({ repoRoot: root, sources: 'skip' }));
33
36
 
34
37
  if (json) {
35
- console.log(JSON.stringify({ capabilities: report }, null, 2));
38
+ console.log(JSON.stringify({ capabilities: report, agentToolScope }, null, 2));
36
39
  return;
37
40
  }
38
41
 
@@ -60,7 +63,36 @@ function handleCapabilitiesCommand({ json = false, check = false, repoRoot }
60
63
  );
61
64
  }
62
65
  console.log('═'.repeat(78));
63
- console.log(`Mode: ${check ? 'Deep Smoke Check' : 'Fast Presence Check'} · Total Capabilities: ${report.length}\n`);
66
+ console.log(`Mode: ${check ? 'Deep Smoke Check' : 'Fast Presence Check'} · Total Capabilities: ${report.length}`);
67
+ console.log('\nAgent tool scope per harness (unenforced: no tool field is projected):');
68
+ for (const row of agentToolScope) console.log(` ${row.harness.padEnd(14)}${row.status === 'native' ? `native ${row.field}` : `unenforced ${row.reason}`}`);
69
+ console.log('');
70
+ }
71
+
72
+ /**
73
+ * Fills `profile` with the caller-stated inputs the task's last readiness record for this template
74
+ * holds and this call did not pass. Returns the profile keys it filled.
75
+ * @returns {Array<string>}
76
+ */
77
+ function carriedInputs({ profile, taskClass, taskId, slug, state } ) {
78
+ const keyOf = { verificationPlan: 'verificationPlan', scope: 'scopeClear', invariants: 'invariants' };
79
+ let prior = null;
80
+ try {
81
+ const scope = resolveTaskScope({ projectRoot: state, taskId, slug });
82
+ const read = readReadinessRecord({ stateRoot: state, taskId, slug: scope.slug || slug || null });
83
+ if (read.status === 'found' && read.record && read.record.taskClass === taskClass) prior = read.record;
84
+ } catch {
85
+ return [];
86
+ }
87
+ const filled = [];
88
+ for (const [inputKey, profileKey] of Object.entries(keyOf)) {
89
+ const value = prior && prior.inputs && prior.inputs[inputKey];
90
+ if (profile[profileKey ] === undefined && typeof value === 'string' && value.trim() !== '') {
91
+ profile[profileKey ] = value;
92
+ filled.push(profileKey );
93
+ }
94
+ }
95
+ return filled;
64
96
  }
65
97
 
66
98
  /**
@@ -107,11 +139,16 @@ function handleReadinessCommand({
107
139
  if (typeof scopeClear === 'string' && scopeClear.trim() !== '') profile.scopeClear = scopeClear;
108
140
  if (typeof invariants === 'string' && invariants.trim() !== '') profile.invariants = invariants;
109
141
  if (userDecisionPending) profile.userDecisionPending = true;
142
+ // An input not passed this call is the one the task's last evaluation for this template stated, so
143
+ // a bare re-check after evidence changes does not discard the scope and plan a READY verdict rested
144
+ // on. Passing an input replaces it. Ceiling: an input can be replaced but not dropped, and
145
+ // `--user-decision-pending` is never carried.
146
+ const carried = carriedInputs({ profile, taskClass, taskId, slug, state });
110
147
  const callerAsserted = Object.keys(profile).filter((k) => k !== 'taskId' && k !== 'taskClass');
111
148
 
112
149
  let report;
113
150
  try {
114
- report = evaluateTaskReadiness({ taskProfile: profile, repoRoot: root, projectRoot: state, treeRoot: sourceRoot || state, mode });
151
+ report = evaluateTaskReadiness({ taskProfile: profile, repoRoot: root, projectRoot: state, treeRoot: sourceRoot || state, sourceRoot: sourceRoot || state, mode });
115
152
  } catch (error ) {
116
153
  return usageError('readiness', error.message, json, error);
117
154
  }
@@ -139,7 +176,7 @@ function handleReadinessCommand({
139
176
  };
140
177
 
141
178
  if (json) {
142
- console.log(JSON.stringify({ ...report, callerAsserted, record: recorded, declaredScope }, null, 2));
179
+ console.log(JSON.stringify({ ...report, callerAsserted, carriedFromLastRecord: carried, record: recorded, declaredScope }, null, 2));
143
180
  reportNotRecorded();
144
181
  return finish(exitCode);
145
182
  }
@@ -164,6 +201,7 @@ function handleReadinessCommand({
164
201
  // Named, not hidden: these requirements were satisfied because the caller said so, and a
165
202
  // verdict that mixes measured and stated inputs must say which is which.
166
203
  console.log(`Caller-stated: ${callerAsserted.join(', ')} (asserted on the command line, not established by evidence)`);
204
+ if (carried.length > 0) console.log(`Carried: ${carried.join(', ')} (stated by the last evaluation of this task; pass the flag to replace it)`);
167
205
  }
168
206
  console.log('─'.repeat(70));
169
207
  console.log('Requirements Breakdown:');
@@ -241,6 +279,30 @@ function readEvidenceBatch(batchPath , taskId , root , slug = n
241
279
  throw new Error('a batch must be a JSON array of evidence items, or an object with an `evidence` array');
242
280
  }
243
281
 
282
+ /**
283
+ * Refuses an evidence item whose file locator names a directory, whatever its provenance: a locator
284
+ * points into a file. An absence item has no locator, and a locator that does not parse is left to
285
+ * `toEvidence`, which names what is wrong with it.
286
+ * @throws {Error} naming the locator
287
+ */
288
+ function refuseDirectoryLocator(raw , sourceRoot , root ) {
289
+ if (!raw || typeof raw !== 'object' || raw.absence || raw.locator === undefined) return;
290
+ let locator;
291
+ try {
292
+ locator = parseLocator(raw.locator);
293
+ } catch {
294
+ return;
295
+ }
296
+ if (!locator.file) return;
297
+ let isDirectory = false;
298
+ try {
299
+ isDirectory = fs.statSync(path.resolve(fileRootFor(sourceRoot, root, locator), locator.file)).isDirectory();
300
+ } catch { /* missing or unreadable: the resolver judges that */ }
301
+ if (isDirectory) {
302
+ throw new Error(`the locator '${locator.file}' is a directory, and a directory is not a valid locator; name a file (path[:line])`);
303
+ }
304
+ }
305
+
244
306
  /**
245
307
  * The `--action add` arm: validate the whole batch, then write it.
246
308
  * @returns {number} exit code
@@ -268,10 +330,8 @@ function addEvidence({ ledger, root, sourceRoot = root, attemptRoot, taskId, ite
268
330
 
269
331
  // The whole batch is validated before any of it is written. A half-written stage batch is worse
270
332
  // than a rejected one: the half that landed looks complete to every later reader.
271
- const treeState = measureTreeState(root);
272
- const hasAbsence = raws.some((raw ) => raw?.absence === true);
273
- const absenceTreeState = hasAbsence && path.resolve(sourceRoot) !== path.resolve(root)
274
- ? measureTreeState(sourceRoot) : null;
333
+ // The tree observed is the checkout the verb runs in (115 IC-007), one measurement for every item.
334
+ const treeState = measureTreeState(sourceRoot);
275
335
  const providerFreshness = new Map();
276
336
  let sourceModeOf = null;
277
337
  const validated = [];
@@ -280,7 +340,8 @@ function addEvidence({ ledger, root, sourceRoot = root, attemptRoot, taskId, ite
280
340
  if (raw && raw.absence && !sourceModeOf) {
281
341
  sourceModeOf = sourceModeLookup(new CapabilityRouter({ repoRoot: REPO_ROOT }).capabilities);
282
342
  }
283
- validated.push(toEvidence({ item: raw }, { taskId, root, treeState, absenceTreeState, probeRoot: sourceRoot, attemptRoot, slug, providerFreshness, sourceModeOf }));
343
+ refuseDirectoryLocator(raw, sourceRoot, root);
344
+ validated.push(toEvidence({ item: raw }, { taskId, root, treeState, probeRoot: sourceRoot, sourceRoot, attemptRoot, slug, providerFreshness, sourceModeOf }));
284
345
  } catch (error ) {
285
346
  const where = raws.length > 1 ? `batch item ${index + 1} of ${raws.length}: ` : '';
286
347
  return usageError('evidence', `${where}${error.message}`, json, error);
@@ -318,8 +379,7 @@ function addEvidence({ ledger, root, sourceRoot = root, attemptRoot, taskId, ite
318
379
  }
319
380
  console.log('─'.repeat(78));
320
381
  console.log(`Wrote ${written.length} item(s) to ${stateFile}`);
321
- const observedTree = absenceTreeState || treeState;
322
- console.log(`Commit at observation: ${observedTree.gitCommit || (observedTree.prefix !== null ? 'not measured' : 'not a git worktree — freshness cannot expire by diff')}`);
382
+ console.log(`Commit at observation: ${treeState.gitCommit || (treeState.prefix !== null ? 'not measured' : 'not a git worktree — freshness cannot expire by diff')}`);
323
383
  console.log('═'.repeat(78) + '\n');
324
384
  return finish(0);
325
385
  }
@@ -361,28 +421,69 @@ function supersedeEvidence({ ledger, taskId, evidenceId, replacedBy, json }
361
421
  return finish(0);
362
422
  }
363
423
 
424
+ /**
425
+ * The `--action retire --stale` arm: retire every active item the ledger classes stale right now,
426
+ * judged the way readiness judges them (the tree the verb runs in). Items are retired without a
427
+ * replacement and the reason is recorded on each; fresh items are not touched.
428
+ * @returns {number} exit code
429
+ */
430
+ function retireStaleEvidence({ ledger, root, sourceRoot, taskId, slug, stale, json } ) {
431
+ if (!stale) {
432
+ return usageError('evidence', '--action retire retires every stale item and needs --stale; '
433
+ + 'to retire one item, point it at its replacement with --action supersede', json);
434
+ }
435
+ // Staleness is derived, never stored by a read: classify on a separate copy so the ledger being
436
+ // saved changes only the items retired here.
437
+ const { FreshnessValidator } = require('./freshness.js');
438
+ const probe = new EvidenceLedger({ repoRoot: root, slug });
439
+ let retired ;
440
+ try {
441
+ probe.load(taskId);
442
+ new FreshnessValidator({ repoRoot: root, treeRoot: sourceRoot, sourceRoot }).validateLedgerFreshness(probe);
443
+ const staleItems = probe.getAllEvidence().filter((item ) => item.taskId === taskId
444
+ && item.freshness?.status === 'STALE' && item.status !== 'superseded');
445
+ for (const item of staleItems) {
446
+ ledger.retireEvidence(item.id, `stale: ${item.freshness.staleReason || 'marked stale'}`);
447
+ }
448
+ retired = staleItems.map((item ) => ledger.getEvidence(item.id));
449
+ if (retired.length > 0) ledger.save(taskId);
450
+ } catch (error ) {
451
+ return usageError('evidence', error.message, json, error);
452
+ }
453
+ const ids = retired.map((item ) => item.id);
454
+ if (json) {
455
+ console.log(JSON.stringify({ action: 'retire', taskId, retired: ids.length, ids, evidence: retired }, null, 2));
456
+ return finish(0);
457
+ }
458
+ console.log(ids.length === 0
459
+ ? `Evidence [Task: ${taskId}]: no stale items to retire.`
460
+ : `Evidence [Task: ${taskId}]: retired ${ids.length} stale item(s):\n${retired.map((item ) => ` ${item.id} ${item.retiredReason}`).join('\n')}`);
461
+ return finish(0);
462
+ }
463
+
364
464
  /**
365
465
  * Handles `doflow evidence` — record a stage's evidence batch, retire a stale item, or query
366
466
  * what is recorded.
367
467
  *
368
468
  * @param {Object} options
369
469
  * @param {string} [options.taskId='default']
370
- * @param {'list'|'status'|'add'|'supersede'} [options.action='list']
470
+ * @param {'list'|'status'|'add'|'supersede'|'retire'} [options.action='list']
371
471
  * @param {Object} [options.item] single-item write, assembled from flags by bin/doflow.js
372
472
  * @param {string} [options.batchPath] `add`: a JSON batch file, or `-` for stdin
373
473
  * @param {string} [options.evidenceId] `supersede`: the item to retire
374
474
  * @param {string} [options.replacedBy] `supersede`: the item that replaces it
475
+ * @param {boolean} [options.stale] `retire`: retire every item the ledger classes stale
375
476
  * @param {boolean} [options.json=false]
376
477
  * @param {string} [options.repoRoot]
377
478
  * @param {string} [options.stateRoot]
378
479
  * @returns {number} exit code
379
480
  */
380
- function handleEvidenceCommand({ taskId = 'default', action = 'list', item = null, batchPath = null, evidenceId = null, replacedBy = null, json = false, repoRoot, stateRoot, sourceRoot, attemptRoot, slug = null } = {}) {
481
+ function handleEvidenceCommand({ taskId = 'default', action = 'list', item = null, batchPath = null, evidenceId = null, replacedBy = null, stale = false, json = false, repoRoot, stateRoot, sourceRoot, attemptRoot, slug = null } = {}) {
381
482
  // See handleReadinessCommand: evidence is the caller's project state, not DoFlow package state.
382
483
  const root = stateRoot || repoRoot || process.cwd();
383
484
  const isQuery = action === 'list' || action === 'status';
384
- if (!isQuery && action !== 'add' && action !== 'supersede') {
385
- return usageError('evidence', `unknown --action '${action}'. Valid: list, add, supersede`, json);
485
+ if (!isQuery && action !== 'add' && action !== 'supersede' && action !== 'retire') {
486
+ return usageError('evidence', `unknown --action '${action}'. Valid: list, add, supersede, retire`, json);
386
487
  }
387
488
  // A write argument on a read action is the defect this verb was reported for: it used to accept
388
489
  // append-shaped flags, ignore them, and print the (unchanged) ledger as if the write had landed.
@@ -390,7 +491,7 @@ function handleEvidenceCommand({ taskId = 'default', action = 'list', item = nul
390
491
  return usageError('evidence', 'these are write arguments and this action only reads — re-run with --action add', json);
391
492
  }
392
493
 
393
- const ledger = new EvidenceLedger({ repoRoot: root });
494
+ const ledger = new EvidenceLedger({ repoRoot: root, slug });
394
495
  try {
395
496
  ledger.load(taskId);
396
497
  } catch (error ) {
@@ -399,6 +500,7 @@ function handleEvidenceCommand({ taskId = 'default', action = 'list', item = nul
399
500
 
400
501
  if (action === 'add') return addEvidence({ ledger, root, sourceRoot: sourceRoot || root, attemptRoot, taskId, item, batchPath, json, slug });
401
502
  if (action === 'supersede') return supersedeEvidence({ ledger, taskId, evidenceId, replacedBy, json });
503
+ if (action === 'retire') return retireStaleEvidence({ ledger, root, sourceRoot: sourceRoot || root, taskId, slug, stale, json });
402
504
 
403
505
  const items = ledger.queryEvidence({ taskId });
404
506
 
@@ -428,10 +530,85 @@ function handleEvidenceCommand({ taskId = 'default', action = 'list', item = nul
428
530
  return finish(0);
429
531
  }
430
532
 
533
+ const EMIT_NUDGES = ['nudge', 'suppress', 'none'];
534
+ const EMIT_MAX_BYTES = /^[1-9][0-9]{0,9}$/;
535
+
536
+ /**
537
+ * 078 IC-005: `doflow-run context-emit`, a thin wrapper over emitContext(). Identity is read from
538
+ * the environment alone (IC-007); no flag sets it. Exits 0 emitted or silent, 2 usage (including a
539
+ * launch without a launched identity, or an invalid identity value), 3 refused.
540
+ */
541
+ function handleContextEmitCommand({ event, cwd, session, harness, nudge, maxBytes, taskId, slug, stateRoot, peek = false, json = false, env = process.env } = {}) {
542
+ // Required on use: context-pack.ts loads the whole pack compiler, which no other verb here needs.
543
+ const { emitContext } = require('./context-pack.js');
544
+ const { resolveIdentity } = require('./context/identity.js');
545
+ if (typeof cwd !== 'string' || cwd === '') return usageError('context-emit', '--cwd <dir> is required', json);
546
+ const dir = path.resolve(cwd);
547
+ if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) return usageError('context-emit', `--cwd '${cwd}' is not a directory`, json);
548
+ if (nudge !== undefined && !EMIT_NUDGES.includes(nudge)) return usageError('context-emit', `--nudge must be one of ${EMIT_NUDGES.join(', ')}`, json);
549
+ if (maxBytes !== undefined && !EMIT_MAX_BYTES.test(String(maxBytes))) return usageError('context-emit', '--max-bytes must be a positive integer', json);
550
+ const sessionId = typeof session === 'string' ? session : '';
551
+ const identity = resolveIdentity(env, { cwd: dir, sessionId });
552
+ if (identity.diagnostics.includes('identity-invalid')) {
553
+ return usageError('context-emit', 'DOFLOW_RUN_ID or DOFLOW_LINEAGE_ID holds an invalid value', json);
554
+ }
555
+ let result ;
556
+ try {
557
+ result = emitContext({
558
+ event, identity, cwd: dir, sessionId, env, peek: peek === true,
559
+ ...(harness ? { harness } : {}),
560
+ ...(nudge ? { nudge } : {}),
561
+ ...(maxBytes !== undefined ? { maxBytes: Number(maxBytes) } : {}),
562
+ ...(taskId ? { taskId } : {}),
563
+ ...(slug ? { slug } : {}),
564
+ ...(stateRoot ? { stateRoot } : {}),
565
+ });
566
+ } catch (error ) {
567
+ if (error?.code === 'USAGE_ERROR') return usageError('context-emit', error.message.replace(/^emitContext: /, ''), json);
568
+ throw error;
569
+ }
570
+ if (json) {
571
+ console.log(JSON.stringify({ v: 1, event, identity, decision: result.decision, text: result.text, pack: result.pack, committed: result.committed }));
572
+ } else if (result.text !== null) {
573
+ process.stdout.write(result.text.endsWith('\n') ? result.text : `${result.text}\n`);
574
+ }
575
+ return finish(result.decision.reason === 'refused:mandatory-over-budget' ? 3 : 0);
576
+ }
577
+
578
+ /**
579
+ * 078 IC-013: `doflow-run context-grant`, a thin wrapper over grantSummary(). The source scope
580
+ * defaults to the caller's identity. Exits 0 created, 1 not found or already granted, 2 usage,
581
+ * 3 over budget (refused before any write).
582
+ */
583
+ function handleContextGrantCommand({ summary, toRun, toLineage, fromWorktree, fromRun, fromLineage, maxBytes, json = false, env = process.env } = {}) {
584
+ const { grantSummary } = require('./context/summary-store.js');
585
+ let granted ;
586
+ try {
587
+ granted = grantSummary({
588
+ summary, toRun, toLineage, env,
589
+ ...(fromWorktree ? { fromWorktree: path.resolve(fromWorktree) } : {}),
590
+ ...(fromRun ? { fromRun } : {}),
591
+ ...(fromLineage ? { fromLineage } : {}),
592
+ ...(maxBytes !== undefined ? { maxBytes } : {}),
593
+ });
594
+ } catch (error ) {
595
+ if (error?.name !== 'SummaryStoreError') throw error;
596
+ if (error.exitCode === 2) return usageError('context-grant', error.message, json);
597
+ if (json) console.log(JSON.stringify({ v: 1, ok: false, error: error.code, summary: error.message }));
598
+ else console.error(`doflow context-grant: ${error.message}`);
599
+ return finish(error.exitCode);
600
+ }
601
+ if (json) console.log(JSON.stringify({ v: 1, ok: true, ...granted }));
602
+ else console.log(`granted ${granted.summaryId} (${granted.bytes} B) -> ${granted.path}`);
603
+ return finish(0);
604
+ }
605
+
431
606
  module.exports = {
432
607
  handleCapabilitiesCommand,
433
608
  handleReadinessCommand,
434
609
  handleEvidenceCommand,
610
+ handleContextEmitCommand,
611
+ handleContextGrantCommand,
435
612
  // Exported for bin/doflow.js, which refuses the same names as command-line flags, and for the
436
613
  // tests that pin the write boundary.
437
614
  EVIDENCE_SCORE_FIELDS,
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
4
+
5
+ /**
6
+ * The per-machine config home (086 IC-003, DD-7): the one place Node code asks where `<home>/doflow`
7
+ * lives. `XDG_CONFIG_HOME` when it is set, non-empty and absolute, else `$HOME/.config` when `HOME` is
8
+ * set, non-empty and absolute, else no config home. A relative or empty value is ignored, never read
9
+ * against the working directory. It reads the `HOME` variable and never `os.homedir()`, so Node and
10
+ * the shell blocks (`doflow_config_home` in `doflow-run`, `policies/lib.sh`, ...) agree on every
11
+ * environment, and an unset HOME is "no home" rather than the account's home.
12
+ */
13
+
14
+ const path = require('node:path');
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+ function configHome(env = process.env) {
28
+ const ignored = [];
29
+ const usable = (name ) => {
30
+ const value = env[name];
31
+ if (typeof value !== 'string' || value === '') return null;
32
+ if (path.isAbsolute(value)) return value;
33
+ ignored.push(name);
34
+ return null;
35
+ };
36
+ const xdg = usable('XDG_CONFIG_HOME');
37
+ const home = usable('HOME');
38
+ const base = xdg !== null ? xdg : home !== null ? path.join(home, '.config') : null;
39
+ return { base, dir: base === null ? null : path.join(base, 'doflow'), ignored };
40
+ }
41
+
42
+ module.exports = { configHome };