@geraldmaron/construct 1.4.2 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (519) hide show
  1. package/.env.example +36 -0
  2. package/README.md +41 -7
  3. package/bin/construct +1027 -64
  4. package/examples/distribution/sources/deck-one-pager.md +1 -1
  5. package/lib/acp/server.mjs +21 -7
  6. package/lib/adapters-sync.mjs +2 -1
  7. package/lib/audit-trail.mjs +185 -2
  8. package/lib/beads/auto-close.mjs +2 -1
  9. package/lib/beads/drift.mjs +2 -1
  10. package/lib/bridges/copilot-proxy.mjs +20 -5
  11. package/lib/certification/skill-inventory.mjs +10 -1
  12. package/lib/cli/approvals.mjs +147 -0
  13. package/lib/cli-commands.mjs +105 -14
  14. package/lib/comment-lint.mjs +127 -8
  15. package/lib/config/schema.mjs +6 -29
  16. package/lib/config/source-target-registry.mjs +70 -0
  17. package/lib/config/source-targets.mjs +179 -205
  18. package/lib/contracts/coverage.mjs +77 -0
  19. package/lib/contracts/validate.mjs +102 -13
  20. package/lib/contracts/violation-log.mjs +50 -4
  21. package/lib/db/migrate.mjs +69 -0
  22. package/lib/db/migrations/001_orchestration_runs.sql +9 -0
  23. package/lib/db/migrations/002_queue_provider.sql +50 -0
  24. package/lib/db/migrations/003_worker_registry.sql +17 -0
  25. package/lib/db/migrations/004_trace_events.sql +16 -0
  26. package/lib/db/migrations/005_shared_memory.sql +15 -0
  27. package/lib/db/migrations/006_orchestration_runs_tenant.sql +5 -0
  28. package/lib/decisions/enforced-baseline.json +0 -2
  29. package/lib/decisions/registry.mjs +3 -2
  30. package/lib/deployment/parity-contract.mjs +1 -1
  31. package/lib/deployment-mode.mjs +78 -2
  32. package/lib/diagram-export.mjs +10 -1
  33. package/lib/distill.mjs +5 -2
  34. package/lib/docs-verify.mjs +2 -1
  35. package/lib/doctor/cli.mjs +1 -0
  36. package/lib/doctor/command-on-path.mjs +24 -0
  37. package/lib/doctor/diagnosis.mjs +89 -0
  38. package/lib/doctor/embedding-health.mjs +50 -0
  39. package/lib/doctor/engine-health.mjs +93 -0
  40. package/lib/doctor/graph-validate.mjs +47 -0
  41. package/lib/doctor/index.mjs +18 -4
  42. package/lib/doctor/sidecar-providers.mjs +56 -0
  43. package/lib/doctor/watchers/consistency.mjs +93 -1
  44. package/lib/doctor/watchers/cx-budget.mjs +1 -1
  45. package/lib/doctor/watchers/graph-staleness.mjs +1 -1
  46. package/lib/doctor/watchers/mcp-protocol.mjs +17 -0
  47. package/lib/doctor/watchers/oracle-liveness.mjs +92 -0
  48. package/lib/doctor/watchers/orchestration-runs.mjs +108 -0
  49. package/lib/doctor/watchers/provider-breaker.mjs +78 -0
  50. package/lib/document-export.mjs +52 -27
  51. package/lib/document-extract/docling-client.mjs +9 -5
  52. package/lib/document-extract/docling-sidecar.py +30 -0
  53. package/lib/document-extract.mjs +1 -1
  54. package/lib/document-ingest.mjs +9 -0
  55. package/lib/embed/approval-queue.mjs +184 -88
  56. package/lib/embed/authority-guard.mjs +65 -2
  57. package/lib/embed/capability-jobs.mjs +365 -0
  58. package/lib/embed/capability-lifecycle.mjs +219 -0
  59. package/lib/embed/capability-loader.mjs +303 -0
  60. package/lib/embed/capability-runtime.mjs +58 -0
  61. package/lib/embed/cli.mjs +185 -8
  62. package/lib/embed/config.mjs +4 -0
  63. package/lib/embed/daemon.mjs +125 -6
  64. package/lib/embed/demand-fetch.mjs +190 -54
  65. package/lib/embed/inbox.mjs +12 -10
  66. package/lib/embed/presets/ops-triage.mjs +236 -0
  67. package/lib/embed/presets/pm-feedback.mjs +341 -0
  68. package/lib/embed/presets/tpm.mjs +401 -0
  69. package/lib/embed/providers/jira.mjs +72 -1
  70. package/lib/embed/providers/registry.mjs +140 -33
  71. package/lib/embedded-contract/capability.mjs +4 -0
  72. package/lib/embedded-contract/execution.mjs +1 -1
  73. package/lib/embedded-contract/model-resolve.mjs +53 -3
  74. package/lib/embedded-contract/workflow-defs.mjs +48 -73
  75. package/lib/embedded-contract/workflow-invoke.mjs +144 -4
  76. package/lib/embedded-contract/workflows/architecture-review.manifest.json +15 -0
  77. package/lib/embedded-contract/workflows/data-structure.manifest.json +14 -0
  78. package/lib/embedded-contract/workflows/evidence-ingest.manifest.json +14 -0
  79. package/lib/embedded-contract/workflows/memo-draft.manifest.json +14 -0
  80. package/lib/embedded-contract/workflows/operations-triage.manifest.json +18 -0
  81. package/lib/embedded-contract/workflows/operations.manifest.json +18 -0
  82. package/lib/embedded-contract/workflows/pm-feedback.manifest.json +18 -0
  83. package/lib/embedded-contract/workflows/prd-draft.manifest.json +15 -0
  84. package/lib/embedded-contract/workflows/proposal-review.manifest.json +15 -0
  85. package/lib/embedded-contract/workflows/research-synthesis.manifest.json +14 -0
  86. package/lib/embedded-contract/workflows/risk-review.manifest.json +15 -0
  87. package/lib/embedded-contract/workflows/structure-notes.manifest.json +14 -0
  88. package/lib/embedded-contract/workflows/transcript-process.manifest.json +14 -0
  89. package/lib/embedded-contract/workflows/triage.manifest.json +14 -0
  90. package/lib/env-config.mjs +50 -9
  91. package/lib/extensions/index.mjs +27 -0
  92. package/lib/extensions/loader.mjs +120 -0
  93. package/lib/extensions/manifest-schema.mjs +141 -0
  94. package/lib/extensions/manifests/anthropic.manifest.json +12 -0
  95. package/lib/extensions/manifests/atlassian-confluence.manifest.json +12 -0
  96. package/lib/extensions/manifests/atlassian-jira.manifest.json +53 -0
  97. package/lib/extensions/manifests/directory.manifest.json +12 -0
  98. package/lib/extensions/manifests/docling.manifest.json +37 -0
  99. package/lib/extensions/manifests/echo.manifest.json +8 -0
  100. package/lib/extensions/manifests/feedback.manifest.json +12 -0
  101. package/lib/extensions/manifests/github-copilot.manifest.json +12 -0
  102. package/lib/extensions/manifests/github.manifest.json +52 -0
  103. package/lib/extensions/manifests/linear.manifest.json +50 -0
  104. package/lib/extensions/manifests/local.manifest.json +12 -0
  105. package/lib/extensions/manifests/ollama.manifest.json +12 -0
  106. package/lib/extensions/manifests/openai.manifest.json +12 -0
  107. package/lib/extensions/manifests/openrouter-anthropic.manifest.json +12 -0
  108. package/lib/extensions/manifests/openrouter-deepseek.manifest.json +12 -0
  109. package/lib/extensions/manifests/openrouter-google.manifest.json +12 -0
  110. package/lib/extensions/manifests/openrouter-llama.manifest.json +12 -0
  111. package/lib/extensions/manifests/openrouter-qwen.manifest.json +12 -0
  112. package/lib/extensions/manifests/openrouter.manifest.json +12 -0
  113. package/lib/extensions/manifests/postgres.manifest.json +12 -0
  114. package/lib/extensions/manifests/salesforce.manifest.json +12 -0
  115. package/lib/extensions/manifests/slack.manifest.json +58 -0
  116. package/lib/extensions/manifests/whisper.manifest.json +36 -0
  117. package/lib/extensions/validate.mjs +175 -0
  118. package/lib/features.mjs +13 -9
  119. package/lib/flows/checkpoint.mjs +184 -0
  120. package/lib/flows/constants.mjs +27 -0
  121. package/lib/flows/define.mjs +146 -0
  122. package/lib/flows/engine.mjs +249 -0
  123. package/lib/flows/errors.mjs +19 -0
  124. package/lib/flows/index.mjs +27 -0
  125. package/lib/flows/joins.mjs +18 -0
  126. package/lib/flows/schema.mjs +90 -0
  127. package/lib/flows/state.mjs +31 -0
  128. package/lib/frameworks/loader.mjs +99 -0
  129. package/lib/frameworks/schema.mjs +157 -0
  130. package/lib/graph/build-from-corpus.mjs +67 -0
  131. package/lib/graph/build-from-embed.mjs +82 -0
  132. package/lib/graph/build-from-registry.mjs +164 -3
  133. package/lib/graph/cli.mjs +456 -12
  134. package/lib/graph/gap-queries.mjs +156 -0
  135. package/lib/graph/gaps.mjs +41 -0
  136. package/lib/graph/impacted.mjs +129 -0
  137. package/lib/graph/runtime-evidence.mjs +177 -0
  138. package/lib/graph/security-coverage.mjs +113 -0
  139. package/lib/graph/staleness.mjs +241 -10
  140. package/lib/graph/store.mjs +24 -7
  141. package/lib/graph/validate.mjs +161 -0
  142. package/lib/headhunt.mjs +9 -8
  143. package/lib/health-check.mjs +15 -7
  144. package/lib/hook-health.mjs +1 -1
  145. package/lib/hooks/agent-tracker.mjs +10 -4
  146. package/lib/hooks/edit-guard.mjs +3 -3
  147. package/lib/hooks/graph-impact-advisory.mjs +2 -2
  148. package/lib/hooks/guard-bash.mjs +41 -15
  149. package/lib/hooks/mcp-health-check.mjs +11 -4
  150. package/lib/hooks/model-fallback.mjs +50 -6
  151. package/lib/hooks/orchestration-dispatch-guard.mjs +14 -3
  152. package/lib/hooks/pre-compact.mjs +181 -173
  153. package/lib/hooks/rule-verifier.mjs +2 -1
  154. package/lib/hooks/session-reflect.mjs +2 -1
  155. package/lib/hooks/session-start.mjs +3 -3
  156. package/lib/host-capabilities.mjs +13 -2
  157. package/lib/host-disposition.mjs +19 -7
  158. package/lib/identity.mjs +92 -0
  159. package/lib/ingest/degraded-extract.mjs +96 -0
  160. package/lib/ingest/docling-remote.mjs +2 -1
  161. package/lib/ingest/provider-extract.mjs +7 -19
  162. package/lib/ingest/sidecar-providers.mjs +196 -0
  163. package/lib/ingest-tooling.mjs +11 -5
  164. package/lib/init-unified.mjs +57 -45
  165. package/lib/init-update.mjs +2 -1
  166. package/lib/install/legacy-global-cleanup.mjs +25 -0
  167. package/lib/intake/daemon.mjs +99 -8
  168. package/lib/intake/git-queue.mjs +110 -38
  169. package/lib/intake/queue-registry.mjs +50 -0
  170. package/lib/intake/queue.mjs +133 -17
  171. package/lib/intake/session-prelude.mjs +57 -8
  172. package/lib/integrations/intake-integrations.mjs +61 -111
  173. package/lib/intent-classifier.mjs +43 -5
  174. package/lib/libreoffice-export.mjs +8 -8
  175. package/lib/logging/rotate.mjs +5 -4
  176. package/lib/mcp/broker.mjs +332 -17
  177. package/lib/mcp/denied-store.mjs +95 -0
  178. package/lib/mcp/destructive-gate.mjs +30 -0
  179. package/lib/mcp/dispatch-envelope.mjs +199 -0
  180. package/lib/mcp/memory-bridge.mjs +2 -1
  181. package/lib/mcp/server.mjs +154 -1411
  182. package/lib/mcp/tool-definitions-memory.mjs +376 -0
  183. package/lib/mcp/tool-definitions-project.mjs +271 -0
  184. package/lib/mcp/tool-definitions-skills.mjs +311 -0
  185. package/lib/mcp/tool-definitions-workflow.mjs +398 -0
  186. package/lib/mcp/tool-definitions.mjs +25 -0
  187. package/lib/mcp/tool-registry.mjs +107 -0
  188. package/lib/mcp/tool-safety.mjs +1 -0
  189. package/lib/mcp/tools/orchestration-delegation-next.tool.mjs +68 -0
  190. package/lib/mcp/tools/orchestration-run.mjs +165 -25
  191. package/lib/mcp/tools/orchestration-task-result.tool.mjs +77 -0
  192. package/lib/mcp/tools/provider-write.mjs +187 -0
  193. package/lib/mcp/tools/scope.mjs +0 -3
  194. package/lib/mcp/tools/skills.mjs +1 -1
  195. package/lib/mcp/tools/storage.mjs +0 -8
  196. package/lib/mcp/transport/auth.mjs +238 -0
  197. package/lib/mcp/transport/http.mjs +136 -0
  198. package/lib/mcp/transport/mode.mjs +31 -0
  199. package/lib/mcp/transport/stdio.mjs +22 -0
  200. package/lib/mcp-catalog.json +4 -4
  201. package/lib/mcp-manager.mjs +34 -23
  202. package/lib/mcp-platform-config.mjs +31 -7
  203. package/lib/mode-capabilities.mjs +109 -0
  204. package/lib/model-router.mjs +42 -9
  205. package/lib/models/catalog.mjs +40 -1
  206. package/lib/net-guard.mjs +247 -0
  207. package/lib/observation-store.mjs +6 -2
  208. package/lib/ollama/provision-context.mjs +2 -1
  209. package/lib/opencode-config.mjs +22 -3
  210. package/lib/opencode-runtime-plugin.mjs +120 -2
  211. package/lib/oracle/actions.mjs +204 -10
  212. package/lib/oracle/cli.mjs +24 -3
  213. package/lib/oracle/dispatch.mjs +2 -1
  214. package/lib/oracle/execute.mjs +2 -2
  215. package/lib/oracle/gaps.mjs +3 -3
  216. package/lib/oracle/heartbeat.mjs +53 -0
  217. package/lib/oracle/read-model.mjs +69 -13
  218. package/lib/oracle/reconcile.mjs +3 -46
  219. package/lib/oracle/routing.mjs +37 -31
  220. package/lib/oracle/synthesize.mjs +1 -1
  221. package/lib/orchestration/classification.mjs +434 -0
  222. package/lib/orchestration/delegation-flow.mjs +132 -0
  223. package/lib/orchestration/flow-selection.mjs +418 -0
  224. package/lib/orchestration/gates.mjs +244 -0
  225. package/lib/orchestration/host-sampling.mjs +121 -0
  226. package/lib/orchestration/policy-constants.mjs +48 -0
  227. package/lib/orchestration/provider-outcome.mjs +197 -0
  228. package/lib/orchestration/readiness.mjs +114 -13
  229. package/lib/orchestration/run-store-postgres.mjs +32 -26
  230. package/lib/orchestration/run-store-sqlite.mjs +8 -14
  231. package/lib/orchestration/run-store.mjs +25 -12
  232. package/lib/orchestration/runtime.mjs +446 -39
  233. package/lib/orchestration/store.mjs +87 -12
  234. package/lib/orchestration/trace-store.mjs +125 -0
  235. package/lib/orchestration/web-capability.mjs +3 -2
  236. package/lib/orchestration/worker-runtime.mjs +162 -0
  237. package/lib/orchestration/worker.mjs +528 -89
  238. package/lib/orchestration-policy.mjs +67 -1111
  239. package/lib/packs/cli.mjs +144 -0
  240. package/lib/packs/core-pack.mjs +112 -0
  241. package/lib/packs/enablement.mjs +187 -0
  242. package/lib/packs/index.mjs +23 -0
  243. package/lib/packs/loader.mjs +176 -0
  244. package/lib/packs/manifest-schema.mjs +58 -0
  245. package/lib/packs/prompts.mjs +120 -0
  246. package/lib/packs/validate.mjs +208 -0
  247. package/lib/plugin-registry.mjs +4 -5
  248. package/lib/policy/audit-gate.mjs +42 -0
  249. package/lib/policy/consumption-budget.mjs +149 -0
  250. package/lib/policy/engine.mjs +81 -6
  251. package/lib/policy/role-authority.mjs +89 -0
  252. package/lib/prompt-composer.js +19 -3
  253. package/lib/providers/contract/adapters/confluence/governed-write.mjs +215 -0
  254. package/lib/providers/contract/adapters/confluence/manifest.json +17 -0
  255. package/lib/providers/contract/adapters/confluence/transport.mjs +135 -0
  256. package/lib/providers/contract/adapters/github/governed-write.mjs +121 -0
  257. package/lib/providers/contract/adapters/github/index.mjs +38 -3
  258. package/lib/providers/contract/adapters/jira/adf.mjs +151 -0
  259. package/lib/providers/contract/adapters/jira/createmeta.mjs +143 -0
  260. package/lib/providers/contract/adapters/jira/governed-write.mjs +182 -0
  261. package/lib/providers/contract/adapters/jira/manifest.json +17 -0
  262. package/lib/providers/contract/adapters/jira/transport.mjs +119 -0
  263. package/lib/providers/contract.mjs +207 -0
  264. package/lib/providers/credential-bootstrap.mjs +7 -4
  265. package/lib/providers/credential-sources.mjs +14 -2
  266. package/lib/providers/directory/index.mjs +273 -0
  267. package/lib/providers/feedback/index.mjs +392 -0
  268. package/lib/providers/filter-audit.mjs +68 -0
  269. package/lib/providers/filter-schema.mjs +54 -0
  270. package/lib/providers/github/index.mjs +31 -0
  271. package/lib/providers/instance-config.mjs +215 -0
  272. package/lib/providers/op-locate.mjs +96 -0
  273. package/lib/providers/op-run.mjs +64 -9
  274. package/lib/providers/registry.mjs +26 -3
  275. package/lib/providers/secret-audit-wiring.mjs +6 -0
  276. package/lib/providers/secret-resolver.mjs +240 -23
  277. package/lib/publish-template.mjs +6 -3
  278. package/lib/publish-tooling.mjs +4 -0
  279. package/lib/publish.mjs +32 -4
  280. package/lib/queue/pg-queue.mjs +395 -0
  281. package/lib/reflect.mjs +2 -1
  282. package/lib/registry/assemble.mjs +28 -2
  283. package/lib/registry/consolidation.mjs +8 -1
  284. package/lib/registry/custom-scaffold.mjs +200 -0
  285. package/lib/registry/custom-schema.mjs +137 -0
  286. package/lib/registry/loader.mjs +8 -3
  287. package/lib/registry/manifests/format-engines.default.json +15 -0
  288. package/lib/registry/manifests/surface-map.default.json +46 -0
  289. package/lib/registry/retired-paths.mjs +1 -0
  290. package/lib/registry/surface-map.mjs +100 -50
  291. package/lib/render-visual-check.mjs +240 -0
  292. package/lib/resources/budget.mjs +40 -17
  293. package/lib/roles/flavor-bindings.mjs +36 -14
  294. package/lib/roles/gateway.mjs +15 -8
  295. package/lib/roots.mjs +107 -0
  296. package/lib/runtime/uv-bootstrap.mjs +32 -6
  297. package/lib/runtime/whisper-bootstrap.mjs +11 -3
  298. package/lib/runtime-env.mjs +5 -2
  299. package/lib/scheduler/index.mjs +8 -20
  300. package/lib/schema-infer.mjs +31 -2
  301. package/lib/scopes/lifecycle.mjs +29 -25
  302. package/lib/scopes/loader.mjs +49 -12
  303. package/lib/scopes/teams.mjs +1 -1
  304. package/lib/security/ingest-boundary.mjs +80 -0
  305. package/lib/security/recall-wrapper.mjs +99 -0
  306. package/lib/security/trust.mjs +132 -0
  307. package/lib/service-manager.mjs +38 -19
  308. package/lib/setup.mjs +41 -23
  309. package/lib/skills-apply.mjs +4 -2
  310. package/lib/specialists/postconditions.mjs +2 -2
  311. package/lib/state-root.mjs +147 -0
  312. package/lib/status.mjs +597 -6
  313. package/lib/storage/admin.mjs +77 -5
  314. package/lib/storage/backend-registry.mjs +73 -0
  315. package/lib/storage/backend.mjs +63 -9
  316. package/lib/storage/embeddings-openai.mjs +12 -2
  317. package/lib/storage/hybrid-query.mjs +11 -3
  318. package/lib/storage/retrieval-hardening.mjs +384 -0
  319. package/lib/storage/shared-memory.mjs +158 -0
  320. package/lib/storage/vector-client.mjs +69 -2
  321. package/lib/team/health.mjs +72 -0
  322. package/lib/telemetry/backends/local.mjs +9 -3
  323. package/lib/telemetry/client.mjs +3 -7
  324. package/lib/template-registry.mjs +10 -12
  325. package/lib/tenant/context.mjs +82 -0
  326. package/lib/tenant/isolation.mjs +129 -0
  327. package/lib/test-corpus-inventory.mjs +104 -2
  328. package/lib/uninstall/uninstall.mjs +78 -12
  329. package/lib/validator.mjs +4 -6
  330. package/lib/worker/entrypoint.mjs +2 -1
  331. package/lib/worker/run.mjs +2 -2
  332. package/lib/worker/trace.mjs +5 -11
  333. package/lib/workflow-state.mjs +52 -8
  334. package/lib/workflows/liveness.mjs +203 -0
  335. package/lib/workflows/loader.mjs +177 -0
  336. package/lib/workflows/manifest-schema.mjs +71 -0
  337. package/lib/workflows/surface-parity.mjs +118 -0
  338. package/lib/workflows/validate.mjs +127 -0
  339. package/lib/writes/control-plane.mjs +140 -0
  340. package/lib/writes/envelope.mjs +206 -0
  341. package/lib/writes/sent-log.mjs +86 -0
  342. package/lib/writes/write-intent.mjs +109 -0
  343. package/package.json +16 -8
  344. package/personas/construct.md +12 -3
  345. package/registry/capabilities.json +143 -36
  346. package/rules/common/comments.md +1 -0
  347. package/schemas/project-config.schema.json +0 -12
  348. package/schemas/unified-registry.schema.json +2 -4
  349. package/scripts/sync-specialists.mjs +284 -81
  350. package/skills/docs/adr-workflow.md +1 -1
  351. package/skills/docs/codebase-research-workflow.md +3 -3
  352. package/skills/docs/prd-workflow.md +5 -6
  353. package/skills/docs/runbook-workflow.md +2 -2
  354. package/skills/docs/user-research-workflow.md +3 -3
  355. package/skills/operating/fleet-health-routing.md +77 -0
  356. package/skills/roles/ai-engineer.md +1 -1
  357. package/skills/roles/architect.md +0 -1
  358. package/skills/roles/business-strategist.md +1 -1
  359. package/skills/roles/data-analyst.telemetry.md +1 -1
  360. package/skills/roles/data-engineer.md +1 -1
  361. package/skills/roles/data-engineer.pipeline.md +1 -1
  362. package/skills/roles/data-engineer.vector-retrieval.md +1 -2
  363. package/skills/roles/data-engineer.warehouse.md +1 -1
  364. package/skills/roles/designer.accessibility.md +1 -1
  365. package/skills/roles/designer.md +0 -1
  366. package/skills/roles/devil-advocate.md +1 -1
  367. package/skills/roles/docs-keeper.md +1 -1
  368. package/skills/roles/evaluator.md +1 -1
  369. package/skills/roles/explorer.md +1 -1
  370. package/skills/roles/platform-engineer.md +1 -1
  371. package/skills/roles/qa.ai-eval.md +1 -2
  372. package/skills/roles/qa.api-contract.md +0 -1
  373. package/skills/roles/qa.data-pipeline.md +0 -1
  374. package/skills/roles/qa.md +0 -1
  375. package/skills/roles/qa.web-ui.md +0 -1
  376. package/skills/roles/release-manager.md +1 -1
  377. package/skills/roles/researcher.md +0 -2
  378. package/skills/roles/reviewer.md +0 -3
  379. package/skills/roles/security.ai.md +1 -1
  380. package/skills/roles/security.legal-compliance.md +1 -1
  381. package/skills/roles/security.md +0 -1
  382. package/skills/roles/security.privacy.md +0 -1
  383. package/skills/roles/security.supply-chain.md +1 -1
  384. package/skills/roles/sre.md +1 -1
  385. package/skills/roles/test-automation.md +1 -1
  386. package/skills/roles/trace-reviewer.md +1 -1
  387. package/skills/roles/ux-researcher.md +1 -1
  388. package/specialists/artifact-manifest.json +36 -36
  389. package/specialists/org/contracts/accessibility-to-qa.json +11 -3
  390. package/specialists/org/contracts/any-to-business-strategist.json +19 -7
  391. package/specialists/org/contracts/any-to-debugger.json +7 -1
  392. package/specialists/org/contracts/any-to-designer.json +7 -1
  393. package/specialists/org/contracts/any-to-docs-keeper.json +18 -4
  394. package/specialists/org/contracts/any-to-explorer.json +13 -4
  395. package/specialists/org/contracts/any-to-sre-incident.json +6 -2
  396. package/specialists/org/contracts/any-to-trace-reviewer.json +16 -4
  397. package/specialists/org/contracts/architect-to-ai-engineer.json +6 -2
  398. package/specialists/org/contracts/architect-to-data-engineer.json +17 -5
  399. package/specialists/org/contracts/architect-to-devil-advocate.json +11 -3
  400. package/specialists/org/contracts/architect-to-engineer.json +20 -4
  401. package/specialists/org/contracts/architect-to-evaluator.json +15 -5
  402. package/specialists/org/contracts/architect-to-legal-compliance.json +15 -5
  403. package/specialists/org/contracts/architect-to-operations.json +17 -4
  404. package/specialists/org/contracts/architect-to-platform-engineer.json +20 -4
  405. package/specialists/org/contracts/construct-to-orchestrator.json +10 -2
  406. package/specialists/org/contracts/data-analyst-to-product-manager.json +11 -2
  407. package/specialists/org/contracts/engineer-to-qa.json +20 -4
  408. package/specialists/org/contracts/engineer-to-reviewer.json +29 -5
  409. package/specialists/org/contracts/explorer-to-engineer.json +11 -3
  410. package/specialists/org/contracts/legal-compliance-to-release-manager.json +12 -4
  411. package/specialists/org/contracts/operations-to-user.json +53 -0
  412. package/specialists/org/contracts/operations-triage-output.json +53 -0
  413. package/specialists/org/contracts/pm-requirements-candidates.json +53 -0
  414. package/specialists/org/contracts/product-manager-to-architect.json +30 -10
  415. package/specialists/org/contracts/product-manager-to-data-analyst.json +13 -3
  416. package/specialists/org/contracts/product-manager-to-ux-researcher.json +15 -5
  417. package/specialists/org/contracts/qa-to-release-manager.json +11 -3
  418. package/specialists/org/contracts/researcher-to-architect.json +10 -2
  419. package/specialists/org/contracts/researcher-to-product-manager.json +16 -5
  420. package/specialists/org/contracts/reviewer-to-security.json +17 -3
  421. package/specialists/org/contracts/test-automation-to-engineer.json +11 -3
  422. package/specialists/org/contracts/trace-reviewer-to-sre.json +12 -4
  423. package/specialists/org/contracts/user-to-construct.json +11 -4
  424. package/specialists/org/frameworks/cx-architect-constraint-option-failure.md +66 -0
  425. package/specialists/org/frameworks/cx-engineer-feasibility-blast-radius.md +66 -0
  426. package/specialists/org/frameworks/cx-ops-dependency-sequencing.md +74 -0
  427. package/specialists/org/frameworks/cx-pm-value-tradeoff.md +66 -0
  428. package/specialists/org/frameworks/cx-qa-risk-based-coverage.md +69 -0
  429. package/specialists/org/groups/engineering-group.json +2 -6
  430. package/specialists/org/groups/governance-group.json +2 -3
  431. package/specialists/org/groups/operations-group.json +5 -8
  432. package/specialists/org/groups/product-group.json +4 -8
  433. package/specialists/org/groups/quality-group.json +3 -7
  434. package/specialists/org/groups/strategy-group.json +6 -9
  435. package/specialists/org/models.json.example +8 -0
  436. package/specialists/org/scopes/creative.json +6 -1
  437. package/specialists/org/scopes/operations.json +7 -1
  438. package/specialists/org/scopes/research.json +6 -1
  439. package/specialists/org/scopes/rnd.json +7 -1
  440. package/specialists/org/specialists/cx-architect.json +27 -8
  441. package/specialists/org/specialists/cx-designer.json +22 -8
  442. package/specialists/org/specialists/cx-engineer.json +71 -7
  443. package/specialists/org/specialists/cx-operations.json +89 -15
  444. package/specialists/org/specialists/cx-orchestrator.json +16 -4
  445. package/specialists/org/specialists/cx-product-manager.json +28 -9
  446. package/specialists/org/specialists/cx-qa.json +16 -6
  447. package/specialists/org/specialists/cx-researcher.json +40 -7
  448. package/specialists/org/specialists/cx-reviewer.json +61 -11
  449. package/specialists/org/specialists/cx-security.json +30 -10
  450. package/specialists/org/teams/design-team.json +3 -4
  451. package/specialists/org/teams/engineering-team.json +3 -10
  452. package/specialists/org/teams/governance-team.json +3 -5
  453. package/specialists/org/teams/operations-team.json +6 -12
  454. package/specialists/org/teams/product-management-team.json +2 -3
  455. package/specialists/org/teams/quality-team.json +4 -12
  456. package/specialists/org/teams/research-team.json +3 -3
  457. package/specialists/org/teams/strategy-team.json +7 -14
  458. package/specialists/prompts/cx-architect.md +20 -1
  459. package/specialists/prompts/cx-data-analyst.md +1 -1
  460. package/specialists/prompts/cx-designer.md +12 -4
  461. package/specialists/prompts/cx-engineer.md +15 -1
  462. package/specialists/prompts/cx-operations.md +14 -2
  463. package/specialists/prompts/cx-orchestrator.md +9 -5
  464. package/specialists/prompts/cx-product-manager.md +5 -1
  465. package/specialists/prompts/cx-qa.md +6 -2
  466. package/specialists/prompts/cx-researcher.md +25 -30
  467. package/specialists/prompts/cx-reviewer.md +19 -1
  468. package/specialists/prompts/cx-security.md +5 -1
  469. package/templates/distribution/construct-brand.typ +123 -59
  470. package/templates/distribution/construct-decision.typ +6 -3
  471. package/templates/distribution/construct-pdf.typ +11 -4
  472. package/templates/distribution/construct-prd.typ +6 -3
  473. package/templates/distribution/construct-research.typ +7 -4
  474. package/lib/providers/contract/adapters/git/index.mjs +0 -115
  475. package/lib/providers/contract/adapters/slack/index.mjs +0 -175
  476. package/specialists/org/contracts/business-strategist-to-product-manager.json +0 -39
  477. package/specialists/org/contracts/construct-to-rd-lead.json +0 -53
  478. package/specialists/org/contracts/data-engineer-to-platform-engineer.json +0 -36
  479. package/specialists/org/contracts/designer-to-accessibility.json +0 -36
  480. package/specialists/org/contracts/platform-engineer-to-engineer.json +0 -31
  481. package/specialists/org/contracts/qa-to-test-automation.json +0 -42
  482. package/specialists/org/contracts/rd-lead-to-architect.json +0 -38
  483. package/specialists/org/contracts/sre-to-release-manager.json +0 -36
  484. package/specialists/org/specialists/cx-accessibility.json +0 -69
  485. package/specialists/org/specialists/cx-ai-engineer.json +0 -75
  486. package/specialists/org/specialists/cx-business-strategist.json +0 -72
  487. package/specialists/org/specialists/cx-data-engineer.json +0 -71
  488. package/specialists/org/specialists/cx-devil-advocate.json +0 -71
  489. package/specialists/org/specialists/cx-docs-keeper.json +0 -82
  490. package/specialists/org/specialists/cx-evaluator.json +0 -69
  491. package/specialists/org/specialists/cx-explorer.json +0 -69
  492. package/specialists/org/specialists/cx-legal-compliance.json +0 -74
  493. package/specialists/org/specialists/cx-oracle.json +0 -46
  494. package/specialists/org/specialists/cx-platform-engineer.json +0 -80
  495. package/specialists/org/specialists/cx-rd-lead.json +0 -73
  496. package/specialists/org/specialists/cx-release-manager.json +0 -77
  497. package/specialists/org/specialists/cx-sre.json +0 -94
  498. package/specialists/org/specialists/cx-test-automation.json +0 -69
  499. package/specialists/org/specialists/cx-trace-reviewer.json +0 -69
  500. package/specialists/org/specialists/cx-ux-researcher.json +0 -68
  501. package/specialists/org/teams/accessibility-team.json +0 -39
  502. package/specialists/org/teams/ux-research-team.json +0 -39
  503. package/specialists/prompts/cx-accessibility.md +0 -55
  504. package/specialists/prompts/cx-ai-engineer.md +0 -124
  505. package/specialists/prompts/cx-business-strategist.md +0 -58
  506. package/specialists/prompts/cx-data-engineer.md +0 -55
  507. package/specialists/prompts/cx-devil-advocate.md +0 -59
  508. package/specialists/prompts/cx-docs-keeper.md +0 -164
  509. package/specialists/prompts/cx-evaluator.md +0 -49
  510. package/specialists/prompts/cx-explorer.md +0 -71
  511. package/specialists/prompts/cx-legal-compliance.md +0 -58
  512. package/specialists/prompts/cx-oracle.md +0 -98
  513. package/specialists/prompts/cx-platform-engineer.md +0 -97
  514. package/specialists/prompts/cx-rd-lead.md +0 -59
  515. package/specialists/prompts/cx-release-manager.md +0 -54
  516. package/specialists/prompts/cx-sre.md +0 -111
  517. package/specialists/prompts/cx-test-automation.md +0 -55
  518. package/specialists/prompts/cx-trace-reviewer.md +0 -101
  519. package/specialists/prompts/cx-ux-researcher.md +0 -53
