@monoes/monomindcli 2.9.6 → 2.9.8

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 (295) hide show
  1. package/.claude/agents/design/design-monodesign.md +1 -2
  2. package/.claude/agents/engineering/engineering-ai-data-remediation-engineer.md +1 -2
  3. package/.claude/agents/engineering/engineering-ai-engineer.md +1 -2
  4. package/.claude/agents/engineering/engineering-autonomous-optimization-architect.md +0 -1
  5. package/.claude/agents/engineering/engineering-backend-architect.md +1 -2
  6. package/.claude/agents/engineering/engineering-code-reviewer.md +1 -2
  7. package/.claude/agents/engineering/engineering-data-engineer.md +1 -2
  8. package/.claude/agents/engineering/engineering-database-optimizer.md +1 -2
  9. package/.claude/agents/engineering/engineering-devops-automator.md +1 -2
  10. package/.claude/agents/engineering/engineering-embedded-firmware-engineer.md +1 -2
  11. package/.claude/agents/engineering/engineering-feishu-integration-developer.md +1 -2
  12. package/.claude/agents/engineering/engineering-frontend-developer.md +1 -2
  13. package/.claude/agents/engineering/engineering-git-workflow-master.md +1 -2
  14. package/.claude/agents/engineering/engineering-incident-response-commander.md +0 -1
  15. package/.claude/agents/engineering/engineering-mobile-app-builder.md +1 -2
  16. package/.claude/agents/engineering/engineering-rapid-prototyper.md +1 -2
  17. package/.claude/agents/engineering/engineering-security-engineer.md +1 -2
  18. package/.claude/agents/engineering/engineering-senior-developer.md +1 -2
  19. package/.claude/agents/engineering/engineering-software-architect.md +1 -2
  20. package/.claude/agents/engineering/engineering-solidity-smart-contract-engineer.md +1 -2
  21. package/.claude/agents/engineering/engineering-sre.md +0 -1
  22. package/.claude/agents/engineering/engineering-technical-writer.md +1 -2
  23. package/.claude/agents/engineering/engineering-threat-detection-engineer.md +0 -1
  24. package/.claude/agents/engineering/engineering-wechat-mini-program-developer.md +1 -2
  25. package/.claude/agents/github/code-review-swarm.md +0 -1
  26. package/.claude/agents/github/github-modes.md +0 -1
  27. package/.claude/agents/github/issue-tracker.md +0 -1
  28. package/.claude/agents/github/multi-repo-swarm.md +0 -1
  29. package/.claude/agents/github/pr-manager.md +0 -1
  30. package/.claude/agents/github/project-board-sync.md +0 -1
  31. package/.claude/agents/github/release-manager.md +0 -1
  32. package/.claude/agents/github/repo-architect.md +0 -1
  33. package/.claude/agents/github/swarm-issue.md +0 -1
  34. package/.claude/agents/github/swarm-pr.md +0 -1
  35. package/.claude/agents/github/sync-coordinator.md +0 -1
  36. package/.claude/agents/github/workflow-automation.md +0 -1
  37. package/.claude/agents/marketing/marketing-competitive-content.md +1 -2
  38. package/.claude/agents/marketing/marketing-cro-specialist.md +1 -2
  39. package/.claude/agents/marketing/marketing-email-specialist.md +1 -2
  40. package/.claude/agents/marketing/marketing-launch-strategist.md +1 -2
  41. package/.claude/agents/marketing/marketing-pricing-strategist.md +1 -2
  42. package/.claude/agents/specialized/agentic-identity-trust.md +0 -1
  43. package/.claude/agents/specialized/agents-orchestrator.md +1 -2
  44. package/.claude/agents/specialized/automation-governance-architect.md +1 -2
  45. package/.claude/agents/specialized/blockchain-security-auditor.md +1 -2
  46. package/.claude/agents/specialized/compliance-auditor.md +1 -2
  47. package/.claude/agents/specialized/identity-graph-operator.md +0 -1
  48. package/.claude/agents/specialized/lsp-index-engineer.md +1 -2
  49. package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +0 -1
  50. package/.claude/agents/specialized/specialized-cultural-intelligence-strategist.md +0 -1
  51. package/.claude/agents/specialized/specialized-developer-advocate.md +1 -2
  52. package/.claude/agents/specialized/specialized-document-generator.md +1 -2
  53. package/.claude/agents/specialized/specialized-mcp-builder.md +1 -2
  54. package/.claude/agents/specialized/specialized-model-qa.md +0 -1
  55. package/.claude/agents/specialized/specialized-workflow-architect.md +1 -2
  56. package/.claude/agents/specialized/zk-steward.md +1 -2
  57. package/.claude/agents/testing/production-validator.md +0 -1
  58. package/.claude/agents/testing/tdd-london-swarm.md +0 -1
  59. package/.claude/agents/testing/testing-accessibility-auditor.md +0 -1
  60. package/.claude/agents/testing/testing-api-tester.md +1 -2
  61. package/.claude/agents/testing/testing-evidence-collector.md +1 -2
  62. package/.claude/agents/testing/testing-performance-benchmarker.md +1 -2
  63. package/.claude/agents/testing/testing-test-results-analyzer.md +1 -2
  64. package/.claude/agents/testing/testing-tool-evaluator.md +1 -2
  65. package/.claude/agents/testing/testing-workflow-optimizer.md +1 -2
  66. package/.claude/commands/hooks/README.md +1 -1
  67. package/.claude/commands/memory/README.md +6 -7
  68. package/.claude/commands/monitoring/README.md +1 -1
  69. package/.claude/helpers/control-start.cjs +27 -7
  70. package/.claude/helpers/handlers/route-handler.cjs +22 -3
  71. package/.claude/helpers/handlers/session-handler.cjs +43 -0
  72. package/.claude/helpers/intelligence.cjs +27 -6
  73. package/.claude/helpers/statusline.cjs +45 -11
  74. package/.claude/skills/agentic-jujutsu/SKILL.md +17 -15
  75. package/.claude/skills/hive-mind-advanced/SKILL.md +212 -559
  76. package/.claude/skills/hooks-automation/SKILL.md +1 -1
  77. package/.claude/skills/mastermind-adapters/SKILL.md +0 -11
  78. package/.claude/skills/mastermind-agents/SKILL.md +0 -11
  79. package/.claude/skills/mastermind-backup/SKILL.md +0 -11
  80. package/.claude/skills/mastermind-bootstrap/SKILL.md +0 -11
  81. package/.claude/skills/mastermind-delegation/SKILL.md +14 -12
  82. package/.claude/skills/mastermind-idea/SKILL.md +0 -5
  83. package/.claude/skills/mastermind-monitor/SKILL.md +0 -15
  84. package/.claude/skills/mastermind-org-settings/SKILL.md +0 -11
  85. package/.claude/skills/mastermind-plugins/SKILL.md +0 -11
  86. package/.claude/skills/mastermind-protocol/SKILL.md +6 -124
  87. package/.claude/skills/mastermind-repeat/SKILL.md +0 -25
  88. package/.claude/skills/mastermind-review/SKILL.md +1 -1
  89. package/.claude/skills/mastermind-stoporg/SKILL.md +0 -19
  90. package/.claude/skills/memory-toolkit/SKILL.md +12 -11
  91. package/.claude/skills/monodesign/scripts/detector/engines/browser/drivers.mjs +8 -1
  92. package/.claude/skills/pair-programming/SKILL.md +1 -1
  93. package/.claude/skills/performance-analysis/SKILL.md +228 -484
  94. package/.claude/skills/specialagent/SKILL.md +31 -133
  95. package/.claude/skills/swarm-advanced/SKILL.md +2 -2
  96. package/.claude/skills/swarm-orchestration/SKILL.md +220 -150
  97. package/.claude/skills/verification-quality/SKILL.md +247 -571
  98. package/README.md +3 -3
  99. package/dist/src/commands/agent-lifecycle.js +3 -3
  100. package/dist/src/commands/agent-lifecycle.js.map +1 -1
  101. package/dist/src/commands/autopilot.d.ts.map +1 -1
  102. package/dist/src/commands/autopilot.js +7 -1
  103. package/dist/src/commands/autopilot.js.map +1 -1
  104. package/dist/src/commands/doc.d.ts.map +1 -1
  105. package/dist/src/commands/doc.js +14 -3
  106. package/dist/src/commands/doc.js.map +1 -1
  107. package/dist/src/commands/doctor-env-checks.d.ts +1 -1
  108. package/dist/src/commands/doctor-env-checks.d.ts.map +1 -1
  109. package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
  110. package/dist/src/commands/doctor-project-checks.js +3 -37
  111. package/dist/src/commands/doctor-project-checks.js.map +1 -1
  112. package/dist/src/commands/doctor.d.ts.map +1 -1
  113. package/dist/src/commands/doctor.js +30 -1
  114. package/dist/src/commands/doctor.js.map +1 -1
  115. package/dist/src/commands/hooks-coverage-commands.d.ts.map +1 -1
  116. package/dist/src/commands/hooks-coverage-commands.js +75 -67
  117. package/dist/src/commands/hooks-coverage-commands.js.map +1 -1
  118. package/dist/src/commands/hooks-workers.d.ts.map +1 -1
  119. package/dist/src/commands/hooks-workers.js +41 -10
  120. package/dist/src/commands/hooks-workers.js.map +1 -1
  121. package/dist/src/commands/hooks.js +1 -1
  122. package/dist/src/commands/index.d.ts +1 -1
  123. package/dist/src/commands/index.d.ts.map +1 -1
  124. package/dist/src/commands/index.js +20 -4
  125. package/dist/src/commands/index.js.map +1 -1
  126. package/dist/src/commands/init.d.ts.map +1 -1
  127. package/dist/src/commands/init.js +80 -7
  128. package/dist/src/commands/init.js.map +1 -1
  129. package/dist/src/commands/mcp.d.ts.map +1 -1
  130. package/dist/src/commands/mcp.js +78 -2
  131. package/dist/src/commands/mcp.js.map +1 -1
  132. package/dist/src/commands/neural-optimize.d.ts.map +1 -1
  133. package/dist/src/commands/neural-optimize.js +27 -5
  134. package/dist/src/commands/neural-optimize.js.map +1 -1
  135. package/dist/src/commands/org-observe.d.ts.map +1 -1
  136. package/dist/src/commands/org-observe.js +1 -0
  137. package/dist/src/commands/org-observe.js.map +1 -1
  138. package/dist/src/commands/org.d.ts.map +1 -1
  139. package/dist/src/commands/org.js +129 -2
  140. package/dist/src/commands/org.js.map +1 -1
  141. package/dist/src/commands/performance.js +1 -1
  142. package/dist/src/commands/performance.js.map +1 -1
  143. package/dist/src/commands/security-cve.d.ts.map +1 -1
  144. package/dist/src/commands/security-cve.js +1 -11
  145. package/dist/src/commands/security-cve.js.map +1 -1
  146. package/dist/src/commands/security-misc.d.ts +0 -9
  147. package/dist/src/commands/security-misc.d.ts.map +1 -1
  148. package/dist/src/commands/security-misc.js +33 -54
  149. package/dist/src/commands/security-misc.js.map +1 -1
  150. package/dist/src/commands/security-scan.d.ts.map +1 -1
  151. package/dist/src/commands/security-scan.js +3 -11
  152. package/dist/src/commands/security-scan.js.map +1 -1
  153. package/dist/src/commands/swarm.d.ts.map +1 -1
  154. package/dist/src/commands/swarm.js +7 -2
  155. package/dist/src/commands/swarm.js.map +1 -1
  156. package/dist/src/commands/ui.d.ts +8 -0
  157. package/dist/src/commands/ui.d.ts.map +1 -0
  158. package/dist/src/commands/ui.js +94 -0
  159. package/dist/src/commands/ui.js.map +1 -0
  160. package/dist/src/init/claudemd-generator.d.ts.map +1 -1
  161. package/dist/src/init/claudemd-generator.js +7 -9
  162. package/dist/src/init/claudemd-generator.js.map +1 -1
  163. package/dist/src/init/executor.d.ts.map +1 -1
  164. package/dist/src/init/executor.js +13 -3
  165. package/dist/src/init/executor.js.map +1 -1
  166. package/dist/src/init/kimi-generator.d.ts +3 -2
  167. package/dist/src/init/kimi-generator.d.ts.map +1 -1
  168. package/dist/src/init/kimi-generator.js +45 -13
  169. package/dist/src/init/kimi-generator.js.map +1 -1
  170. package/dist/src/init/statusline-generator.d.ts +1 -1
  171. package/dist/src/init/statusline-generator.js +1 -1
  172. package/dist/src/init/write-capabilities.js +7 -7
  173. package/dist/src/init/write-capabilities.js.map +1 -1
  174. package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
  175. package/dist/src/knowledge/document-pipeline.js +1 -0
  176. package/dist/src/knowledge/document-pipeline.js.map +1 -1
  177. package/dist/src/knowledge/eval/golden-set.d.ts.map +1 -1
  178. package/dist/src/knowledge/eval/golden-set.js +21 -32
  179. package/dist/src/knowledge/eval/golden-set.js.map +1 -1
  180. package/dist/src/mcp-tools/embeddings-tools.js +2 -2
  181. package/dist/src/mcp-tools/embeddings-tools.js.map +1 -1
  182. package/dist/src/mcp-tools/hooks-intelligence.d.ts.map +1 -1
  183. package/dist/src/mcp-tools/hooks-intelligence.js +29 -3
  184. package/dist/src/mcp-tools/hooks-intelligence.js.map +1 -1
  185. package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
  186. package/dist/src/mcp-tools/hooks-routing.js +32 -19
  187. package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
  188. package/dist/src/mcp-tools/monograph/query-tools.d.ts.map +1 -1
  189. package/dist/src/mcp-tools/monograph/query-tools.js +48 -18
  190. package/dist/src/mcp-tools/monograph/query-tools.js.map +1 -1
  191. package/dist/src/mcp-tools/performance-tools.d.ts.map +1 -1
  192. package/dist/src/mcp-tools/performance-tools.js +15 -10
  193. package/dist/src/mcp-tools/performance-tools.js.map +1 -1
  194. package/dist/src/memory/embedding-operations.d.ts +4 -0
  195. package/dist/src/memory/embedding-operations.d.ts.map +1 -1
  196. package/dist/src/memory/embedding-operations.js +125 -32
  197. package/dist/src/memory/embedding-operations.js.map +1 -1
  198. package/dist/src/memory/hnsw-operations.d.ts +1 -1
  199. package/dist/src/memory/hnsw-operations.js +1 -1
  200. package/dist/src/memory/memory-bridge.d.ts +8 -0
  201. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  202. package/dist/src/memory/memory-bridge.js +37 -8
  203. package/dist/src/memory/memory-bridge.js.map +1 -1
  204. package/dist/src/memory/memory-read.d.ts +1 -1
  205. package/dist/src/memory/memory-read.js +2 -2
  206. package/dist/src/memory/memory-read.js.map +1 -1
  207. package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
  208. package/dist/src/orgrt/antigravity-runner.js +6 -6
  209. package/dist/src/orgrt/antigravity-runner.js.map +1 -1
  210. package/dist/src/orgrt/checkpoint-ops.d.ts +11 -1
  211. package/dist/src/orgrt/checkpoint-ops.d.ts.map +1 -1
  212. package/dist/src/orgrt/checkpoint-ops.js +18 -86
  213. package/dist/src/orgrt/checkpoint-ops.js.map +1 -1
  214. package/dist/src/orgrt/checkpoint.d.ts +1 -1
  215. package/dist/src/orgrt/checkpoint.d.ts.map +1 -1
  216. package/dist/src/orgrt/checkpoint.js +3 -3
  217. package/dist/src/orgrt/checkpoint.js.map +1 -1
  218. package/dist/src/orgrt/daemon.d.ts +9 -1
  219. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  220. package/dist/src/orgrt/daemon.js +267 -139
  221. package/dist/src/orgrt/daemon.js.map +1 -1
  222. package/dist/src/orgrt/decisions.d.ts +13 -0
  223. package/dist/src/orgrt/decisions.d.ts.map +1 -1
  224. package/dist/src/orgrt/decisions.js +95 -0
  225. package/dist/src/orgrt/decisions.js.map +1 -1
  226. package/dist/src/orgrt/forwarder.d.ts.map +1 -1
  227. package/dist/src/orgrt/forwarder.js +148 -15
  228. package/dist/src/orgrt/forwarder.js.map +1 -1
  229. package/dist/src/orgrt/kimicode-runner.js +1 -1
  230. package/dist/src/orgrt/kimicode-runner.js.map +1 -1
  231. package/dist/src/orgrt/opencode-runner.js +1 -1
  232. package/dist/src/orgrt/opencode-runner.js.map +1 -1
  233. package/dist/src/orgrt/session.d.ts +27 -1
  234. package/dist/src/orgrt/session.d.ts.map +1 -1
  235. package/dist/src/orgrt/session.js +67 -6
  236. package/dist/src/orgrt/session.js.map +1 -1
  237. package/dist/src/orgrt/task-dag.d.ts +11 -1
  238. package/dist/src/orgrt/task-dag.d.ts.map +1 -1
  239. package/dist/src/orgrt/task-dag.js +93 -2
  240. package/dist/src/orgrt/task-dag.js.map +1 -1
  241. package/dist/src/orgrt/templates.d.ts.map +1 -1
  242. package/dist/src/orgrt/templates.js +26 -2
  243. package/dist/src/orgrt/templates.js.map +1 -1
  244. package/dist/src/orgrt/types.d.ts +77 -1
  245. package/dist/src/orgrt/types.d.ts.map +1 -1
  246. package/dist/src/orgrt/types.js +28 -2
  247. package/dist/src/orgrt/types.js.map +1 -1
  248. package/dist/src/orgrt/vercel-providers.d.ts.map +1 -1
  249. package/dist/src/orgrt/vercel-providers.js +9 -4
  250. package/dist/src/orgrt/vercel-providers.js.map +1 -1
  251. package/dist/src/orgrt/vercel-runner.d.ts +0 -23
  252. package/dist/src/orgrt/vercel-runner.d.ts.map +1 -1
  253. package/dist/src/orgrt/vercel-runner.js +38 -7
  254. package/dist/src/orgrt/vercel-runner.js.map +1 -1
  255. package/dist/tsconfig.tsbuildinfo +1 -1
  256. package/package.json +3 -3
  257. package/.claude/commands/mastermind/approvev1.md +0 -94
  258. package/.claude/commands/mastermind/architect.md +0 -52
  259. package/.claude/commands/mastermind/autodev.md +0 -28
  260. package/.claude/commands/mastermind/build.md +0 -23
  261. package/.claude/commands/mastermind/finish.md +0 -17
  262. package/.claude/commands/mastermind/runorgv1.md +0 -159
  263. package/.claude/commands/mastermind/taskdev.md +0 -23
  264. package/.claude/commands/mastermind/tdd.md +0 -19
  265. package/.claude/commands/mastermind/verify.md +0 -19
  266. package/.claude/skills/mastermind-approvev1/SKILL.md +0 -191
  267. package/.claude/skills/mastermind-architect/SKILL.md +0 -862
  268. package/.claude/skills/mastermind-autodev/SKILL.md +0 -360
  269. package/.claude/skills/mastermind-build/SKILL.md +0 -169
  270. package/.claude/skills/mastermind-companies/SKILL.md +0 -256
  271. package/.claude/skills/mastermind-content/SKILL.md +0 -197
  272. package/.claude/skills/mastermind-costs/SKILL.md +0 -151
  273. package/.claude/skills/mastermind-finance/SKILL.md +0 -166
  274. package/.claude/skills/mastermind-finish/SKILL.md +0 -251
  275. package/.claude/skills/mastermind-heartbeatv1/SKILL.md +0 -167
  276. package/.claude/skills/mastermind-instance-settings/SKILL.md +0 -315
  277. package/.claude/skills/mastermind-marketing/SKILL.md +0 -228
  278. package/.claude/skills/mastermind-marketing/references/copywriting-frameworks.md +0 -181
  279. package/.claude/skills/mastermind-marketing/references/persuasion-psychology.md +0 -158
  280. package/.claude/skills/mastermind-ops/SKILL.md +0 -168
  281. package/.claude/skills/mastermind-org-chart/SKILL.md +0 -209
  282. package/.claude/skills/mastermind-project-detail/SKILL.md +0 -249
  283. package/.claude/skills/mastermind-project-workspace/SKILL.md +0 -244
  284. package/.claude/skills/mastermind-projects/SKILL.md +0 -167
  285. package/.claude/skills/mastermind-runorgv1/SKILL.md +0 -731
  286. package/.claude/skills/mastermind-sales/SKILL.md +0 -170
  287. package/.claude/skills/mastermind-taskdev/SKILL.md +0 -377
  288. package/.claude/skills/mastermind-taskdev/code-quality-reviewer-prompt.md +0 -60
  289. package/.claude/skills/mastermind-taskdev/final-reviewer-prompt.md +0 -144
  290. package/.claude/skills/mastermind-taskdev/implementer-prompt.md +0 -114
  291. package/.claude/skills/mastermind-taskdev/spec-reviewer-prompt.md +0 -80
  292. package/.claude/skills/mastermind-tdd/SKILL.md +0 -424
  293. package/.claude/skills/mastermind-verify/SKILL.md +0 -196
  294. package/.claude/skills/mastermind-wiki/SKILL.md +0 -314
  295. package/.claude/skills/monolean-review/SKILL.md +0 -57
