@geraldmaron/construct 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (497) hide show
  1. package/README.md +7 -10
  2. package/bin/construct +286 -220
  3. package/bin/construct-postinstall.mjs +0 -21
  4. package/commands/work/optimize-prompts.md +1 -1
  5. package/examples/distribution/sources/adr.md +2 -2
  6. package/examples/seed-observations/decisions.md +1 -1
  7. package/lib/artifact-loop-core.mjs +412 -0
  8. package/lib/artifact-manifest.mjs +6 -0
  9. package/lib/artifact-release-gate.mjs +115 -49
  10. package/lib/audit-rules.mjs +2 -4
  11. package/lib/audit-skills.mjs +32 -20
  12. package/lib/audit-specialists.mjs +44 -26
  13. package/lib/auto-docs.mjs +6 -5
  14. package/lib/brand-prose.mjs +3 -3
  15. package/lib/brand-tokens.mjs +2 -2
  16. package/lib/certification/artifact-fixtures.mjs +4 -1
  17. package/lib/certification/demo-parity.mjs +6 -32
  18. package/lib/certification/real-llm-scenarios.mjs +58 -13
  19. package/lib/certification/role-cards.mjs +7 -6
  20. package/lib/certification/role-overlays.mjs +4 -4
  21. package/lib/certification/runner.mjs +9 -2
  22. package/lib/certification/skill-inventory.mjs +34 -22
  23. package/lib/certification/skill-scenarios.mjs +21 -8
  24. package/lib/certification/specialist-contracts.mjs +4 -3
  25. package/lib/certification/specialist-scenarios.mjs +7 -6
  26. package/lib/certification/status.mjs +5 -4
  27. package/lib/cli-commands.mjs +56 -57
  28. package/lib/comment-lint.mjs +1 -5
  29. package/lib/completions.mjs +20 -2
  30. package/lib/config/legacy-config-migration.mjs +125 -0
  31. package/lib/config/schema.mjs +5 -5
  32. package/lib/config/source-targets.mjs +80 -0
  33. package/lib/contracts/validate.mjs +119 -51
  34. package/lib/decisions/golden.mjs +3 -2
  35. package/lib/decisions/registry.mjs +11 -6
  36. package/lib/demo-project.mjs +188 -0
  37. package/lib/demo-recording.mjs +9 -34
  38. package/lib/demo-script.mjs +2 -2
  39. package/lib/demo-surface.mjs +13 -131
  40. package/lib/demo-tour-renderer.mjs +92 -0
  41. package/lib/demo.mjs +69 -54
  42. package/lib/diagram-export.mjs +63 -14
  43. package/lib/doctor/source-checkout.mjs +3 -4
  44. package/lib/doctor/watchers/consistency.mjs +90 -22
  45. package/lib/doctor/watchers/credential-parity.mjs +97 -0
  46. package/lib/doctor/watchers/mcp-protocol.mjs +1 -1
  47. package/lib/doctor/watchers/service-health.mjs +4 -32
  48. package/lib/document-export.mjs +73 -9
  49. package/lib/document-extract.mjs +10 -198
  50. package/lib/embed/artifact.mjs +2 -3
  51. package/lib/embed/cli.mjs +1 -1
  52. package/lib/embed/config.mjs +1 -2
  53. package/lib/embed/customer-profiles.mjs +1 -1
  54. package/lib/embed/daemon.mjs +5 -6
  55. package/lib/embed/demand-fetch.mjs +114 -2
  56. package/lib/embed/docs-lifecycle.mjs +9 -5
  57. package/lib/embed/intake-metrics.mjs +2 -2
  58. package/lib/embed/notifications.mjs +2 -3
  59. package/lib/embed/recommendation-store.mjs +25 -22
  60. package/lib/embed/role-framing.mjs +4 -9
  61. package/lib/embedded-contract/capability.mjs +4 -2
  62. package/lib/embedded-contract/contract-version.mjs +1 -1
  63. package/lib/env-config.mjs +2 -2
  64. package/lib/flavors/loader.mjs +21 -19
  65. package/lib/graph/build-from-registry.mjs +31 -7
  66. package/lib/graph/staleness.mjs +1 -1
  67. package/lib/headhunt.mjs +82 -35
  68. package/lib/hooks/agent-tracker.mjs +2 -2
  69. package/lib/hooks/config-protection.mjs +1 -1
  70. package/lib/hooks/registry-sync.mjs +3 -3
  71. package/lib/host-capabilities.mjs +5 -5
  72. package/lib/improvement/controller.mjs +2 -2
  73. package/lib/init-unified.mjs +19 -21
  74. package/lib/intake/classify.mjs +26 -0
  75. package/lib/intake/daemon.mjs +2 -3
  76. package/lib/intake/prepare.mjs +10 -3
  77. package/lib/intake/session-prelude.mjs +1 -1
  78. package/lib/intake/tables/creative.mjs +9 -9
  79. package/lib/intake/tables/operations.mjs +4 -4
  80. package/lib/intake/tables/research.mjs +2 -2
  81. package/lib/integrations/intake-integrations.mjs +9 -10
  82. package/lib/knowledge/research-store.mjs +2 -2
  83. package/lib/mcp/server.mjs +104 -61
  84. package/lib/mcp/tool-budget.mjs +1 -46
  85. package/lib/mcp/tool-recovery.mjs +44 -0
  86. package/lib/mcp/tools/artifact-author.mjs +36 -0
  87. package/lib/mcp/tools/find-tool.mjs +86 -0
  88. package/lib/mcp/tools/orchestration-run.mjs +107 -69
  89. package/lib/mcp/tools/project.mjs +4 -3
  90. package/lib/mcp/tools/{profile.mjs → scope.mjs} +54 -52
  91. package/lib/mcp/tools/skills.mjs +39 -22
  92. package/lib/mcp/tools/telemetry.mjs +2 -1
  93. package/lib/mcp/tools/workflow.mjs +1 -1
  94. package/lib/mcp-platform-config.mjs +7 -5
  95. package/lib/migrations/index.mjs +4 -2
  96. package/lib/migrations/v2-unified-registry.mjs +35 -0
  97. package/lib/model-router.mjs +203 -36
  98. package/lib/models/catalog.mjs +25 -9
  99. package/lib/models/execution-capability-profile.mjs +3 -3
  100. package/lib/models/execution-policy.mjs +7 -6
  101. package/lib/models/provider-poll.mjs +18 -4
  102. package/lib/opencode-config.mjs +56 -1
  103. package/lib/opencode-runtime-plugin.mjs +13 -10
  104. package/lib/oracle/artifact-gate.mjs +14 -4
  105. package/lib/oracle/cli.mjs +2 -0
  106. package/lib/oracle/dispatch.mjs +18 -1
  107. package/lib/oracle/execute.mjs +39 -7
  108. package/lib/oracle/index.mjs +1 -1
  109. package/lib/oracle/org-graph.mjs +10 -5
  110. package/lib/oracle/policy.mjs +6 -0
  111. package/lib/oracle/read-model.mjs +103 -6
  112. package/lib/oracle/reconcile.mjs +31 -4
  113. package/lib/oracle/remediation-dispatch.mjs +53 -0
  114. package/lib/oracle/routing.mjs +5 -0
  115. package/lib/oracle/synthesize.mjs +80 -3
  116. package/lib/orchestration/routing-tables.mjs +44 -10
  117. package/lib/orchestration/runtime.mjs +2 -0
  118. package/lib/orchestration/worker.mjs +1 -1
  119. package/lib/orchestration-policy.mjs +351 -62
  120. package/lib/overrides/resolver.mjs +1 -12
  121. package/lib/parity.mjs +37 -11
  122. package/lib/policy/engine.mjs +80 -15
  123. package/lib/prompt-composer.js +51 -15
  124. package/lib/prompt-metadata.mjs +3 -2
  125. package/lib/providers/connection-probe.mjs +58 -0
  126. package/lib/providers/copilot-auth.mjs +1 -1
  127. package/lib/providers/credential-bootstrap.mjs +1 -1
  128. package/lib/providers/op-run.mjs +3 -4
  129. package/lib/providers/secret-resolver.mjs +31 -0
  130. package/lib/publish-tooling.mjs +3 -11
  131. package/lib/publish.mjs +12 -29
  132. package/lib/reconcile/mcp-entry-reconcile.mjs +14 -9
  133. package/lib/reflect.mjs +2 -2
  134. package/lib/registry/agent-manifest.mjs +190 -0
  135. package/lib/registry/assemble.mjs +133 -0
  136. package/lib/registry/catalog.mjs +171 -0
  137. package/lib/registry/cli.mjs +590 -6
  138. package/lib/registry/consolidation.mjs +5 -4
  139. package/lib/registry/docs-sync.mjs +67 -0
  140. package/lib/registry/loader.mjs +147 -0
  141. package/lib/registry/org-io.mjs +76 -0
  142. package/lib/registry/retired-paths.mjs +71 -0
  143. package/lib/registry/surface-map.mjs +5 -7
  144. package/lib/registry/validator.mjs +438 -0
  145. package/lib/research-execution-policy.mjs +173 -0
  146. package/lib/roles/catalog.mjs +4 -9
  147. package/lib/roles/fence.mjs +107 -1
  148. package/lib/roles/flavor-bindings.mjs +68 -0
  149. package/lib/roles/gateway.mjs +140 -29
  150. package/lib/roles/manifest.mjs +22 -13
  151. package/lib/roles/router.mjs +1 -1
  152. package/lib/runtime-env.mjs +1 -1
  153. package/lib/scopes/enrich.mjs +67 -0
  154. package/lib/scopes/hooks.mjs +12 -0
  155. package/lib/{profiles → scopes}/lifecycle.mjs +70 -70
  156. package/lib/scopes/loader.mjs +104 -0
  157. package/lib/scopes/rebrand.mjs +32 -0
  158. package/lib/scopes/research-profile.mjs +16 -0
  159. package/lib/scopes/teams.mjs +98 -0
  160. package/lib/service-manager.mjs +1 -117
  161. package/lib/setup-prompts.mjs +1 -1
  162. package/lib/setup.mjs +17 -28
  163. package/lib/skills/composition-graph.mjs +98 -0
  164. package/lib/skills/router.mjs +80 -0
  165. package/lib/specialist-contracts.mjs +17 -18
  166. package/lib/specialists/postconditions.mjs +2 -2
  167. package/lib/specialists/prompt-schema.mjs +6 -5
  168. package/lib/specialists/roster.mjs +7 -12
  169. package/lib/specialists/schema.mjs +9 -6
  170. package/lib/status.mjs +25 -90
  171. package/lib/storage/file-lock.mjs +6 -3
  172. package/lib/telemetry/skill-calls.mjs +1 -1
  173. package/lib/templates/doc-presentation.mjs +63 -0
  174. package/lib/templates/visual-requirements.mjs +35 -2
  175. package/lib/term-format.mjs +107 -2
  176. package/lib/test-env-setup.mjs +21 -0
  177. package/lib/ui/components.mjs +42 -0
  178. package/lib/ui/glyphs.mjs +58 -0
  179. package/lib/ui/links.mjs +115 -0
  180. package/lib/ui/theme.mjs +108 -0
  181. package/lib/uninstall/uninstall.mjs +2 -1
  182. package/lib/validator.mjs +45 -8
  183. package/lib/validators/skill-effectiveness.mjs +174 -0
  184. package/lib/validators/skills.mjs +1 -1
  185. package/package.json +12 -7
  186. package/personas/construct.md +12 -3
  187. package/platforms/claude/CLAUDE.md +1 -1
  188. package/rules/common/beads-hygiene.md +52 -0
  189. package/rules/common/neurodivergent-output.md +4 -7
  190. package/rules/common/research.md +2 -0
  191. package/scripts/sync-specialists.mjs +260 -49
  192. package/skills/ai/prompt-optimizer.md +3 -3
  193. package/skills/brand/output-vibe.md +48 -0
  194. package/skills/docs/adr-workflow.md +3 -0
  195. package/skills/docs/backlog-proposal-workflow.md +3 -0
  196. package/skills/docs/codebase-research-workflow.md +5 -2
  197. package/skills/docs/customer-profile-workflow.md +3 -0
  198. package/skills/docs/document-ingest-workflow.md +3 -0
  199. package/skills/docs/evidence-ingest-workflow.md +4 -1
  200. package/skills/docs/init-project.md +1 -1
  201. package/skills/docs/prd-workflow.md +1 -1
  202. package/skills/docs/prfaq-workflow.md +3 -0
  203. package/skills/docs/product-intelligence-workflow.md +4 -1
  204. package/skills/docs/product-signal-workflow.md +3 -0
  205. package/skills/docs/research-workflow.md +13 -6
  206. package/skills/docs/runbook-workflow.md +3 -0
  207. package/skills/docs/strategy-workflow.md +3 -0
  208. package/skills/docs/user-research-workflow.md +6 -3
  209. package/skills/operating/orchestration-reference.md +1 -1
  210. package/skills/roles/{engineer.ai.md → ai-engineer.md} +2 -2
  211. package/skills/roles/architect.ai-systems.md +1 -1
  212. package/skills/roles/architect.data.md +1 -1
  213. package/skills/roles/architect.enterprise.md +1 -1
  214. package/skills/roles/architect.integration.md +1 -1
  215. package/skills/roles/architect.md +1 -1
  216. package/skills/roles/architect.platform.md +1 -1
  217. package/skills/roles/{product-manager.business-strategy.md → business-strategist.md} +3 -3
  218. package/skills/roles/data-analyst.experiment.md +1 -1
  219. package/skills/roles/data-analyst.md +1 -1
  220. package/skills/roles/data-analyst.product-intelligence.md +1 -1
  221. package/skills/roles/data-analyst.product.md +1 -1
  222. package/skills/roles/data-analyst.telemetry.md +1 -1
  223. package/skills/roles/{engineer.data.md → data-engineer.md} +2 -2
  224. package/skills/roles/data-engineer.pipeline.md +2 -2
  225. package/skills/roles/data-engineer.vector-retrieval.md +2 -2
  226. package/skills/roles/data-engineer.warehouse.md +2 -2
  227. package/skills/roles/debugger.md +1 -1
  228. package/skills/roles/designer.accessibility.md +1 -1
  229. package/skills/roles/designer.md +1 -1
  230. package/skills/roles/{reviewer.devil-advocate.md → devil-advocate.md} +2 -2
  231. package/skills/roles/{operator.docs.md → docs-keeper.md} +3 -3
  232. package/skills/roles/engineer.md +3 -7
  233. package/skills/roles/{reviewer.evaluator.md → evaluator.md} +2 -2
  234. package/skills/roles/{researcher.explorer.md → explorer.md} +2 -2
  235. package/skills/roles/{operator.md → operations.md} +2 -5
  236. package/skills/roles/orchestrator.md +1 -1
  237. package/skills/roles/{engineer.platform.md → platform-engineer.md} +2 -2
  238. package/skills/roles/product-manager.ai-product.md +1 -1
  239. package/skills/roles/product-manager.enterprise.md +1 -1
  240. package/skills/roles/product-manager.growth.md +1 -2
  241. package/skills/roles/product-manager.md +1 -2
  242. package/skills/roles/product-manager.platform.md +1 -1
  243. package/skills/roles/product-manager.product.md +1 -1
  244. package/skills/roles/qa.ai-eval.md +1 -1
  245. package/skills/roles/qa.api-contract.md +1 -1
  246. package/skills/roles/qa.data-pipeline.md +1 -1
  247. package/skills/roles/qa.md +1 -1
  248. package/skills/roles/qa.web-ui.md +1 -1
  249. package/skills/roles/{operator.release.md → release-manager.md} +3 -3
  250. package/skills/roles/researcher.md +1 -1
  251. package/skills/roles/reviewer.md +1 -1
  252. package/skills/roles/security.ai.md +1 -1
  253. package/skills/roles/security.appsec.md +1 -1
  254. package/skills/roles/security.cloud.md +1 -1
  255. package/skills/roles/security.legal-compliance.md +1 -1
  256. package/skills/roles/security.md +1 -1
  257. package/skills/roles/security.privacy.md +1 -1
  258. package/skills/roles/security.supply-chain.md +1 -1
  259. package/skills/roles/{operator.sre.md → sre.md} +3 -3
  260. package/skills/roles/{qa.test-automation.md → test-automation.md} +2 -2
  261. package/skills/roles/{reviewer.trace.md → trace-reviewer.md} +2 -2
  262. package/skills/roles/{researcher.ux.md → ux-researcher.md} +2 -2
  263. package/skills/routing.json +18 -0
  264. package/skills/routing.md +1 -1
  265. package/specialists/artifact-manifest.json +2 -1
  266. package/specialists/audit-enrichments.json +14 -14
  267. package/specialists/org/contracts/accessibility-to-qa.json +37 -0
  268. package/specialists/org/contracts/any-to-business-strategist.json +57 -0
  269. package/specialists/org/contracts/any-to-debugger.json +38 -0
  270. package/specialists/org/contracts/any-to-designer.json +33 -0
  271. package/specialists/org/contracts/any-to-docs-keeper.json +34 -0
  272. package/specialists/org/contracts/any-to-explorer.json +39 -0
  273. package/specialists/org/contracts/any-to-sre-incident.json +33 -0
  274. package/specialists/org/contracts/any-to-trace-reviewer.json +32 -0
  275. package/specialists/org/contracts/architect-to-ai-engineer.json +32 -0
  276. package/specialists/org/contracts/architect-to-data-engineer.json +52 -0
  277. package/specialists/org/contracts/architect-to-devil-advocate.json +38 -0
  278. package/specialists/org/contracts/architect-to-engineer.json +34 -0
  279. package/specialists/org/contracts/architect-to-evaluator.json +59 -0
  280. package/specialists/org/contracts/architect-to-legal-compliance.json +55 -0
  281. package/specialists/org/contracts/architect-to-operations.json +45 -0
  282. package/specialists/org/contracts/architect-to-platform-engineer.json +42 -0
  283. package/specialists/org/contracts/business-strategist-to-product-manager.json +39 -0
  284. package/specialists/org/contracts/construct-to-orchestrator.json +36 -0
  285. package/specialists/org/contracts/construct-to-rd-lead.json +53 -0
  286. package/specialists/org/contracts/data-analyst-to-product-manager.json +43 -0
  287. package/specialists/org/contracts/data-engineer-to-platform-engineer.json +36 -0
  288. package/specialists/org/contracts/designer-to-accessibility.json +36 -0
  289. package/specialists/org/contracts/engineer-to-qa.json +34 -0
  290. package/specialists/org/contracts/engineer-to-reviewer.json +52 -0
  291. package/specialists/org/contracts/explorer-to-engineer.json +38 -0
  292. package/specialists/org/contracts/legal-compliance-to-release-manager.json +43 -0
  293. package/specialists/org/contracts/platform-engineer-to-engineer.json +31 -0
  294. package/specialists/org/contracts/product-manager-to-architect.json +71 -0
  295. package/specialists/org/contracts/product-manager-to-data-analyst.json +49 -0
  296. package/specialists/org/contracts/product-manager-to-ux-researcher.json +51 -0
  297. package/specialists/org/contracts/qa-to-release-manager.json +42 -0
  298. package/specialists/org/contracts/qa-to-test-automation.json +42 -0
  299. package/specialists/org/contracts/rd-lead-to-architect.json +38 -0
  300. package/specialists/org/contracts/researcher-to-architect.json +40 -0
  301. package/specialists/org/contracts/researcher-to-product-manager.json +57 -0
  302. package/specialists/org/contracts/reviewer-to-security.json +41 -0
  303. package/specialists/org/contracts/sre-to-release-manager.json +36 -0
  304. package/specialists/org/contracts/test-automation-to-engineer.json +34 -0
  305. package/specialists/org/contracts/trace-reviewer-to-sre.json +41 -0
  306. package/specialists/org/contracts/user-to-construct.json +30 -0
  307. package/specialists/org/groups/engineering-group.json +43 -0
  308. package/specialists/org/groups/governance-group.json +38 -0
  309. package/specialists/org/groups/operations-group.json +41 -0
  310. package/specialists/org/groups/product-group.json +46 -0
  311. package/specialists/org/groups/quality-group.json +42 -0
  312. package/specialists/org/groups/strategy-group.json +41 -0
  313. package/specialists/org/policies/action-approval.json +13 -0
  314. package/specialists/org/policies/agents-routing.json +13 -0
  315. package/specialists/org/policies/architecture.json +20 -0
  316. package/specialists/org/policies/bash-safety.json +13 -0
  317. package/specialists/org/policies/beads-hygiene.json +13 -0
  318. package/specialists/org/policies/bootstrap-state.json +13 -0
  319. package/specialists/org/policies/code-review.json +13 -0
  320. package/specialists/org/policies/coding-style.json +13 -0
  321. package/specialists/org/policies/comments.json +13 -0
  322. package/specialists/org/policies/commit-approval.json +13 -0
  323. package/specialists/org/policies/contract-preconditions.json +13 -0
  324. package/specialists/org/policies/deployment.json +20 -0
  325. package/specialists/org/policies/description.json +14 -0
  326. package/specialists/org/policies/design-approval.json +19 -0
  327. package/specialists/org/policies/doc-ownership.json +13 -0
  328. package/specialists/org/policies/file-path-fence.json +13 -0
  329. package/specialists/org/policies/framing.json +13 -0
  330. package/specialists/org/policies/git-workflow.json +13 -0
  331. package/specialists/org/policies/incident-response.json +15 -0
  332. package/specialists/org/policies/intake-triage.json +15 -0
  333. package/specialists/org/policies/neurodivergent-output.json +13 -0
  334. package/specialists/org/policies/no-fabrication.json +13 -0
  335. package/specialists/org/policies/patterns.json +13 -0
  336. package/specialists/org/policies/quality-gate-approval.json +17 -0
  337. package/specialists/org/policies/release-gates.json +13 -0
  338. package/specialists/org/policies/research-evidence.json +13 -0
  339. package/specialists/org/policies/review-before-change.json +13 -0
  340. package/specialists/org/policies/rollback.json +15 -0
  341. package/specialists/org/policies/scope-change.json +20 -0
  342. package/specialists/org/policies/secret-scan.json +13 -0
  343. package/specialists/org/policies/security-approval.json +17 -0
  344. package/specialists/org/policies/security.json +13 -0
  345. package/specialists/org/policies/session-efficiency.json +13 -0
  346. package/specialists/org/policies/skill-routing.json +13 -0
  347. package/specialists/org/policies/strategic-prioritization.json +17 -0
  348. package/specialists/org/policies/testing.json +13 -0
  349. package/specialists/org/policies/tool-invisibility.json +14 -0
  350. package/specialists/org/scopes/creative.json +54 -0
  351. package/specialists/org/scopes/operations.json +51 -0
  352. package/specialists/org/scopes/research.json +60 -0
  353. package/specialists/org/scopes/rnd.json +81 -0
  354. package/specialists/org/specialists/cx-accessibility.json +69 -0
  355. package/specialists/org/specialists/cx-ai-engineer.json +75 -0
  356. package/specialists/org/specialists/cx-architect.json +89 -0
  357. package/specialists/org/specialists/cx-business-strategist.json +72 -0
  358. package/specialists/org/specialists/cx-data-analyst.json +68 -0
  359. package/specialists/org/specialists/cx-data-engineer.json +71 -0
  360. package/specialists/org/specialists/cx-debugger.json +75 -0
  361. package/specialists/org/specialists/cx-designer.json +85 -0
  362. package/specialists/org/specialists/cx-devil-advocate.json +71 -0
  363. package/specialists/org/specialists/cx-docs-keeper.json +82 -0
  364. package/specialists/org/specialists/cx-engineer.json +106 -0
  365. package/specialists/org/specialists/cx-evaluator.json +69 -0
  366. package/specialists/org/specialists/cx-explorer.json +69 -0
  367. package/specialists/org/specialists/cx-legal-compliance.json +74 -0
  368. package/specialists/org/specialists/cx-operations.json +72 -0
  369. package/specialists/org/specialists/cx-oracle.json +46 -0
  370. package/specialists/org/specialists/cx-orchestrator.json +81 -0
  371. package/specialists/org/specialists/cx-platform-engineer.json +80 -0
  372. package/specialists/org/specialists/cx-product-manager.json +102 -0
  373. package/specialists/org/specialists/cx-qa.json +79 -0
  374. package/specialists/org/specialists/cx-rd-lead.json +73 -0
  375. package/specialists/org/specialists/cx-release-manager.json +77 -0
  376. package/specialists/org/specialists/cx-researcher.json +82 -0
  377. package/specialists/org/specialists/cx-reviewer.json +71 -0
  378. package/specialists/org/specialists/cx-security.json +91 -0
  379. package/specialists/org/specialists/cx-sre.json +94 -0
  380. package/specialists/org/specialists/cx-test-automation.json +69 -0
  381. package/specialists/org/specialists/cx-trace-reviewer.json +69 -0
  382. package/specialists/org/specialists/cx-ux-researcher.json +68 -0
  383. package/specialists/org/teams/accessibility-team.json +39 -0
  384. package/specialists/org/teams/design-team.json +40 -0
  385. package/specialists/org/teams/engineering-team.json +50 -0
  386. package/specialists/org/teams/governance-team.json +41 -0
  387. package/specialists/org/teams/operations-team.json +46 -0
  388. package/specialists/org/teams/product-management-team.json +45 -0
  389. package/specialists/org/teams/quality-team.json +49 -0
  390. package/specialists/org/teams/research-team.json +39 -0
  391. package/specialists/org/teams/strategy-team.json +48 -0
  392. package/specialists/org/teams/ux-research-team.json +39 -0
  393. package/specialists/prompts/_shared/validation-contract.md +1 -1
  394. package/specialists/prompts/_team-template.md +10 -0
  395. package/specialists/prompts/cx-accessibility.md +1 -0
  396. package/specialists/prompts/cx-ai-engineer.md +1 -1
  397. package/specialists/prompts/cx-business-strategist.md +1 -1
  398. package/specialists/prompts/cx-data-engineer.md +1 -1
  399. package/specialists/prompts/cx-designer.md +1 -0
  400. package/specialists/prompts/cx-devil-advocate.md +1 -1
  401. package/specialists/prompts/cx-docs-keeper.md +1 -1
  402. package/specialists/prompts/cx-evaluator.md +1 -1
  403. package/specialists/prompts/cx-explorer.md +1 -1
  404. package/specialists/prompts/cx-operations.md +1 -1
  405. package/specialists/prompts/cx-oracle.md +7 -3
  406. package/specialists/prompts/cx-orchestrator.md +17 -1
  407. package/specialists/prompts/cx-platform-engineer.md +1 -1
  408. package/specialists/prompts/cx-product-manager.md +2 -0
  409. package/specialists/prompts/cx-release-manager.md +1 -1
  410. package/specialists/prompts/cx-researcher.md +7 -4
  411. package/specialists/prompts/cx-sre.md +1 -1
  412. package/specialists/prompts/cx-test-automation.md +2 -2
  413. package/specialists/prompts/cx-trace-reviewer.md +3 -3
  414. package/specialists/prompts/cx-ux-researcher.md +2 -1
  415. package/templates/demos/scripts/architecture-review-adr.json +30 -0
  416. package/templates/demos/scripts/capability-contract.json +25 -0
  417. package/templates/demos/scripts/intake-triage.json +25 -0
  418. package/templates/demos/scripts/profile-doctor-health.json +25 -0
  419. package/templates/demos/tapes/agentic-platforms-prd.tape +2 -2
  420. package/templates/demos/tapes/architecture-review-adr.tape +44 -0
  421. package/templates/demos/tapes/capability-contract.tape +39 -0
  422. package/templates/demos/tapes/intake-triage.tape +39 -0
  423. package/templates/demos/tapes/profile-doctor-health.tape +39 -0
  424. package/templates/distribution/construct-brand.typ +23 -18
  425. package/templates/distribution/construct-decision.typ +1 -1
  426. package/templates/distribution/construct-pdf.typ +1 -1
  427. package/templates/distribution/construct-prd.typ +1 -1
  428. package/templates/distribution/construct-research.typ +1 -1
  429. package/templates/distribution/mermaid-puppeteer.json +8 -0
  430. package/templates/docs/persona-artifact.md +1 -1
  431. package/templates/docs/prd.md +6 -0
  432. package/lib/boundary.mjs +0 -127
  433. package/lib/certification/dashboard-api.mjs +0 -71
  434. package/lib/chat/cli.mjs +0 -333
  435. package/lib/chat/command-suggest.mjs +0 -161
  436. package/lib/chat/commands.mjs +0 -215
  437. package/lib/chat/config.mjs +0 -142
  438. package/lib/chat/context-compactor.mjs +0 -250
  439. package/lib/chat/context-continuation.mjs +0 -253
  440. package/lib/chat/continuation-source.mjs +0 -58
  441. package/lib/chat/demo-guide.mjs +0 -61
  442. package/lib/chat/design-tokens.mjs +0 -91
  443. package/lib/chat/desktop-binary.mjs +0 -81
  444. package/lib/chat/desktop-build.mjs +0 -130
  445. package/lib/chat/desktop-launcher.mjs +0 -133
  446. package/lib/chat/evidence.mjs +0 -145
  447. package/lib/chat/export.mjs +0 -74
  448. package/lib/chat/harness/driver.mjs +0 -91
  449. package/lib/chat/list-picker.mjs +0 -112
  450. package/lib/chat/model-picker.mjs +0 -356
  451. package/lib/chat/openrouter-fallback.mjs +0 -151
  452. package/lib/chat/permission-prompt.mjs +0 -33
  453. package/lib/chat/picker-catalog.mjs +0 -45
  454. package/lib/chat/policy-telemetry.mjs +0 -34
  455. package/lib/chat/present.mjs +0 -246
  456. package/lib/chat/session-context.mjs +0 -39
  457. package/lib/chat/session-persist.mjs +0 -73
  458. package/lib/chat/session-restore.mjs +0 -71
  459. package/lib/chat/session-settings.mjs +0 -53
  460. package/lib/chat/system-prompt.mjs +0 -52
  461. package/lib/chat/transparency.mjs +0 -93
  462. package/lib/chat/tui/color-scheme.mjs +0 -42
  463. package/lib/chat/tui/markdown.mjs +0 -123
  464. package/lib/chat/tui/presentation.mjs +0 -100
  465. package/lib/chat/tui/render.mjs +0 -500
  466. package/lib/chat/tui/turn-block.mjs +0 -284
  467. package/lib/chat/tui/turn-present.mjs +0 -18
  468. package/lib/chat/tui/turn-state.mjs +0 -88
  469. package/lib/chat/tui/usage.mjs +0 -122
  470. package/lib/chat/web-commands.mjs +0 -146
  471. package/lib/chat/web-launcher.mjs +0 -63
  472. package/lib/chat/web-picker-keys.mjs +0 -46
  473. package/lib/chat/web-session.mjs +0 -159
  474. package/lib/config/alias.mjs +0 -57
  475. package/lib/dashboard-demo.mjs +0 -71
  476. package/lib/dashboard-static.mjs +0 -175
  477. package/lib/install/desktop-binary-download.mjs +0 -88
  478. package/lib/profiles/loader.mjs +0 -123
  479. package/lib/profiles/rebrand.mjs +0 -46
  480. package/lib/server/auth.mjs +0 -169
  481. package/lib/server/chat-loop.mjs +0 -622
  482. package/lib/server/chat.mjs +0 -336
  483. package/lib/server/cors.mjs +0 -77
  484. package/lib/server/csrf.mjs +0 -103
  485. package/lib/server/demo-preview.mjs +0 -63
  486. package/lib/server/index.mjs +0 -2641
  487. package/lib/server/insights.mjs +0 -780
  488. package/lib/server/langfuse-login.mjs +0 -58
  489. package/lib/server/rate-limit.mjs +0 -93
  490. package/lib/server/telemetry-login.mjs +0 -100
  491. package/lib/server/webhook.mjs +0 -512
  492. package/specialists/contracts.json +0 -1032
  493. package/specialists/contracts.schema.json +0 -83
  494. package/specialists/policy-inventory.json +0 -188
  495. package/specialists/registry.json +0 -1412
  496. package/specialists/role-manifests.json +0 -217
  497. package/specialists/teams.json +0 -94