@@ -0,0 +1,398 @@
1
+ /**
2
+ * lib/mcp/tool-definitions-workflow.mjs — raw tool schemas: publish, workflow lifecycle, orchestration run/status/readiness.
3
+ *
4
+ * Pure data: name/description/inputSchema/outputSchema for a slice of the
5
+ * hardcoded (non-self-registered) MCP tool catalog. Split out of
6
+ * lib/mcp/tool-definitions.mjs (which itself was split out of
7
+ * lib/mcp/server.mjs) purely to keep each file under the ~600-line
8
+ * house limit — no behavior differs from one combined array.
9
+ * lib/mcp/server.mjs concatenates every slice and applies
10
+ * withSafetyEnvelope (lib/mcp/tool-safety.mjs) at load time.
11
+ */
12
+ export const TOOL_DEFS_WORKFLOW = [
13
+ {
14
+ name: 'publish_detect',
15
+ outputSchema: { type: 'object' },
16
+ description: 'Detect availability of publish pipeline tooling: Pandoc/Typst export, pandoc-ext/diagram figures, and VHS terminal demos.',
17
+ inputSchema: {
18
+ type: 'object',
19
+ properties: {
20
+ format: { type: 'string', enum: ['pdf', 'docx', 'doc', 'deck', 'pptx', 'html', 'rtf', 'odt', 'epub', 'tex', 'txt', 'md', 'mdx'], description: 'Export format to probe (default pdf).' },
21
+ figures: { type: 'boolean', description: 'Include figure binaries (default true).' },
22
+ demo: { type: 'string', description: 'When set, require VHS/asciinema for terminal demo.' },
23
+ },
24
+ },
25
+ },
26
+ {
27
+ name: 'publish_run',
28
+ outputSchema: { type: 'object' },
29
+ description: 'Run the publish pipeline: export markdown with optional figure filter and optional demo recordings. Use dry_run=true to probe tooling only.',
30
+ inputSchema: {
31
+ type: 'object',
32
+ required: ['input_path'],
33
+ properties: {
34
+ input_path: { type: 'string', description: 'Absolute path to markdown research brief.' },
35
+ output_path: { type: 'string', description: 'Optional output path for export.' },
36
+ format: { type: 'string', enum: ['pdf', 'docx', 'doc', 'deck', 'pptx', 'html', 'rtf', 'odt', 'epub', 'tex', 'txt', 'md', 'mdx'], description: 'Target format (default pdf).' },
37
+ demo: { type: 'string', description: 'Terminal tape name to record.' },
38
+ figures: { type: 'boolean', description: 'Render diagrams (default true).' },
39
+ strict: { type: 'boolean', description: 'Fail when toolchain or release gate fails (default true).' },
40
+ source_only: { type: 'boolean', description: 'Write sources only (default false).' },
41
+ no_gate: { type: 'boolean', description: 'Skip artifact release gate (default false).' },
42
+ artifact_type: { type: 'string', description: 'Manifest doc type for release gate when path inference is ambiguous.' },
43
+ dry_run: { type: 'boolean', description: 'Detect tooling only (default false).' },
44
+ },
45
+ },
46
+ },
47
+ {
48
+ name: 'knowledge_search',
49
+ outputSchema: { type: 'object' },
50
+ category: 'retrieval',
51
+ description: 'Search Construct\'s own documentation, knowledge base, and distilled embed observations. Call this immediately — no approval needed — when the user asks what Construct is, how a feature works, what commands exist, or anything about Construct\'s architecture or configuration. Also searches embed observations from GitHub, Jira, and other configured sources. Returns relevant excerpts with source file and heading.',
52
+ inputSchema: {
53
+ type: 'object',
54
+ required: ['query'],
55
+ properties: {
56
+ query: { type: 'string', description: 'Natural-language question or keyword (e.g. "what is construct", "how does embed mode work", "provider authority guard", "slack configuration", "open Jira issues").' },
57
+ top_k: { type: 'number', description: 'Max excerpts to return (default: 5).' },
58
+ repo_root: { type: 'string', description: 'Repo root override (default: auto-detected from server location).' },
59
+ root_dir: { type: 'string', description: 'Data directory where .cx/observations/ lives (default: home directory). Pass this to search embed observations from a custom data dir.' },
60
+ },
61
+ },
62
+ },
63
+ {
64
+ name: 'workflow_init',
65
+ outputSchema: { type: 'object' },
66
+ description: 'Initialize a new workflow for the current project. Creates plan.md state if not already present and returns the initial workflow envelope.',
67
+ inputSchema: {
68
+ type: 'object',
69
+ properties: {
70
+ cwd: { type: 'string', description: 'Project root (default: server cwd).' },
71
+ title: { type: 'string', description: 'Workflow title shown in the plan header (default: "Untitled workflow").' },
72
+ spec_ref: { type: 'string', description: 'Optional reference to a spec/PRD/ADR id this workflow implements.' },
73
+ },
74
+ },
75
+ },
76
+ {
77
+ name: 'workflow_add_task',
78
+ outputSchema: { type: 'object' },
79
+ description: 'Add a task to the current workflow. Pass `request` for intent-based routing (the classifier picks track + specialist) or pass explicit task fields (`key`, `title`, etc.) for manual entry.',
80
+ inputSchema: {
81
+ type: 'object',
82
+ properties: {
83
+ cwd: { type: 'string', description: 'Project root (default: server cwd).' },
84
+ request: { type: 'string', description: 'Natural-language task request; when present, intent-based routing is used and the explicit fields below act as overrides.' },
85
+ key: { type: 'string', description: 'Stable task key (e.g. T-001). Generated when omitted.' },
86
+ title: { type: 'string', description: 'Short task title.' },
87
+ phase: { type: 'string', description: 'Phase bucket (plan, build, validate, ship, etc.).' },
88
+ owner: { type: 'string', description: 'Specialist or persona that owns the task.' },
89
+ files: { type: 'array', items: { type: 'string' }, description: 'File paths this task touches.' },
90
+ readFirst: { type: 'array', items: { type: 'string' }, description: 'Files the owner should read before editing.' },
91
+ doNotChange: { type: 'array', items: { type: 'string' }, description: 'Files/regions the owner must not modify.' },
92
+ acceptanceCriteria: { type: 'array', items: { type: 'string' }, description: 'Acceptance criteria as a checklist.' },
93
+ verification: { type: 'string', description: 'Command(s) or description of how to verify the task is done.' },
94
+ dependsOn: { type: 'array', items: { type: 'string' }, description: 'Task keys this task depends on.' },
95
+ overlays: { type: 'array', items: { type: 'string' }, description: 'Role flavors that augment the owner persona for this task.' },
96
+ challengeRequired: { type: 'boolean', description: 'Force a cx-reviewer plan-challenge before the task can complete.' },
97
+ challengeStatus: { type: 'string', description: 'Initial challenge status when seeded.' },
98
+ tokenBudget: { type: 'number', description: 'Per-task token budget for cost tracking.' },
99
+ status: { type: 'string', description: 'Initial status override.' },
100
+ },
101
+ },
102
+ },
103
+ {
104
+ name: 'workflow_update_task',
105
+ outputSchema: { type: 'object' },
106
+ description: 'Update fields on an existing workflow task. Requires the task `key`. Only fields supplied are changed.',
107
+ inputSchema: {
108
+ type: 'object',
109
+ required: ['key'],
110
+ properties: {
111
+ cwd: { type: 'string', description: 'Project root (default: server cwd).' },
112
+ key: { type: 'string', description: 'Task key to update.' },
113
+ status: { type: 'string', description: 'New status (pending, in_progress, blocked_needs_user, blocked_by_dep, done, etc.).' },
114
+ owner: { type: 'string', description: 'New owner persona.' },
115
+ phase: { type: 'string', description: 'New phase bucket.' },
116
+ note: { type: 'string', description: 'Append-only progress note.' },
117
+ verification: { type: 'string', description: 'Updated verification description.' },
118
+ overlays: { type: 'array', items: { type: 'string' }, description: 'Replace the overlay list.' },
119
+ challengeRequired: { type: 'boolean', description: 'Toggle whether a challenge is required.' },
120
+ challengeStatus: { type: 'string', description: 'Update the challenge status (proposed, accepted, refused, etc.).' },
121
+ },
122
+ },
123
+ },
124
+ {
125
+ name: 'workflow_needs_main_input',
126
+ outputSchema: { type: 'object' },
127
+ description: 'Mark a workflow task as blocked pending user input. Sets status to blocked_needs_user and writes a packet describing the blocker for the orchestrator to surface.',
128
+ inputSchema: {
129
+ type: 'object',
130
+ required: ['taskKey', 'blocker', 'question'],
131
+ properties: {
132
+ cwd: { type: 'string', description: 'Project root (default: server cwd).' },
133
+ taskKey: { type: 'string', description: 'Task key to mark blocked.' },
134
+ worker: { type: 'string', description: 'Specialist that needs input (default: current owner).' },
135
+ blocker: { type: 'string', description: 'One-line description of what is blocking progress.' },
136
+ question: { type: 'string', description: 'The specific question to put to the user.' },
137
+ },
138
+ },
139
+ },
140
+ {
141
+ name: 'workflow_validate',
142
+ outputSchema: { type: 'object' },
143
+ description: 'Validate the current workflow state against the schema and run consistency checks (no orphan tasks, no circular dependencies, every owner resolves to a known persona).',
144
+ inputSchema: {
145
+ type: 'object',
146
+ properties: {
147
+ cwd: { type: 'string', description: 'Project root (default: server cwd).' },
148
+ },
149
+ },
150
+ },
151
+ {
152
+ name: 'workflow_status',
153
+ outputSchema: { type: 'object' },
154
+ description: 'Return the full workflow snapshot for the current project: tasks, summary, alignment health, and the public-health surface used by the dashboard.',
155
+ inputSchema: {
156
+ type: 'object',
157
+ properties: {
158
+ cwd: { type: 'string', description: 'Project root (default: server cwd).' },
159
+ },
160
+ },
161
+ },
162
+ {
163
+ name: 'workflow_contract_validate',
164
+ outputSchema: { type: 'object' },
165
+ description: 'Validate a producer→consumer handoff against specialists/org. Required when a specialist hands off to another role: enforces input.mustContain, output schema, disk-artifact postconditions, and binary postconditions per producer (rubber-stamp prevention, post-hoc threat-model prevention, etc.). Self-enforcing: a producer with binary rules MUST pass `packet`, or the call itself is a contract violation.',
166
+ inputSchema: {
167
+ type: 'object',
168
+ required: ['producer', 'consumer'],
169
+ properties: {
170
+ producer: { type: 'string', description: 'Producer agent or persona name (e.g. cx-reviewer, cx-security).' },
171
+ consumer: { type: 'string', description: 'Consumer agent or persona name receiving the handoff.' },
172
+ id: { type: 'string', description: 'Optional contract id; overrides producer/consumer lookup.' },
173
+ artifact: { type: 'object', description: 'The handoff payload to validate against the contract schema and disk-artifact postconditions.' },
174
+ packet: { type: 'object', description: 'The producer\'s in-memory output packet. REQUIRED when the producer has binary postconditions; omitting it is itself a contract violation.' },
175
+ enforcement: { type: 'string', enum: ['block', 'warn'], description: 'Enforcement mode (default: block). Use warn only when explicitly advisory.' },
176
+ },
177
+ },
178
+ },
179
+ {
180
+ name: 'workflow_import_plan',
181
+ outputSchema: { type: 'object' },
182
+ description: 'Bulk-add tasks from a markdown plan to the current workflow. Parses headings and bullet structure to extract task titles, owners, and acceptance criteria.',
183
+ inputSchema: {
184
+ type: 'object',
185
+ required: ['markdown'],
186
+ properties: {
187
+ cwd: { type: 'string', description: 'Project root (default: server cwd).' },
188
+ markdown: { type: 'string', description: 'Plan markdown to parse.' },
189
+ phase: { type: 'string', description: 'Phase bucket applied to all imported tasks.' },
190
+ owner: { type: 'string', description: 'Default owner for tasks that do not specify one.' },
191
+ readFirst: { type: 'array', items: { type: 'string' }, description: 'Default readFirst files applied to all imported tasks.' },
192
+ doNotChange: { type: 'array', items: { type: 'string' }, description: 'Default doNotChange files applied to all imported tasks.' },
193
+ acceptanceCriteria: { type: 'array', items: { type: 'string' }, description: 'Default acceptance criteria applied to all imported tasks.' },
194
+ title: { type: 'string', description: 'Workflow title to set if the workflow is newly created.' },
195
+ spec_ref: { type: 'string', description: 'Spec reference to associate with the workflow.' },
196
+ },
197
+ },
198
+ },
199
+ {
200
+ name: 'cx_trace_telemetry',
201
+ outputSchema: { type: 'object' },
202
+ description: 'Record a single CX telemetry trace for an agent invocation. Use to log start/end, model used, token cost, and outcome verdict for performance review.',
203
+ inputSchema: {
204
+ type: 'object',
205
+ required: ['agent', 'trace'],
206
+ properties: {
207
+ agent: { type: 'string', description: 'Agent or persona name being traced.' },
208
+ trace: { type: 'object', description: 'Trace record: start_ts, end_ts, model, tokens, verdict, notes, etc.' },
209
+ cwd: { type: 'string', description: 'Project root (default: server cwd).' },
210
+ },
211
+ },
212
+ },
213
+ {
214
+ name: 'artifact_workflow',
215
+ outputSchema: { type: 'object' },
216
+ description: 'Plan a manifest-backed document artifact workflow and return a truthful provenance report. It separates planned steps from locally executed validation/export and never claims a host-planned specialist review or rewrite was completed. Durable local export requires approval_mode=allow-durable-write.',
217
+ inputSchema: {
218
+ type: 'object',
219
+ properties: {
220
+ input: { type: 'string', description: 'Natural-language artifact request.' },
221
+ artifact_type: { type: 'string', description: 'Registered manifest document class.' },
222
+ file_path: { type: 'string', description: 'Optional existing source document for local validation/export.' },
223
+ format: { type: 'string', description: 'Distribution format such as pdf, docx, html, deck, or pptx.' },
224
+ output_path: { type: 'string', description: 'Optional output destination when locally exporting.' },
225
+ branding: { type: 'string', enum: ['construct', 'plain'], description: 'Construct is default; plain is an explicit opt-out.' },
226
+ overrides: { type: 'object', description: 'Per-invocation manifest workflow overrides.' },
227
+ approval_mode: { type: 'string', enum: ['proposal-only', 'requires-human-approval', 'allow-durable-write'], description: 'Only allow-durable-write performs local validation/export.' },
228
+ },
229
+ },
230
+ },
231
+ {
232
+ name: 'author_artifact',
233
+ outputSchema: { type: 'object' },
234
+ description: 'Materialize a typed Construct artifact you have drafted (prd, prd-platform, prd-business, meta-prd, adr, rfc, research-brief, evidence-brief, runbook) to disk and run the release gate. YOU draft the full markdown — start with a single # title and include the type\'s required ## sections (call get_template first for the shape) — and pass it as draft_markdown; the canonical file is written and the gate verdict + errors are returned so you can fix and re-call. This is the Construct author→materialize→validate pass for supported hosts.',
235
+ inputSchema: {
236
+ type: 'object',
237
+ properties: {
238
+ draft_markdown: { type: 'string', description: 'The complete artifact markdown you authored. Must start with one # title line and contain the required ## sections for the type.' },
239
+ artifact_type: { type: 'string', description: 'Artifact type (prd, meta-prd, adr, rfc, research-brief, evidence-brief, runbook, …). Defaults to prd; inferred from subject when omitted.' },
240
+ subject: { type: 'string', description: 'Short subject/title hint (e.g. "OIDC integration") used for the filename and type inference.' },
241
+ },
242
+ required: ['draft_markdown'],
243
+ },
244
+ },
245
+ {
246
+ name: 'model_resolve',
247
+ outputSchema: { type: 'object' },
248
+ description: 'Resolve which model an embedded Construct workflow should use given the host/IDE provider context. Precedence: host model → same-provider-family fallback → Construct tier default → structured config error. Never reads or returns credential values (requiresCredential is a boolean) and never claims unverified provider health. Read-only; performs no writes.',
249
+ inputSchema: {
250
+ type: 'object',
251
+ properties: {
252
+ workflow_type: { type: 'string', description: 'Workflow type hint (e.g. evidence-ingest, prd-draft, architecture-review). Selects a tier when requested_tier is absent.' },
253
+ requested_tier: { type: 'string', enum: ['reasoning', 'standard', 'fast'], description: 'Desired tier; overrides the workflow-type hint.' },
254
+ host: { type: 'string', description: 'Host/IDE identifier (advisory).' },
255
+ host_model: { type: 'string', description: 'Model the host is currently using (e.g. anthropic/claude-sonnet-4-6).' },
256
+ host_provider: { type: 'string', description: 'Provider family the host uses, when no host_model is given.' },
257
+ capabilities: { type: 'array', items: { type: 'string' }, description: 'Optional required capabilities; unverifiable ones are returned as warnings.' },
258
+ allow_cross_provider_fallback: { type: 'boolean', description: 'Permit falling back outside the host provider family (default false).' },
259
+ },
260
+ },
261
+ },
262
+ {
263
+ name: 'triage_recommend',
264
+ outputSchema: { type: 'object' },
265
+ description: 'Classify an artifact and return a role-aware plan (primary owner, role chain with rationale, suggested skills, evidence requirements, expected outputs, approval requirements, risks, next steps, canExecute) WITHOUT enqueuing or executing. Classification confidence is reported distinctly from any generation confidence. Read-only; performs no durable write.',
266
+ inputSchema: {
267
+ type: 'object',
268
+ properties: {
269
+ input: { type: 'string', description: 'Artifact text to classify (meeting notes, bug report, proposal, etc.). Provide this OR file_path.' },
270
+ file_path: { type: 'string', description: 'Path to a file to extract and classify (PDF/Office via docling, audio/video via whisper, transcripts, plain text). Used when input is absent.' },
271
+ source_path: { type: 'string', description: 'Optional filename/source hint to aid classification.' },
272
+ artifact_type: { type: 'string', description: 'Optional artifact-type hint (advisory).' },
273
+ domain: { type: 'string', description: 'Optional broad domain hint.' },
274
+ desired_outcome: { type: 'string', description: 'Optional desired outcome (advisory).' },
275
+ constraints: { type: 'array', items: { type: 'string' }, description: 'Optional constraints (advisory).' },
276
+ available_roles: { type: 'array', items: { type: 'string' }, description: 'Restrict the plan to these role ids; dropped roles are reported as warnings.' },
277
+ },
278
+ },
279
+ },
280
+ {
281
+ name: 'workflow_invoke',
282
+ outputSchema: { type: 'object' },
283
+ description: 'Invoke a named Construct workflow (roles/skills) non-interactively and return a provenanced execution plan: selected roles, rationale, applied skills, resolved model, evidence requirements, output contract, risks, and a traceId. Construct returns the orchestration plan; the host runtime performs specialist reasoning. Durable writes occur ONLY when approval_mode is allow-durable-write; proposal-only and requires-human-approval perform no durable writes.',
284
+ inputSchema: {
285
+ type: 'object',
286
+ required: ['workflow_type'],
287
+ properties: {
288
+ workflow_type: { type: 'string', description: 'One of: evidence-ingest, proposal-review, prd-draft, architecture-review, risk-review, research-synthesis.' },
289
+ input: { type: 'string', description: 'Artifact text the workflow operates on. Provide this OR file_path.' },
290
+ file_path: { type: 'string', description: 'Path to a file to extract (docling/whisper/transcript) and operate on, used when input is absent.' },
291
+ context: { type: 'object', description: 'Optional structured context; keys matching evidence requirements mark them satisfied.' },
292
+ role_strategy: { type: 'string', enum: ['auto', 'explicit', 'constrained'], description: 'auto = default chain; explicit = use requested_roles; constrained = default chain intersected with requested_roles.' },
293
+ requested_roles: { type: 'array', items: { type: 'string' }, description: 'Role ids for explicit/constrained strategies.' },
294
+ approval_mode: { type: 'string', enum: ['proposal-only', 'requires-human-approval', 'allow-durable-write'], description: 'Gate for durable writes (default: the workflow type default).' },
295
+ trace: { type: 'boolean', description: 'Emit a traceId for provenance correlation (default true).' },
296
+ host: { type: 'string', description: 'Host/IDE identifier (advisory).' },
297
+ host_model: { type: 'string', description: 'Model the host uses, for model resolution.' },
298
+ host_provider: { type: 'string', description: 'Provider family the host uses, for model resolution.' },
299
+ },
300
+ },
301
+ },
302
+ {
303
+ name: 'capability_describe',
304
+ outputSchema: { type: 'object' },
305
+ description: 'Describe what this Construct install can do: versions, contract interfaces (CLI/MCP/SDK), roles, skills, workflows, schemas, models/providers, policies, telemetry posture, and plugins. Read-only and secret-free — provider entries carry env-key names and a configured boolean only, never credential values. Reads live registries so the published contract cannot drift from reality.',
306
+ inputSchema: {
307
+ type: 'object',
308
+ properties: {
309
+ root_dir: { type: 'string', description: 'Optional Construct install root (default: server toolkit dir).' },
310
+ },
311
+ },
312
+ },
313
+ {
314
+ name: 'construct_execution_resolve',
315
+ outputSchema: { type: 'object' },
316
+ description: 'Resolve the execution-capability contract for an embedded workflow BEFORE/at workflow start: returns executionMode (construct-orchestrated | construct-prompt-only | host-direct | same-family-fallback), constructCapabilitiesActive (subset of personas/skills/workflow-routing/prompt-envelope), degraded + machine-readable degradationReason, requestedStrategy vs effectiveStrategy, and the resolved provider/model. Descriptive, not enforced: reports what Construct planned and can resolve a model for, never an observation that the host ran personas (see the semantics field). Read-only and secret-free.',
317
+ inputSchema: {
318
+ type: 'object',
319
+ properties: {
320
+ workflow_type: { type: 'string', description: 'Workflow whose orchestration plan is weighed (e.g. evidence-ingest, architecture-review). Absent ⇒ generic orchestration availability.' },
321
+ requested_strategy: { type: 'string', enum: ['orchestrated', 'prompt-only', 'auto'], description: 'Desired execution strategy (default auto).' },
322
+ use_construct: { type: 'boolean', description: 'false ⇒ host-direct (host runs without Construct capabilities). Default true.' },
323
+ host: { type: 'string', description: 'Host/IDE identifier (advisory).' },
324
+ host_model: { type: 'string', description: 'Model the host is currently using, for model resolution.' },
325
+ host_provider: { type: 'string', description: 'Provider family the host uses, when no host_model is given.' },
326
+ requested_tier: { type: 'string', enum: ['reasoning', 'standard', 'fast'], description: 'Desired model tier; overrides the workflow-type hint.' },
327
+ capabilities: { type: 'array', items: { type: 'string' }, description: 'Optional required capabilities; unverifiable ones are returned as warnings.' },
328
+ allow_cross_provider_fallback: { type: 'boolean', description: 'Permit model fallback outside the host provider family (default false).' },
329
+ },
330
+ },
331
+ },
332
+ {
333
+ name: 'orchestration_run',
334
+ outputSchema: { type: 'object' },
335
+ description: 'EXECUTE a real multi-specialist orchestration run and return per-specialist output — the executing counterpart to workflow_invoke (which only plans). For MCP hosts with no subagent primitive (VS Code/Copilot, Cursor), this is how you actually run a specialist chain: the engine owns orchestration, this tool is the thin client (ADR-0022). Solo runs execute in-process — no daemon, no port, no token; a remote/team orchestration service is opt-in via CONSTRUCT_ORCHESTRATION_URL. Default worker backend for MCP-originated runs is `host`: Construct materializes each specialist prompt and the calling host executes it in its own model session (no API credits spent) — the result carries the materialized prompts plus hostInstructions, and results are submitted back via orchestration_task_result. `provider` executes specialists against a configured provider key instead (real API spend); `inline` only prepares tasks (no execution at all).',
336
+ inputSchema: {
337
+ type: 'object',
338
+ required: ['request'],
339
+ properties: {
340
+ request: { type: 'string', description: 'Natural-language description of the work to orchestrate (e.g. "refactor the auth module and review it for security").' },
341
+ workflow_type: { type: 'string', description: 'Optional workflow type to shape the plan (e.g. architecture-review, risk-review).' },
342
+ requested_strategy: { type: 'string', enum: ['orchestrated', 'prompt-only', 'auto'], description: 'Execution strategy (default auto).' },
343
+ worker_backend: { type: 'string', enum: ['inline', 'provider', 'host'], description: 'host materializes prompts for the calling MCP host to execute itself (no API credits; default for MCP-originated runs); provider executes specialists against a configured provider key; inline prepares only.' },
344
+ host: { type: 'string', description: 'Host/IDE identifier (advisory).' },
345
+ host_model: { type: 'string', description: 'Model the host uses, for model resolution.' },
346
+ host_provider: { type: 'string', description: 'Provider family the host uses, for model resolution.' },
347
+ file_count: { type: 'number', description: 'Optional planning hint: number of files in scope.' },
348
+ module_count: { type: 'number', description: 'Optional planning hint: number of modules in scope.' },
349
+ wait: { type: 'boolean', description: 'Wait for the run to reach a terminal state and return task output (default true). false returns the runId immediately to poll with orchestration_status.' },
350
+ timeout_ms: { type: 'number', description: 'Max time to wait when wait=true (default 120000). On timeout the runId is returned to poll.' },
351
+ },
352
+ },
353
+ },
354
+ {
355
+ name: 'web_search',
356
+ outputSchema: { type: 'object' },
357
+ category: 'retrieval',
358
+ description: 'Search the PUBLIC WEB and return CITED results — the only search surface that reaches the open web, kept distinct from knowledge_search / provider_fetch / repo search so it is never conflated or faked. Requires a governed provider (WEB_SEARCH_URL); without one it returns a typed degradation (capability-unavailable) and zero results, never source/repo results dressed as web. Every result carries a verifiable URL, a claim-relative class, and an Admiralty grade with derived confidence (ADR-0017; high reserved for A1/A2/B1).',
359
+ inputSchema: {
360
+ type: 'object',
361
+ required: ['query', 'claim'],
362
+ properties: {
363
+ query: { type: 'string', description: 'The search query string.' },
364
+ claim: { type: 'string', description: 'The claim the results are meant to support — drives claim-relative source classification (ADR-0017).' },
365
+ recency: { type: 'string', description: 'Optional freshness window hint (e.g. "30d").' },
366
+ },
367
+ },
368
+ },
369
+ {
370
+ name: 'orchestration_status',
371
+ outputSchema: { type: 'object' },
372
+ description: 'Inspect orchestration runs on the local Construct daemon: pass run_id for the full record (status, per-task status/executor/output/error), or omit it for a list of recent runs. Fails fast if the daemon is unreachable.',
373
+ inputSchema: {
374
+ type: 'object',
375
+ properties: {
376
+ run_id: { type: 'string', description: 'Run id to fetch. Omit to list recent runs.' },
377
+ limit: { type: 'number', description: 'Max runs to list when run_id is omitted (default 20).' },
378
+ },
379
+ },
380
+ },
381
+ {
382
+ name: 'orchestration_readiness',
383
+ outputSchema: { type: 'object' },
384
+ description: 'Report whether this MCP session has the required Construct orchestration tools attached and reachable now. Returns a pass/fail verdict, typed reasonCode, one next step, required/observed/missing tools, and a redacted diagnostic bundle for support.',
385
+ inputSchema: {
386
+ type: 'object',
387
+ properties: {
388
+ host: { type: 'string', description: 'Host/IDE identifier, if known.' },
389
+ session_id: { type: 'string', description: 'Host session/thread id, if known.' },
390
+ observed_tools: { type: 'array', items: { type: 'string' }, description: 'Optional tool names the host observed in tools/list. When omitted, this server reports its own catalog under observation_scope server-self-report, not host-session.' },
391
+ reachable_tools: { type: 'array', items: { type: 'string' }, description: 'Optional long-tail tools reachable through a gateway enum.' },
392
+ required_tools: { type: 'array', items: { type: 'string' }, description: 'Tools required for orchestration. Defaults to orchestration_policy + orchestration_run.' },
393
+ client_contract_version: { type: 'string', description: 'Client contract version for compatibility checks.' },
394
+ observation_scope: { type: 'string', enum: ['host-session', 'local-probe', 'local-config', 'server-self-report'], description: 'What was observed. Pass host-session only when observed_tools/reachable_tools reflect what the host actually saw in tools/list.' },
395
+ },
396
+ },
397
+ },
398
+ ];
@@ -0,0 +1,25 @@
1
+ /**
2
+ * lib/mcp/tool-definitions.mjs — raw MCP tool schema catalog (hardcoded, non-self-registered tools).
3
+ *
4
+ * Pure data: name/description/inputSchema/outputSchema for every tool that
5
+ * isn't self-registered via lib/mcp/tools/*.mjs's TOOL_DEFS convention (see
6
+ * lib/mcp/tool-registry.mjs). Extracted from lib/mcp/server.mjs so the
7
+ * dispatcher module stays readable; server.mjs applies withSafetyEnvelope
8
+ * (lib/mcp/tool-safety.mjs classifications) to this array at load time.
9
+ *
10
+ * The catalog itself is split across tool-definitions-{project,skills,memory,
11
+ * workflow}.mjs to keep each file under the ~600-line house limit; this
12
+ * module concatenates them back into one array so callers see no difference
13
+ * from a single combined catalog.
14
+ */
15
+ import { TOOL_DEFS_PROJECT } from './tool-definitions-project.mjs';
16
+ import { TOOL_DEFS_SKILLS } from './tool-definitions-skills.mjs';
17
+ import { TOOL_DEFS_MEMORY } from './tool-definitions-memory.mjs';
18
+ import { TOOL_DEFS_WORKFLOW } from './tool-definitions-workflow.mjs';
19
+
20
+ export const RAW_HARDCODED_TOOL_DEFS = [
21
+ ...TOOL_DEFS_PROJECT,
22
+ ...TOOL_DEFS_SKILLS,
23
+ ...TOOL_DEFS_MEMORY,
24
+ ...TOOL_DEFS_WORKFLOW,
25
+ ];
@@ -0,0 +1,107 @@
1
+ /**
2
+ * lib/mcp/tool-registry.mjs — dynamic MCP tool module scanner (LMCP-B5).
3
+ *
4
+ * server.mjs's ALL_TOOL_DEFS/dispatchToolByName stay hand-maintained for the
5
+ * existing 75+ tools (a full migration is a rewrite, not this bridge). New
6
+ * tools instead self-register: a file named `<name>.tool.mjs` under
7
+ * lib/mcp/tools/ (or a caller-supplied directory, e.g. a test fixture) may
8
+ * export:
9
+ *
10
+ * TOOL_DEFS — array of { name, description, inputSchema, outputSchema?, safety }
11
+ * TOOL_HANDLERS — object mapping name -> async (args, opts) => result
12
+ *
13
+ * scanToolModules() imports every `*.tool.mjs` file in the directory and
14
+ * collects these exports. Only files with that suffix are imported, so the
15
+ * existing hand-written tool modules (project.mjs, document.mjs, ...) are
16
+ * never touched by the scan and load exactly as before.
17
+ *
18
+ * `safety` is required on every def — mirrors the fail-loud contract
19
+ * withSafetyEnvelope already applies to the hardcoded catalog (see
20
+ * lib/mcp/tool-safety.mjs): a tool missing one throws immediately, so a
21
+ * newly self-registered tool cannot ship unclassified. A def naming a tool
22
+ * with no matching TOOL_HANDLERS entry throws the same way.
23
+ */
24
+
25
+ import { readdirSync } from 'node:fs';
26
+ import { join, resolve, dirname } from 'node:path';
27
+ import { fileURLToPath, pathToFileURL } from 'node:url';
28
+ import { DEFAULT_OUTPUT_SCHEMA } from './tool-safety.mjs';
29
+
30
+ const HERE = dirname(fileURLToPath(import.meta.url));
31
+
32
+ export const DEFAULT_TOOLS_DIR = resolve(HERE, 'tools');
33
+ export const TOOL_MODULE_SUFFIX = '.tool.mjs';
34
+
35
+ function isPlainObject(value) {
36
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
37
+ }
38
+
39
+ /**
40
+ * scanToolModules({ dir } = {})
41
+ *
42
+ * Returns { defs, handlers, errors }:
43
+ * defs — array of tool definitions (outputSchema defaulted, safety intact)
44
+ * handlers — Map<name, handlerFn>
45
+ * errors — non-fatal import failures (file failed to load as a module)
46
+ *
47
+ * Throws synchronously (not collected in errors) when a loaded module
48
+ * declares a tool without a safety classification, or names a tool with no
49
+ * matching handler — both are registration-shape bugs, not runtime faults,
50
+ * and must fail the same way withSafetyEnvelope already does for the
51
+ * hardcoded catalog.
52
+ */
53
+ export async function scanToolModules({ dir = DEFAULT_TOOLS_DIR } = {}) {
54
+ const defs = [];
55
+ const handlers = new Map();
56
+ const errors = [];
57
+
58
+ let entries;
59
+ try {
60
+ entries = readdirSync(dir, { withFileTypes: true });
61
+ } catch {
62
+ return { defs, handlers, errors };
63
+ }
64
+
65
+ const files = entries
66
+ .filter((e) => e.isFile() && e.name.endsWith(TOOL_MODULE_SUFFIX))
67
+ .map((e) => join(dir, e.name))
68
+ .sort();
69
+
70
+ for (const filePath of files) {
71
+ let mod;
72
+ try {
73
+ mod = await import(pathToFileURL(filePath).href);
74
+ } catch (err) {
75
+ errors.push(`${filePath}: failed to import (${err.message})`);
76
+ continue;
77
+ }
78
+
79
+ const toolDefs = Array.isArray(mod.TOOL_DEFS) ? mod.TOOL_DEFS : null;
80
+ if (!toolDefs) continue;
81
+ const toolHandlers = isPlainObject(mod.TOOL_HANDLERS) ? mod.TOOL_HANDLERS : {};
82
+
83
+ for (const def of toolDefs) {
84
+ if (!def || typeof def.name !== 'string' || !def.name.trim()) {
85
+ throw new Error(`${filePath}: TOOL_DEFS entry missing a string 'name'`);
86
+ }
87
+ if (!isPlainObject(def.safety)) {
88
+ throw new Error(
89
+ `tool-safety: "${def.name}" (${filePath}) has no safety classification — ` +
90
+ `every self-registered tool must export an inline 'safety' block ` +
91
+ `({ class, filesystem, network, process }) on its TOOL_DEFS entry.`
92
+ );
93
+ }
94
+ const handler = toolHandlers[def.name];
95
+ if (typeof handler !== 'function') {
96
+ throw new Error(`${filePath}: TOOL_DEFS declares '${def.name}' but TOOL_HANDLERS has no matching function`);
97
+ }
98
+ if (handlers.has(def.name)) {
99
+ throw new Error(`${filePath}: duplicate self-registered tool name '${def.name}'`);
100
+ }
101
+ defs.push({ ...def, outputSchema: def.outputSchema ?? DEFAULT_OUTPUT_SCHEMA });
102
+ handlers.set(def.name, handler);
103
+ }
104
+ }
105
+
106
+ return { defs, handlers, errors };
107
+ }
@@ -54,6 +54,7 @@ export const TOOL_SAFETY = Object.freeze({
54
54
  efficiency_snapshot: { class: READ, filesystem: 'read', network: 'none', process: 'none' },
55
55
  session_usage: { class: READ, filesystem: 'read', network: 'none', process: 'none' },
56
56
  provider_fetch: { class: WRITE, filesystem: 'write', network: 'fetch', process: 'none' },
57
+ provider_write: { class: DESTRUCTIVE, filesystem: 'write', network: 'fetch', process: 'none' },
57
58
  scope_show: { class: READ, filesystem: 'read', network: 'none', process: 'none' },
58
59
  scope_list: { class: READ, filesystem: 'read', network: 'none', process: 'none' },
59
60
  scope_drafts: { class: READ, filesystem: 'read', network: 'none', process: 'none' },
@@ -0,0 +1,68 @@
1
+ /**
2
+ * lib/mcp/tools/orchestration-delegation-next.tool.mjs — self-registered MCP
3
+ * tool (lib/mcp/tool-registry.mjs) that advances an orchestration-policy
4
+ * route's delegation chain by exactly one step (ADR-0067, construct-rf26.9).
5
+ *
6
+ * orchestration_policy classifies a request into intent/track/specialists/
7
+ * gates and — for a non-immediate track — the full contractChain, for a
8
+ * caller to read and self-sequence. This tool is the flow-engine-backed
9
+ * alternative for the SEQUENCING part specifically: it rebuilds the same
10
+ * deterministic route (routeRequest is a pure function of request/fileCount/
11
+ * moduleCount/introducesContract/explicitDrive) and drives its implied
12
+ * delegation flow (lib/orchestration/delegation-flow.mjs) one checkpointed
13
+ * step at a time, returning only the current specialist's delegation — never
14
+ * the rest of the chain. Call it once per specialist, with the same run_id,
15
+ * until `done` is true; state persists across calls (and across process
16
+ * restarts) via lib/flows/checkpoint.mjs under the machine-scoped state root.
17
+ */
18
+
19
+ import { routeRequest } from '../../orchestration-policy.mjs';
20
+ import { advanceDelegation } from '../../orchestration/delegation-flow.mjs';
21
+
22
+ export const TOOL_DEFS = [
23
+ {
24
+ name: 'orchestration_delegation_next',
25
+ description:
26
+ 'Advance a request\'s delegation chain by exactly one step. Pass the same classification inputs '
27
+ + 'you would give orchestration_policy (request/fileCount/moduleCount/introducesContract/explicitDrive) '
28
+ + 'plus a run_id you mint and keep for this dispatch (e.g. a session or task id). The first call starts '
29
+ + 'the chain and returns the first specialist\'s delegation; each subsequent call with the same run_id '
30
+ + 'returns the next one. Never returns more than the current step — act on currentDelegation only, then '
31
+ + 'call again. `done: true` with `currentDelegation: null` means the chain is exhausted (or the route\'s '
32
+ + 'track resolved to no specialists at all, e.g. immediate).',
33
+ inputSchema: {
34
+ type: 'object',
35
+ required: ['request', 'run_id'],
36
+ properties: {
37
+ request: { type: 'string', description: 'The same request text passed to orchestration_policy.' },
38
+ run_id: { type: 'string', description: 'Caller-chosen id for this dispatch. Reuse it across calls to advance the same chain.' },
39
+ fileCount: { type: 'number', description: 'Approximate number of files involved.' },
40
+ moduleCount: { type: 'number', description: 'Approximate number of modules involved.' },
41
+ introducesContract: { type: 'boolean', description: 'Whether the change introduces a new contract/dependency.' },
42
+ explicitDrive: { type: 'boolean', description: 'Whether drive/full-send mode is explicitly active.' },
43
+ },
44
+ },
45
+ outputSchema: { type: 'object' },
46
+ safety: { class: 'write', filesystem: 'write', network: 'none', process: 'none' },
47
+ },
48
+ ];
49
+
50
+ export async function orchestrationDelegationNext(args = {}, { cwd = process.cwd() } = {}) {
51
+ const { request, run_id: runId } = args;
52
+ if (!request || typeof request !== 'string') return { error: 'Missing "request".' };
53
+ if (!runId || typeof runId !== 'string') return { error: 'Missing "run_id" — mint and reuse one id for this dispatch.' };
54
+
55
+ const route = routeRequest({
56
+ request,
57
+ fileCount: args.fileCount ?? 0,
58
+ moduleCount: args.moduleCount ?? 0,
59
+ introducesContract: args.introducesContract ?? false,
60
+ explicitDrive: args.explicitDrive ?? false,
61
+ });
62
+
63
+ return advanceDelegation(cwd, runId, route);
64
+ }
65
+
66
+ export const TOOL_HANDLERS = {
67
+ orchestration_delegation_next: orchestrationDelegationNext,
68
+ };