@@ -21,7 +21,7 @@ import { KimiCodeAgentRunner } from './kimicode-runner.js';
21
21
  import { VercelAgentRunner } from './vercel-runner.js';
22
22
  import { CodexAgentRunner } from './codex-runner.js';
23
23
  import { AntigravityAgentRunner } from './antigravity-runner.js';
24
- import { captureCheckpoint } from './checkpoint.js';
24
+ import { captureCheckpoint, generateChecksum, validateCheckpoint, isCheckpointExpired, restoreMailboxQueue, } from './checkpoint.js';
25
25
  import { loadGlobalFenceConfig, mergeFenceConfigs, createFenceForRole, } from './fence.js';
26
26
  // ── Extracted module imports ────────────────────────────────────────────
27
27
  import * as approvalOps from './approvals.js';
@@ -263,7 +263,7 @@ export class OrgDaemon {
263
263
  return ws;
264
264
  return isAbsolute(ws) ? ws : join(this.root, ws);
265
265
  }
266
- async startOrg(name, taskOverride) {
266
+ async startOrg(name, taskOverride, options) {
267
267
  // A restart-driven start (scheduleBossRestart) keeps its crash counter so the
268
268
  // cap holds; any other (explicit) start resets it so a manual re-run gets a
269
269
  // fresh budget.
@@ -279,9 +279,31 @@ export class OrgDaemon {
279
279
  throw new Error(`org ${name} already running`);
280
280
  const defPath = join(this.root, ORG_DIR, `${name}.json`);
281
281
  const def = OrgDefSchema.parse(JSON.parse(readFileSync(defPath, 'utf8')));
282
- // random suffix: second-precision stamps collide across processes (two CLI
283
- // invocations in the same second would share a run dir and its bus.jsonl)
284
- const run = `run-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}-${Math.random().toString(36).slice(2, 6)}`;
282
+ let run;
283
+ let checkpoint;
284
+ if (options?.resume) {
285
+ const rtPath = join(this.root, ORG_DIR, name, 'runtime.json');
286
+ if (!existsSync(rtPath))
287
+ throw new Error(`cannot resume org "${name}": runtime.json not found`);
288
+ const rt = JSON.parse(readFileSync(rtPath, 'utf8'));
289
+ if (!rt?.run || !rt?.checkpoint)
290
+ throw new Error(`cannot resume org "${name}": no valid checkpoint found`);
291
+ if (isCheckpointExpired(rt.checkpoint))
292
+ throw new Error(`cannot resume org "${name}": checkpoint expired`);
293
+ if (!validateCheckpoint(rt.checkpoint))
294
+ throw new Error(`cannot resume org "${name}": checkpoint validation failed`);
295
+ run = rt.run;
296
+ checkpoint = rt.checkpoint;
297
+ if (rt.abandonedRoles) {
298
+ this.abandoned.set(name, new Set(rt.abandonedRoles));
299
+ }
300
+ }
301
+ else {
302
+ this.abandoned.delete(name); // a previous run's missing roles say nothing about this one
303
+ // random suffix: second-precision stamps collide across processes (two CLI
304
+ // invocations in the same second would share a run dir and its bus.jsonl)
305
+ run = `run-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}-${Math.random().toString(36).slice(2, 6)}`;
306
+ }
285
307
  const dir = join(this.root, ORG_DIR, name, run);
286
308
  mkdirSync(dir, { recursive: true });
287
309
  // Role sessions run at the project root by default. They used to run in an
@@ -292,7 +314,6 @@ export class OrgDaemon {
292
314
  // not path-scoped, meaning the sandbox blocked the safe tools and let the
293
315
  // unrestricted one through. Opt back in with run_config.workspace:
294
316
  // 'isolated', or pin an absolute path.
295
- this.abandoned.delete(name); // a previous run's missing roles say nothing about this one
296
317
  const ws = this.workspaceSetting(def);
297
318
  let cwd;
298
319
  let worktreePath;
@@ -483,7 +504,9 @@ export class OrgDaemon {
483
504
  // Extracted so a role that fails its gate check can be spawned later by
484
505
  // scheduleDeferredSpawn() once resources free up, without re-running the
485
506
  // gate logic or duplicating the session-wiring below.
486
- const spawnRole = (role) => {
507
+ const spawnRole = (role, roleCheckpoint) => {
508
+ if (running.agents.has(role.id))
509
+ return;
487
510
  let roleCwd = cwd;
488
511
  if (ws === 'worktree-per-role' && role.id !== bossRole.id) {
489
512
  const wtPath = join(this.root, ORG_DIR, name, `worktree-${role.id}`);
@@ -517,16 +540,32 @@ export class OrgDaemon {
517
540
  }
518
541
  }
519
542
  const mailbox = new Mailbox();
543
+ if (roleCheckpoint?.mailboxQueue?.length) {
544
+ restoreMailboxQueue({ mailbox }, roleCheckpoint.mailboxQueue);
545
+ }
546
+ if (roleCheckpoint?.mailboxClosed) {
547
+ mailbox.close();
548
+ }
520
549
  const policy = new PolicyEngine(role.id, { maxTokens: role.budget_tokens ?? perRoleBudget, ...(role.policy ?? {}) }, bus, roleCwd);
550
+ if (roleCheckpoint?.tokensUsed) {
551
+ policy.setUsage(roleCheckpoint.tokensUsed);
552
+ }
521
553
  const runtime = {
522
554
  mailbox,
523
555
  policy,
524
- status: 'running',
556
+ status: roleCheckpoint?.status ?? 'running',
525
557
  done: Promise.resolve(),
526
- metrics: { tokens: 0, costUsd: 0 },
558
+ metrics: { tokens: roleCheckpoint?.tokensUsed ?? 0, costUsd: roleCheckpoint?.costUsd ?? 0 },
559
+ lastMessageId: roleCheckpoint?.lastMessageId,
560
+ error: roleCheckpoint?.error,
561
+ sessionId: roleCheckpoint?.sessionId,
527
562
  worktreePath: roleCwd !== cwd ? roleCwd : undefined,
528
563
  scrollback: new ScrollbackBuffer(),
529
564
  };
565
+ if (roleCheckpoint?.scrollback?.length) {
566
+ for (const line of roleCheckpoint.scrollback)
567
+ runtime.scrollback.push(line);
568
+ }
530
569
  const sessionOpts = {
531
570
  org: name,
532
571
  role,
@@ -540,8 +579,10 @@ export class OrgDaemon {
540
579
  // instead of polluting the workspace cwd.
541
580
  orgDir: join(this.root, ORG_DIR, name),
542
581
  maxTurns: role.max_turns_per_message ?? def.run_config.max_turns_per_message,
582
+ resumeSessionId: roleCheckpoint?.sessionId,
543
583
  lastMessageId: () => runtime.lastMessageId,
544
584
  onOutput: (line) => runtime.scrollback.push(line),
585
+ onSessionId: (id) => { runtime.sessionId = id; },
545
586
  deliver: (from, to, subject, body) => this.deliver(name, from, to, subject, body),
546
587
  askHuman: (r, question) => this.askHuman(name, r, question),
547
588
  onGate: (r, gateName, gateDesc) => this.createGate(name, r, gateName, gateDesc),
@@ -628,6 +669,18 @@ export class OrgDaemon {
628
669
  const running = this.orgs.get(name);
629
670
  return JSON.stringify(running?.taskDag?.all() ?? [], null, 2);
630
671
  },
672
+ splitTask: (r, parentId, children) => {
673
+ return this.dagSplitTask(name, r, parentId, children);
674
+ },
675
+ mergeTask: (r, sourceId, targetId) => {
676
+ return this.dagMergeTask(name, r, sourceId, targetId);
677
+ },
678
+ cancelTask: (r, taskId, reason) => {
679
+ return this.dagCancelTask(name, r, taskId, reason);
680
+ },
681
+ planGraph: (r, specs) => {
682
+ return this.dagPlanGraph(name, r, specs);
683
+ },
631
684
  queryFn: this.opts.queryFn,
632
685
  // Runner resolution: explicit opts.runner > role `runtime` field >
633
686
  // org def `runtime` field > MONOMIND_RUNTIME env (opencode/kimicode) >
@@ -646,133 +699,172 @@ export class OrgDaemon {
646
699
  // status chatter) so a dead agent surfaces instead of a run that
647
700
  // silently never progresses.
648
701
  const BACKOFFS_MS = this.opts.crashBackoffsMs ?? [1000, 5000, 15000];
649
- runtime.done = (async () => {
650
- for (let attempt = 0;; attempt++) {
651
- try {
652
- await runAgentSession(sessionOpts);
653
- runtime.status = 'ended';
654
- return;
655
- }
656
- catch (err) {
657
- // Drop the crashed session's stale waker immediately: a push()
658
- // during the backoff window must queue for the NEXT session, not
659
- // wake the dead generator to swallow it.
660
- mailbox.detach();
661
- const message = err instanceof Error ? err.message : String(err);
662
- // Exit 143 = SIGTERM. If the mailbox is already closed, we
663
- // sent the signal ourselves during stop — not a crash.
664
- const killedByStop = mailbox.isClosed && /exit(?:ed)? with code 143/.test(message);
665
- const crash = () => {
666
- if (killedByStop) {
667
- runtime.status = 'ended';
702
+ if (!mailbox.isClosed && runtime.status !== 'crashed') {
703
+ runtime.done = (async () => {
704
+ for (let attempt = 0;; attempt++) {
705
+ try {
706
+ await runAgentSession(sessionOpts);
707
+ runtime.status = 'ended';
708
+ return;
709
+ }
710
+ catch (err) {
711
+ // Drop the crashed session's stale waker immediately: a push()
712
+ // during the backoff window must queue for the NEXT session, not
713
+ // wake the dead generator to swallow it.
714
+ mailbox.detach();
715
+ const message = err instanceof Error ? err.message : String(err);
716
+ const isTurnLimit = /Reached maximum number of turns|error_max_turns/i.test(message);
717
+ // Bounded like every other recovery: attempt counts every pass
718
+ // through this loop, so a role that keeps surfacing max-turns
719
+ // errors here (session.ts already swallows the normal ones)
720
+ // falls through to crash handling instead of looping forever.
721
+ if (isTurnLimit && !mailbox.isClosed && attempt < BACKOFFS_MS.length) {
722
+ sessionOpts.resumeSessionId = undefined;
723
+ mailbox.push(`${Mailbox.CONTINUE_PREFIX} You reached the turn limit on your task. Continue your in-progress work from where you left off; if finished, end your turn.`);
668
724
  bus.emit({
669
725
  type: 'status',
670
726
  from: role.id,
671
- msg: `agent "${role.id}" terminated by stop (was still working when drain window expired)`,
672
- reason: 'terminated-by-stop',
727
+ reason: 'turn-limit-recover',
728
+ msg: `agent "${role.id}" hit turn limit error — continuing with fresh session`,
673
729
  });
674
- return;
730
+ continue;
675
731
  }
676
- runtime.status = 'crashed';
677
- runtime.error = message;
678
- // Close the mailbox so deliver()/receiveRemote() report a real
679
- // error instead of pushing into a queue no session will read
680
- // (and returning a false "delivered" receipt to the sender).
681
- mailbox.close();
682
- const isContextLimit = OrgDaemon.CONTEXT_LIMIT_RE.test(message);
683
- bus.emit({
684
- type: 'audit',
685
- from: role.id,
686
- msg: `agent "${role.id}" crashed: ${message}`,
687
- reason: isContextLimit ? 'agent-context-limit' : 'agent-session-crash',
688
- data: {
689
- agentId: role.id,
690
- error: message,
691
- restarts: attempt,
692
- contextLimit: isContextLimit,
693
- },
694
- });
695
- if (role.id !== bossRole.id) {
696
- // #2/#3: a worker is gone for the rest of this run. Without this
697
- // notice the coordinator keeps messaging a corpse (observed: four
698
- // unanswered org_send calls to a developer that had crashed on a
699
- // context-window limit). Tell the boss to reassign — and if the
700
- // crash was a context overflow, tell it to chunk smaller, since
701
- // re-dispatching the same task verbatim fails the same way.
702
- const bossRt = running.agents.get(bossRole.id);
703
- if (bossRt && !bossRt.mailbox.isClosed) {
704
- const guidance = isContextLimit
705
- ? ' This was a context-window overflow — re-dispatching the same task verbatim will fail identically. Break the work into smaller pieces (one file or section at a time) and do not paste large file contents in a single message.'
706
- : '';
707
- bossRt.mailbox.push(`[system] Worker "${role.id}" crashed and will not recover this run (${message}). It can no longer receive messages — stop messaging it. Reassign its outstanding work to another agent or take it on yourself.${guidance}`);
732
+ // Exit 143 = SIGTERM. If the mailbox is already closed, we
733
+ // sent the signal ourselves during stop — not a crash.
734
+ const killedByStop = mailbox.isClosed && /exit(?:ed)? with code 143/.test(message);
735
+ const crash = () => {
736
+ if (killedByStop) {
737
+ runtime.status = 'ended';
708
738
  bus.emit({
709
- type: 'audit',
710
- from: bossRole.id,
711
- reason: 'worker-crashed',
712
- msg: `worker "${role.id}" crashed (contextLimit=${isContextLimit}); coordinator notified to reassign`,
739
+ type: 'status',
740
+ from: role.id,
741
+ msg: `agent "${role.id}" terminated by stop (was still working when drain window expired)`,
742
+ reason: 'terminated-by-stop',
713
743
  });
744
+ return;
745
+ }
746
+ runtime.status = 'crashed';
747
+ runtime.error = message;
748
+ // Close the mailbox so deliver()/receiveRemote() report a real
749
+ // error instead of pushing into a queue no session will read
750
+ // (and returning a false "delivered" receipt to the sender).
751
+ mailbox.close();
752
+ const isContextLimit = OrgDaemon.CONTEXT_LIMIT_RE.test(message);
753
+ bus.emit({
754
+ type: 'audit',
755
+ from: role.id,
756
+ msg: `agent "${role.id}" crashed: ${message}`,
757
+ reason: isContextLimit ? 'agent-context-limit' : 'agent-session-crash',
758
+ data: {
759
+ agentId: role.id,
760
+ error: message,
761
+ restarts: attempt,
762
+ contextLimit: isContextLimit,
763
+ },
764
+ });
765
+ if (role.id !== bossRole.id) {
766
+ // #2/#3: a worker is gone for the rest of this run. Without this
767
+ // notice the coordinator keeps messaging a corpse (observed: four
768
+ // unanswered org_send calls to a developer that had crashed on a
769
+ // context-window limit). Tell the boss to reassign — and if the
770
+ // crash was a context overflow, tell it to chunk smaller, since
771
+ // re-dispatching the same task verbatim fails the same way.
772
+ const bossRt = running.agents.get(bossRole.id);
773
+ if (bossRt && !bossRt.mailbox.isClosed) {
774
+ const guidance = isContextLimit
775
+ ? ' This was a context-window overflow — re-dispatching the same task verbatim will fail identically. Break the work into smaller pieces (one file or section at a time) and do not paste large file contents in a single message.'
776
+ : '';
777
+ bossRt.mailbox.push(`[system] Worker "${role.id}" crashed and will not recover this run (${message}). It can no longer receive messages — stop messaging it. Reassign its outstanding work to another agent or take it on yourself.${guidance}`);
778
+ bus.emit({
779
+ type: 'audit',
780
+ from: bossRole.id,
781
+ reason: 'worker-crashed',
782
+ msg: `worker "${role.id}" crashed (contextLimit=${isContextLimit}); coordinator notified to reassign`,
783
+ });
784
+ }
785
+ }
786
+ else {
787
+ // #4: the coordinator itself died. Don't go silent and wait for a
788
+ // human — attempt a bounded whole-org restart with fresh sessions
789
+ // (which also sheds whatever bloated context caused the crash).
790
+ this.scheduleBossRestart(name);
714
791
  }
792
+ };
793
+ // Fatal errors (provider auth/quota/billing — tagged with
794
+ // err.fatal by the runner) can NEVER be fixed by a restart: the
795
+ // same call fails identically or hangs. Skip the backoff loop
796
+ // and go straight to terminal crash handling instead of burning
797
+ // the retry budget and wall-clock on a guaranteed failure.
798
+ const fatal = err?.fatal === true;
799
+ if (fatal) {
800
+ bus.emit({
801
+ type: 'status',
802
+ from: role.id,
803
+ reason: 'agent-fatal',
804
+ msg: `agent "${role.id}" hit a fatal (non-retryable) error — not restarting`,
805
+ });
806
+ crash();
807
+ return;
715
808
  }
716
- else {
717
- // #4: the coordinator itself died. Don't go silent and wait for a
718
- // human — attempt a bounded whole-org restart with fresh sessions
719
- // (which also sheds whatever bloated context caused the crash).
720
- this.scheduleBossRestart(name);
809
+ if (mailbox.isClosed || attempt >= BACKOFFS_MS.length) {
810
+ crash();
811
+ return;
721
812
  }
722
- };
723
- // Fatal errors (provider auth/quota/billing — tagged with
724
- // err.fatal by the runner) can NEVER be fixed by a restart: the
725
- // same call fails identically or hangs. Skip the backoff loop
726
- // and go straight to terminal crash handling instead of burning
727
- // the retry budget and wall-clock on a guaranteed failure.
728
- const fatal = err?.fatal === true;
729
- if (fatal) {
730
813
  bus.emit({
731
814
  type: 'status',
732
815
  from: role.id,
733
- reason: 'agent-fatal',
734
- msg: `agent "${role.id}" hit a fatal (non-retryable) error — not restarting`,
816
+ reason: 'agent-restart',
817
+ msg: `agent "${role.id}" crashed (${message}) — restarting in ${BACKOFFS_MS[attempt]}ms (attempt ${attempt + 1}/${BACKOFFS_MS.length})`,
735
818
  });
736
- crash();
737
- return;
738
- }
739
- if (mailbox.isClosed || attempt >= BACKOFFS_MS.length) {
740
- crash();
741
- return;
819
+ await new Promise((r) => {
820
+ const t = setTimeout(r, BACKOFFS_MS[attempt]);
821
+ t.unref?.();
822
+ });
823
+ if (mailbox.isClosed) {
824
+ crash();
825
+ return;
826
+ } // org stopped during backoff — never recovered
742
827
  }
743
- bus.emit({
744
- type: 'status',
745
- from: role.id,
746
- reason: 'agent-restart',
747
- msg: `agent "${role.id}" crashed (${message}) — restarting in ${BACKOFFS_MS[attempt]}ms (attempt ${attempt + 1}/${BACKOFFS_MS.length})`,
748
- });
749
- await new Promise((r) => {
750
- const t = setTimeout(r, BACKOFFS_MS[attempt]);
751
- t.unref?.();
752
- });
753
- if (mailbox.isClosed) {
754
- crash();
755
- return;
756
- } // org stopped during backoff — never recovered
757
828
  }
758
- }
759
- })();
829
+ })();
830
+ }
760
831
  running.agents.set(role.id, runtime);
761
832
  };
762
- spawnRole(bossRole); // always, ungated — see comment above
763
- // Lazy spawn: register non-boss roles as pending. They spawn on first
764
- // message (see deliver()), avoiding the memory gate stampede at startup.
765
- const pendingRoles = new Map();
766
- for (const role of def.roles) {
767
- if (role.id === bossRole.id)
768
- continue;
769
- pendingRoles.set(role.id, role);
833
+ if (options?.resume && checkpoint) {
834
+ const restoredRoles = new Set(Object.keys(checkpoint.roleState));
835
+ for (const [roleId, roleState] of Object.entries(checkpoint.roleState)) {
836
+ const role = def.roles.find((r) => r.id === roleId);
837
+ if (role)
838
+ spawnRole(role, roleState);
839
+ }
840
+ const pendingRoles = new Map();
841
+ for (const role of def.roles) {
842
+ if (!restoredRoles.has(role.id)) {
843
+ pendingRoles.set(role.id, role);
844
+ }
845
+ }
846
+ running.pendingRoles = pendingRoles;
847
+ running.spawnRole = spawnRole;
848
+ running.taskDag = new TaskDag();
849
+ if (worktreePath)
850
+ running.worktreePath = worktreePath;
851
+ }
852
+ else {
853
+ spawnRole(bossRole); // always, ungated — see comment above
854
+ // Lazy spawn: register non-boss roles as pending. They spawn on first
855
+ // message (see deliver()), avoiding the memory gate stampede at startup.
856
+ const pendingRoles = new Map();
857
+ for (const role of def.roles) {
858
+ if (role.id === bossRole.id)
859
+ continue;
860
+ pendingRoles.set(role.id, role);
861
+ }
862
+ running.pendingRoles = pendingRoles;
863
+ running.spawnRole = spawnRole;
864
+ running.taskDag = new TaskDag();
865
+ if (worktreePath)
866
+ running.worktreePath = worktreePath;
770
867
  }
771
- running.pendingRoles = pendingRoles;
772
- running.spawnRole = spawnRole;
773
- running.taskDag = new TaskDag();
774
- if (worktreePath)
775
- running.worktreePath = worktreePath;
776
868
  // Crash cleanup: reap SDK children if this process exits abnormally.
777
869
  // monolean: process-scoped listener — upgrade path = per-org tracking
778
870
  const crashCleanup = () => {
@@ -816,25 +908,40 @@ export class OrgDaemon {
816
908
  }
817
909
  }
818
910
  const boss = bossRole;
819
- // Cross-run memory: brief the coordinator on the previous run so scheduled
820
- // orgs accumulate instead of starting cold every interval.
821
- const prev = readHistory(this.root, name).at(-1);
822
- const prevBrief = prev
823
- ? `\n\nPrevious run (${prev.run}${prev.endedAt ? `, ${new Date(prev.endedAt).toISOString()}` : ''}): ` +
824
- (prev.outcome
825
- ? `outcome "${prev.outcome.status}" — ${prev.outcome.summary}`
826
- : `no recorded outcome (${prev.messages} messages, ${prev.assets.length} assets${prev.crashes.length ? `, ${prev.crashes.length} crashed agent(s)` : ''})`) +
827
- `\nBuild on that work — do not redo what is already done.`
828
- : '';
829
- running.agents
830
- .get(boss.id)
831
- .mailbox.push(`Org "${name}" started (run ${run}).\nGoal: ${taskOverride ?? def.goal}\n` +
832
- `Coordinate your team via org_send. When the goal is achieved (or clearly can't be), record it with org_complete, then end your turn.${prevBrief}`);
833
- bus.emit({
834
- type: 'status',
835
- msg: `org started (${def.roles.length} agents)`,
836
- data: { goal: taskOverride ?? def.goal },
837
- });
911
+ if (options?.resume) {
912
+ if (running.agents.get(boss.id)?.mailbox.serialize().queue.length === 0) {
913
+ running.agents
914
+ .get(boss.id)
915
+ ?.mailbox.push(`Org "${name}" resumed from checkpoint (run ${run}).\nGoal: ${taskOverride ?? def.goal}\n` +
916
+ `Outstanding tasks and role states have been restored. Continue coordinating your team.`);
917
+ }
918
+ bus.emit({
919
+ type: 'status',
920
+ msg: `org resumed from checkpoint (${run})`,
921
+ data: { goal: taskOverride ?? def.goal },
922
+ });
923
+ }
924
+ else {
925
+ // Cross-run memory: brief the coordinator on the previous run so scheduled
926
+ // orgs accumulate instead of starting cold every interval.
927
+ const prev = readHistory(this.root, name).at(-1);
928
+ const prevBrief = prev
929
+ ? `\n\nPrevious run (${prev.run}${prev.endedAt ? `, ${new Date(prev.endedAt).toISOString()}` : ''}): ` +
930
+ (prev.outcome
931
+ ? `outcome "${prev.outcome.status}" — ${prev.outcome.summary}`
932
+ : `no recorded outcome (${prev.messages} messages, ${prev.assets.length} assets${prev.crashes.length ? `, ${prev.crashes.length} crashed agent(s)` : ''})`) +
933
+ `\nBuild on that work — do not redo what is already done.`
934
+ : '';
935
+ running.agents
936
+ .get(boss.id)
937
+ .mailbox.push(`Org "${name}" started (run ${run}).\nGoal: ${taskOverride ?? def.goal}\n` +
938
+ `Coordinate your team via org_send. When the goal is achieved (or clearly can't be), record it with org_complete, then end your turn.${prevBrief}`);
939
+ bus.emit({
940
+ type: 'status',
941
+ msg: `org started (${def.roles.length} agents)`,
942
+ data: { goal: taskOverride ?? def.goal },
943
+ });
944
+ }
838
945
  this.persistState(name, 'running', run);
839
946
  // Idle watchdog: a hung tool call (or a run that quietly finished without
840
947
  // org_complete) produces no bus events, and every agent just waits. After
@@ -966,7 +1073,7 @@ export class OrgDaemon {
966
1073
  // Snapshot checkpoint BEFORE closing mailboxes / draining sessions — the
967
1074
  // queue is emptied during the drain, so capturing afterwards loses all
968
1075
  // unconsumed messages (the whole point of checkpoint-resume).
969
- const stopCheckpoint = captureCheckpoint(org);
1076
+ const stopCheckpoint = captureCheckpoint(org, 'stopped');
970
1077
  // Capture THIS run's forwarder now: an autoWake-restart of the same org
971
1078
  // during the long tail below (agent wait, flush, history write) would
972
1079
  // register a NEW forwarder under the same name — settling/unsubscribing
@@ -1112,12 +1219,21 @@ export class OrgDaemon {
1112
1219
  const p = join(this.root, ORG_DIR, name, 'runtime.json');
1113
1220
  const missing = [...(this.abandoned.get(name) ?? [])];
1114
1221
  const running = org ?? this.orgs.get(name);
1222
+ const validStatus = status === 'stopped' || status === 'crashed' ? status : 'running';
1115
1223
  // Pattern 3: Capture full checkpoint state for resume. On stop, finishStop
1116
1224
  // passes a snapshot captured BEFORE mailboxes close and sessions drain —
1117
1225
  // otherwise the queue is always empty by persist time.
1118
1226
  let checkpoint = checkpointOverride ?? null;
1119
- if (running) {
1120
- checkpoint = captureCheckpoint(running);
1227
+ if (!checkpoint && running) {
1228
+ checkpoint = captureCheckpoint(running, validStatus);
1229
+ }
1230
+ else if (checkpoint && checkpoint.status !== validStatus) {
1231
+ const { checksum: _, ...state } = checkpoint;
1232
+ checkpoint = {
1233
+ ...state,
1234
+ status: validStatus,
1235
+ checksum: generateChecksum({ ...state, status: validStatus }),
1236
+ };
1121
1237
  }
1122
1238
  // C4: writeJsonFileAtomic (tmp + rename) — a direct writeFileSync here
1123
1239
  // could leave runtime.json truncated on Ctrl-C during `org stop`, which
@@ -1216,6 +1332,18 @@ export class OrgDaemon {
1216
1332
  dagCompleteTask(org, role, taskId, result) {
1217
1333
  return decisionOps.dagCompleteTask(this, org, role, taskId, result);
1218
1334
  }
1335
+ dagSplitTask(org, role, parentId, children) {
1336
+ return decisionOps.dagSplitTask(this, org, role, parentId, children);
1337
+ }
1338
+ dagMergeTask(org, role, sourceId, targetId) {
1339
+ return decisionOps.dagMergeTask(this, org, role, sourceId, targetId);
1340
+ }
1341
+ dagCancelTask(org, role, taskId, reason) {
1342
+ return decisionOps.dagCancelTask(this, org, role, taskId, reason);
1343
+ }
1344
+ dagPlanGraph(org, role, specs) {
1345
+ return decisionOps.dagPlanGraph(this, org, role, specs);
1346
+ }
1219
1347
  recordDecision(org, role, decision) {
1220
1348
  decisionOps.recordDecision(this, org, role, decision);
1221
1349
  }