@@ -93,6 +93,20 @@ function pruneRaisedIssues(projectDir, { dryRun = false } = {}) {
93
93
 
94
94
  const BARE_GOAL_FIELD_LABELS = ['intent', 'workCategory', 'riskFlags', 'acceptanceCriteria'];
95
95
 
96
+ const RESEARCHER_PROBE_MISSING = [
97
+ 'artifact missing required field: question',
98
+ 'artifact missing required field: method',
99
+ 'artifact missing required field: sources',
100
+ 'artifact missing required field: findings',
101
+ 'artifact missing required field: confidence',
102
+ ];
103
+
104
+ const A11Y_PROBE_MISSING = [
105
+ 'artifact missing required field: findings',
106
+ 'artifact missing required field: wcagCriterion',
107
+ 'artifact missing required field: userImpact',
108
+ ];
109
+
96
110
  function missingBareGoalConstructFields(missing) {
97
111
  if (!Array.isArray(missing) || missing.length !== BARE_GOAL_FIELD_LABELS.length) return false;
98
112
  return BARE_GOAL_FIELD_LABELS.every((field) =>
@@ -107,6 +121,19 @@ function isBareGoalConstructViolation(row) {
107
121
  return Array.isArray(keys) && keys.length === 1 && keys[0] === 'goal';
108
122
  }
109
123
 
124
+ function isEmptyProbeViolation(row, contractId, expectedMissing) {
125
+ if (row?.contractId !== contractId) return false;
126
+ const keys = row.packet_keys ?? row.packetKeys;
127
+ if (!Array.isArray(keys) || keys.length !== 0) return false;
128
+ return JSON.stringify(row.missing) === JSON.stringify(expectedMissing);
129
+ }
130
+
131
+ function isDevSessionContractNoise(row) {
132
+ return isBareGoalConstructViolation(row)
133
+ || isEmptyProbeViolation(row, 'researcher-to-architect', RESEARCHER_PROBE_MISSING)
134
+ || isEmptyProbeViolation(row, 'accessibility-to-qa', A11Y_PROBE_MISSING);
135
+ }
136
+
110
137
  /**
111
138
  * @param {string} projectDir
112
139
  * @returns {{ shouldSupersede: boolean, recentCount: number, reason: string }}
@@ -116,18 +143,18 @@ export function planContractViolationSupersede(projectDir) {
116
143
  if (!recent.length) {
117
144
  return { shouldSupersede: false, recentCount: 0, reason: 'no recent contract violations' };
118
145
  }
119
- const allBareGoal = recent.every(isBareGoalConstructViolation);
120
- if (!allBareGoal) {
146
+ const allDevSessionNoise = recent.every(isDevSessionContractNoise);
147
+ if (!allDevSessionNoise) {
121
148
  return {
122
149
  shouldSupersede: false,
123
150
  recentCount: recent.length,
124
- reason: 'recent violations include non-bare-goal construct-to-orchestrator or other contracts',
151
+ reason: 'recent violations include non-probe contract failures',
125
152
  };
126
153
  }
127
154
  return {
128
155
  shouldSupersede: true,
129
156
  recentCount: recent.length,
130
- reason: 'historical bare-goal construct-to-orchestrator violations superseded after handoff enrichment fix',
157
+ reason: 'dev-session contract probes superseded (bare-goal construct, empty researcher/a11y packets)',
131
158
  };
132
159
  }
133
160
 
@@ -0,0 +1,53 @@
1
+ /**
2
+ * lib/oracle/remediation-dispatch.mjs — static vs swarm dispatch for Oracle remediation.
3
+ *
4
+ * Seeds orchestration-policy teamRouting with gap/action remediation specialists.
5
+ * Swarm when involvedTeams.length > 1; static when a single team owns the work.
6
+ */
7
+
8
+ import { classifyIntent, teamRoutingForSpecialists } from '../orchestration-policy.mjs';
9
+ import { routeGap, routeAction } from './routing.mjs';
10
+
11
+ function remediationText(item) {
12
+ return String(item.detail ?? item.summary ?? item.id ?? 'Oracle remediation');
13
+ }
14
+
15
+ function seededSpecialists(item) {
16
+ const route = item.remediationRoute ?? (item.kind ? routeAction(item.kind) : routeGap(item));
17
+ return [route.primary, route.secondary].filter(Boolean);
18
+ }
19
+
20
+ /**
21
+ * @param {object} item — gap or recommended action with optional remediationRoute
22
+ * @param {{ projectDir?: string, cwd?: string }} [opts]
23
+ * @returns {{ mode: 'static'|'swarm', primary: string, specialists: string[], teamRouting: object }}
24
+ */
25
+ export function resolveRemediationDispatch(item, { projectDir, cwd } = {}) {
26
+ const route = item.remediationRoute ?? (item.kind ? routeAction(item.kind) : routeGap(item));
27
+ const primary = route.primary;
28
+ const specialists = seededSpecialists(item);
29
+ const request = remediationText(item);
30
+ const intent = classifyIntent(request);
31
+ const teamRouting = teamRoutingForSpecialists(specialists, {
32
+ intent,
33
+ request,
34
+ cwd: cwd ?? projectDir ?? null,
35
+ });
36
+
37
+ const involvedTeams = teamRouting.involvedTeams ?? [];
38
+ if (involvedTeams.length <= 1) {
39
+ return {
40
+ mode: 'static',
41
+ primary,
42
+ specialists: [primary],
43
+ teamRouting,
44
+ };
45
+ }
46
+
47
+ return {
48
+ mode: 'swarm',
49
+ primary,
50
+ specialists: Array.from(new Set(specialists)),
51
+ teamRouting,
52
+ };
53
+ }
@@ -34,6 +34,11 @@ const GAP_ROUTES = {
34
34
  'dependency-graph-stale': { primary: 'cx-platform-engineer', secondary: null },
35
35
  'matrix-coverage-gap': { primary: 'cx-architect', secondary: 'cx-qa' },
36
36
  'impact-untested': { primary: 'cx-qa', secondary: 'cx-engineer' },
37
+ // Team governance signals — route to rd-lead for strategic resolution
38
+ 'team-understaffed': { primary: 'cx-rd-lead', secondary: 'cx-orchestrator' },
39
+ 'escalation-path-broken': { primary: 'cx-rd-lead', secondary: 'cx-architect' },
40
+ 'team-decision-violation': { primary: 'cx-rd-lead', secondary: 'cx-orchestrator' },
41
+ 'cross-team-handoff-blocked': { primary: 'cx-rd-lead', secondary: null },
37
42
  };
38
43
 
39
44
  const ACTION_ROUTES = {
@@ -5,6 +5,8 @@
5
5
 
6
6
  import { orgGraphToGapHints } from './org-graph.mjs';
7
7
  import { routeAction, routeGap, signOffMetadata } from './routing.mjs';
8
+ import { resolveRemediationDispatch } from './remediation-dispatch.mjs';
9
+ import { isConstructPackageRepo } from '../host-disposition.mjs';
8
10
 
9
11
  const LOW_SUCCESS_RATE = 0.6;
10
12
 
@@ -224,7 +226,8 @@ export function synthesizeVerdict(readModel) {
224
226
  }
225
227
 
226
228
  const dupLanes = readModel.structure?.duplicateLanes ?? [];
227
- if (dupLanes.length > 0) {
229
+ const skipStructureSprawl = isConstructPackageRepo(readModel.projectDir);
230
+ if (dupLanes.length > 0 && !skipStructureSprawl) {
228
231
  gaps.push(gap(
229
232
  'structure-sprawl',
230
233
  'medium',
@@ -259,11 +262,13 @@ export function synthesizeVerdict(readModel) {
259
262
 
260
263
  const artifactGate = readModel.artifactGate ?? {};
261
264
  if (artifactGate.specialistAudit?.present && !artifactGate.specialistAudit.pass) {
265
+ const auditDetail = artifactGate.specialistAudit.error
266
+ ?? `${artifactGate.specialistAudit.crossCheckCount} issue(s)`;
262
267
  gaps.push(gap(
263
268
  'specialist-audit-drift',
264
269
  'high',
265
270
  'artifact-manifest',
266
- `Specialist audit cross-check failed (${artifactGate.specialistAudit.crossCheckCount} issue(s))`,
271
+ `Specialist audit cross-check failed (${auditDetail})`,
267
272
  ));
268
273
  recommendedActions.push(action(
269
274
  'registry-validate',
@@ -285,7 +290,7 @@ export function synthesizeVerdict(readModel) {
285
290
  ));
286
291
  }
287
292
 
288
- if ((artifactGate.reviewerGapCount ?? 0) > 0) {
293
+ if ((artifactGate.reviewerGapCount ?? 0) > 0 && artifactGate.reviewerGateArmed !== false) {
289
294
  gaps.push(gap(
290
295
  'artifact-reviewer-gap',
291
296
  'medium',
@@ -340,6 +345,70 @@ export function synthesizeVerdict(readModel) {
340
345
  }
341
346
  }
342
347
 
348
+ // Team governance signals from unified registry
349
+ const teamGov = readModel.teamGovernance ?? { present: false, teams: {} };
350
+ if (teamGov.present) {
351
+ const understaffedTeams = Object.values(teamGov.teams ?? {}).filter((t) => t.understaffed);
352
+ if (understaffedTeams.length > 0) {
353
+ gaps.push(gap(
354
+ 'team-understaffed',
355
+ 'high',
356
+ 'team-governance',
357
+ `${understaffedTeams.length} team(s) understaffed: ${understaffedTeams.map((t) => t.id).join(', ')}`,
358
+ ));
359
+ recommendedActions.push(action(
360
+ 'specialist-review',
361
+ 'Review team staffing gaps and escalate to rd-lead for resolution',
362
+ { teams: understaffedTeams.map((t) => ({ id: t.id, name: t.name })) },
363
+ ));
364
+ }
365
+
366
+ const brokenEscalations = Object.values(teamGov.teams ?? {}).filter((t) => t.escalationPathBroken);
367
+ if (brokenEscalations.length > 0) {
368
+ gaps.push(gap(
369
+ 'escalation-path-broken',
370
+ 'high',
371
+ 'team-governance',
372
+ `${brokenEscalations.length} team(s) have broken escalation path: ${brokenEscalations.map((t) => t.id).join(', ')}`,
373
+ ));
374
+ recommendedActions.push(action(
375
+ 'registry-validate',
376
+ 'Validate and repair team escalation paths in unified registry',
377
+ { teams: brokenEscalations.map((t) => t.id) },
378
+ ));
379
+ }
380
+
381
+ const ownerlessTeams = Object.values(teamGov.teams ?? {}).filter((t) => !t.ownerExists);
382
+ if (ownerlessTeams.length > 0) {
383
+ gaps.push(gap(
384
+ 'team-decision-violation',
385
+ 'high',
386
+ 'team-governance',
387
+ `${ownerlessTeams.length} team(s) missing owner specialist: ${ownerlessTeams.map((t) => `${t.id} (owner: ${t.owner})`).join(', ')}`,
388
+ ));
389
+ recommendedActions.push(action(
390
+ 'specialist-review',
391
+ 'Assign specialists to team owner roles or update registry',
392
+ { teams: ownerlessTeams.map((t) => ({ id: t.id, missingOwner: t.owner })) },
393
+ ));
394
+ }
395
+
396
+ const blockedHandoffs = teamGov.crossTeamHandoffsBlocked ?? [];
397
+ if (blockedHandoffs.length > 0) {
398
+ gaps.push(gap(
399
+ 'cross-team-handoff-blocked',
400
+ 'high',
401
+ 'team-governance',
402
+ `${blockedHandoffs.length} cross-team handoff(s) blocked on an unstaffed approver team: ${blockedHandoffs.map((h) => `${h.contract} (needs ${h.blockedBy.join(', ')})`).join('; ')}`,
403
+ ));
404
+ recommendedActions.push(action(
405
+ 'specialist-review',
406
+ 'Staff the required approver team(s) or relax the cross-team approval requirement so the handoff can complete',
407
+ { handoffs: blockedHandoffs },
408
+ ));
409
+ }
410
+ }
411
+
343
412
  for (const hint of orgGraphToGapHints(readModel.orgGraph ?? {})) {
344
413
  if (!gaps.some((g) => g.id === hint.id)) gaps.push(hint);
345
414
  if (hint.id === 'workflow-misaligned') {
@@ -365,6 +434,10 @@ export function synthesizeVerdict(readModel) {
365
434
  secondary: route.secondary ?? null,
366
435
  gateType: route.gateType ?? null,
367
436
  };
437
+ const dispatch = resolveRemediationDispatch(g, { projectDir: readModel.projectDir });
438
+ g.remediationRoute.mode = dispatch.mode;
439
+ g.remediationRoute.specialists = dispatch.specialists;
440
+ g.remediationRoute.teamRouting = dispatch.teamRouting;
368
441
  }
369
442
  for (const a of recommendedActions) {
370
443
  const route = routeAction(a.kind);
@@ -372,6 +445,10 @@ export function synthesizeVerdict(readModel) {
372
445
  primary: route.primary,
373
446
  gateType: route.gateType ?? null,
374
447
  };
448
+ const dispatch = resolveRemediationDispatch(a, { projectDir: readModel.projectDir });
449
+ a.remediationRoute.mode = dispatch.mode;
450
+ a.remediationRoute.specialists = dispatch.specialists;
451
+ a.remediationRoute.teamRouting = dispatch.teamRouting;
375
452
  }
376
453
 
377
454
  let verdict = 'healthy';
@@ -2,7 +2,7 @@
2
2
  * lib/orchestration/routing-tables.mjs — declarative routing resolver.
3
3
  *
4
4
  * Reads specialist subscriptions, doc-artifact ownership, and watch-condition
5
- * references from specialists/registry.json (with optional .cx/specialists/
5
+ * references from specialists/org (with optional .cx/specialists/
6
6
  * overlays) and exposes the forward lookups the orchestration layer needs.
7
7
  *
8
8
  * The resolver is the single source of truth for event/doc/watch routing.
@@ -19,10 +19,8 @@
19
19
 
20
20
  import { readFileSync, existsSync, readdirSync } from 'node:fs';
21
21
  import { join } from 'node:path';
22
- import { fileURLToPath } from 'node:url';
23
22
  import { findProjectRoot } from '../project-root.mjs';
24
-
25
- const REGISTRY_PATH = fileURLToPath(new URL('../../specialists/registry.json', import.meta.url));
23
+ import { loadRegistry, clearCache } from '../registry/loader.mjs';
26
24
 
27
25
  // Watch-condition predicates. Each is a pure function from requestSignals
28
26
  // (see orchestration-policy.requestSignals) to boolean. Registry entries
@@ -65,9 +63,10 @@ function loadOverlays() {
65
63
  }
66
64
 
67
65
  function buildTables() {
68
- const registry = readJsonSafe(REGISTRY_PATH);
69
- if (!registry || !Array.isArray(registry.specialists)) {
70
- throw new Error('routing-tables: registry.json missing or malformed');
66
+ clearCache();
67
+ const registry = loadRegistry();
68
+ if (!registry || typeof registry.specialists !== 'object') {
69
+ throw new Error('routing-tables: assembled registry missing or malformed');
71
70
  }
72
71
 
73
72
  // Forward maps. Last writer wins for overlays; the resolver validates
@@ -83,8 +82,8 @@ function buildTables() {
83
82
 
84
83
  function apply(entry, source) {
85
84
  const cxId = entry.name?.startsWith('cx-') ? entry.name : `cx-${entry.name}`;
86
- if (Array.isArray(entry.subscriptions)) {
87
- for (const event of entry.subscriptions) {
85
+ if (Array.isArray(entry.events || entry.subscriptions)) {
86
+ for (const event of (entry.events || entry.subscriptions)) {
88
87
  if (eventToOwner.has(event) && eventToOwner.get(event) !== cxId && source === 'registry') {
89
88
  errors.push(`duplicate event ownership: ${event} → ${eventToOwner.get(event)} vs ${cxId}`);
90
89
  }
@@ -113,7 +112,7 @@ function buildTables() {
113
112
  }
114
113
  }
115
114
 
116
- for (const entry of registry.specialists) apply(entry, 'registry');
115
+ for (const entry of Object.values(registry.specialists)) apply(entry, 'registry');
117
116
  for (const overlay of loadOverlays()) apply(overlay, 'overlay');
118
117
 
119
118
  if (errors.length > 0) {
@@ -171,6 +170,41 @@ export function knownWatchers() {
171
170
  return Object.keys(WATCHERS);
172
171
  }
173
172
 
173
+ /**
174
+ * Get the team id for a specialist.
175
+ * Returns the team id or null if specialist not found.
176
+ */
177
+ export function teamForSpecialist(specialistId) {
178
+ if (!specialistId) return null;
179
+ const registry = loadRegistry();
180
+ if (!registry?.specialists) return null;
181
+ const cxId = specialistId.startsWith('cx-') ? specialistId : `cx-${specialistId}`;
182
+ return registry.specialists[cxId]?.team || null;
183
+ }
184
+
185
+ /**
186
+ * Get all specialists in a team.
187
+ * Returns array of specialist ids (with cx- prefix).
188
+ */
189
+ export function specialistsInTeam(teamId) {
190
+ if (!teamId) return [];
191
+ const registry = loadRegistry();
192
+ if (!registry?.specialists) return [];
193
+ return Object.entries(registry.specialists)
194
+ .filter(([, s]) => s.team === teamId)
195
+ .map(([id]) => id);
196
+ }
197
+
198
+ /**
199
+ * Get team definition by id.
200
+ * Returns team object or null if not found.
201
+ */
202
+ export function getTeamById(teamId) {
203
+ if (!teamId) return null;
204
+ const registry = loadRegistry();
205
+ return registry?.teams?.[teamId] || null;
206
+ }
207
+
174
208
  export function _resetCache() {
175
209
  cache = null;
176
210
  }
@@ -185,6 +185,8 @@ export async function planRun(request = {}, { env = process.env, cwd = process.c
185
185
  intent: route.intent,
186
186
  track: route.track,
187
187
  specialists: route.specialists || [],
188
+ suggestedWorkflowType: route.suggestedWorkflowType || null,
189
+ researchExecutionPolicy: route.researchExecutionPolicy || null,
188
190
  dispatchPlan: route.dispatchPlan,
189
191
  contractChain: (route.contractChain || []).map((e) => ({ id: e.contract?.id, producer: e.contract?.producer, consumer: e.contract?.consumer, stage: e.stage })),
190
192
  },
@@ -95,7 +95,7 @@ function anthropicThinkingConfig(model) {
95
95
 
96
96
  // Key resolution delegates to the shared secret resolver so env, the dotenv
97
97
  // files, shell rc exports, and 1Password op:// references all behave identically
98
- // across the worker, the chat engine, and the router. allowAmbient stays the
98
+ // across the worker and router. allowAmbient stays the
99
99
  // hermetic switch: a caller that injects its own env (embedded callers, tests)
100
100
  // suppresses file/rc discovery so a developer's real key never bleeds into a run.
101
101