@geraldmaron/construct 1.4.2 → 1.5.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 (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 +55 -38
  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 +261 -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 +103 -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,86 @@
1
+ /**
2
+ * lib/writes/sent-log.mjs — durable JSONL record of executed external writes.
3
+ *
4
+ * WriteSentLog persists idempotency keys and outcomes so a retried or duplicate
5
+ * write-intent is deduplicated rather than re-executed against the remote system.
6
+ */
7
+
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+
11
+ export class WriteSentLog {
12
+ #records = [];
13
+ #persistPath = null;
14
+
15
+ constructor({ persistPath } = {}) {
16
+ if (persistPath) {
17
+ this.#persistPath = persistPath;
18
+ this.#load();
19
+ }
20
+ }
21
+
22
+ record(entry) {
23
+ const rec = {
24
+ idempotencyKey: entry.idempotencyKey,
25
+ writeType: entry.writeType,
26
+ provider: entry.provider,
27
+ sentAt: entry.sentAt || new Date().toISOString(),
28
+ completedAt: entry.completedAt || null,
29
+ status: entry.status || 'pending',
30
+ externalUrl: entry.externalUrl || null,
31
+ externalId: entry.externalId || null,
32
+ result: entry.result || null,
33
+ error: entry.error || null,
34
+ };
35
+ this.#records.push(rec);
36
+ this.#persist();
37
+ return rec;
38
+ }
39
+
40
+ findByIdempotencyKey(key) {
41
+ let found = null;
42
+ for (const r of this.#records) {
43
+ if (r.idempotencyKey === key) found = r;
44
+ }
45
+ return found;
46
+ }
47
+
48
+ list({ provider, status, since } = {}) {
49
+ let results = [...this.#records];
50
+ if (provider) results = results.filter(r => r.provider === provider);
51
+ if (status) results = results.filter(r => r.status === status);
52
+ if (since) results = results.filter(r => new Date(r.sentAt) >= new Date(since));
53
+ return results;
54
+ }
55
+
56
+ pruneOlderThan(ms) {
57
+ const cutoff = Date.now() - ms;
58
+ const before = this.#records.length;
59
+ this.#records = this.#records.filter(r => new Date(r.sentAt).getTime() > cutoff);
60
+ this.#persist();
61
+ return before - this.#records.length;
62
+ }
63
+
64
+ #persist() {
65
+ if (!this.#persistPath) return;
66
+ try {
67
+ fs.mkdirSync(path.dirname(this.#persistPath), { recursive: true });
68
+ const lines = this.#records.map(r => JSON.stringify(r)).join('\n');
69
+ fs.writeFileSync(this.#persistPath, lines + '\n', 'utf8');
70
+ } catch {}
71
+ }
72
+
73
+ #load() {
74
+ try {
75
+ if (!fs.existsSync(this.#persistPath)) return;
76
+ const lines = fs.readFileSync(this.#persistPath, 'utf8').split('\n').filter(Boolean);
77
+ for (const line of lines) {
78
+ try { this.#records.push(JSON.parse(line)); } catch {}
79
+ }
80
+ } catch {}
81
+ }
82
+
83
+ static resolvePersistPath(rootDir) {
84
+ return path.join(rootDir, '.cx', 'writes', 'sent-log.jsonl');
85
+ }
86
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * lib/writes/write-intent.mjs — the writeIntent record: the only artifact
3
+ * shape a specialist, embed capability, or MCP caller may produce when it
4
+ * wants an external write to happen.
5
+ *
6
+ * A writeIntent never executes anything by itself. `buildWriteIntent`
7
+ * validates and normalizes the record; `lib/writes/control-plane.mjs` is the
8
+ * only module that turns an *approved* writeIntent into a call through
9
+ * lib/writes/envelope.mjs. Nothing in this file resolves a provider adapter
10
+ * or performs I/O — it is schema and validation only, so it stays importable
11
+ * from any orchestration or embed path without smuggling in write access.
12
+ */
13
+
14
+ /** Providers with a governed-write adapter under lib/providers/contract/adapters/*. */
15
+ export const KNOWN_PROVIDERS = Object.freeze(['jira', 'github', 'confluence']);
16
+
17
+ /**
18
+ * Validate a writeIntent's required shape. Returns `{ ok: true }` or
19
+ * `{ ok: false, errors: string[] }` — never throws, so a malformed proposal
20
+ * from a specialist degrades to a rejected intent rather than crashing the
21
+ * caller.
22
+ *
23
+ * @param {object} intent
24
+ * @param {string} intent.providerId - one of KNOWN_PROVIDERS
25
+ * @param {string} intent.writeKind - adapter-specific write type (e.g. 'issue', 'comment')
26
+ * @param {object} intent.payload - write payload passed to the adapter
27
+ * @param {object} [intent.requestedBy] - actor identity of the recommending specialist
28
+ * @returns {{ ok: boolean, errors?: string[] }}
29
+ */
30
+ export function validateWriteIntent(intent) {
31
+ const errors = [];
32
+ if (!intent || typeof intent !== 'object') {
33
+ return { ok: false, errors: ['writeIntent must be an object'] };
34
+ }
35
+ if (!intent.providerId || typeof intent.providerId !== 'string') {
36
+ errors.push('writeIntent.providerId is required');
37
+ } else if (!KNOWN_PROVIDERS.includes(intent.providerId)) {
38
+ errors.push(`writeIntent.providerId "${intent.providerId}" is not a known governed provider (${KNOWN_PROVIDERS.join(', ')})`);
39
+ }
40
+ if (!intent.writeKind || typeof intent.writeKind !== 'string') {
41
+ errors.push('writeIntent.writeKind is required');
42
+ }
43
+ if (!intent.payload || typeof intent.payload !== 'object') {
44
+ errors.push('writeIntent.payload is required and must be an object');
45
+ }
46
+ return errors.length ? { ok: false, errors } : { ok: true };
47
+ }
48
+
49
+ /**
50
+ * Build a normalized writeIntent record from a specialist's recommendation.
51
+ * Throws on an invalid intent so a caller cannot silently enqueue a
52
+ * malformed record — the run should see the failure at recommend time, not
53
+ * discover it later when the control plane tries to execute it.
54
+ *
55
+ * @param {object} spec
56
+ * @param {string} spec.providerId
57
+ * @param {string} spec.writeKind
58
+ * @param {object} spec.payload
59
+ * @param {object} [spec.requestedBy] - { specialistId, role, serviceId, sessionId }
60
+ * @param {string} [spec.surface] - origin surface, e.g. 'embed-capability' | 'mcp' | 'cli'
61
+ * @returns {{ providerId: string, writeKind: string, payload: object, requestedBy: object, surface: string, tool: string }}
62
+ */
63
+ export function buildWriteIntent(spec) {
64
+ const intent = {
65
+ providerId: spec?.providerId,
66
+ writeKind: spec?.writeKind,
67
+ payload: spec?.payload,
68
+ };
69
+ const result = validateWriteIntent(intent);
70
+ if (!result.ok) {
71
+ throw new Error(`buildWriteIntent: invalid writeIntent — ${result.errors.join('; ')}`);
72
+ }
73
+ return {
74
+ providerId: intent.providerId,
75
+ writeKind: intent.writeKind,
76
+ payload: intent.payload,
77
+ requestedBy: spec?.requestedBy ?? {},
78
+ surface: spec?.surface ?? 'unknown',
79
+ tool: writeIntentToolName(intent.providerId, intent.writeKind),
80
+ };
81
+ }
82
+
83
+ /**
84
+ * The tool-name encoding shared with lib/embed/capability-jobs.mjs's
85
+ * ApprovalQueue.enqueue({ tool }) calls and lib/embed/authority-guard.mjs's
86
+ * grant keys — "<providerId>.<writeKind>", e.g. "jira.issue". Kept in one
87
+ * place so the control-plane drain and the enqueue side can never drift.
88
+ *
89
+ * @param {string} providerId
90
+ * @param {string} writeKind
91
+ * @returns {string}
92
+ */
93
+ export function writeIntentToolName(providerId, writeKind) {
94
+ return `${providerId}.${writeKind}`;
95
+ }
96
+
97
+ /**
98
+ * Parse a "<providerId>.<writeKind>" tool name back into its parts. Returns
99
+ * null when the name has no dot, which the caller should treat as
100
+ * unresolvable rather than guessing.
101
+ *
102
+ * @param {string} tool
103
+ * @returns {{ providerId: string, writeKind: string }|null}
104
+ */
105
+ export function parseWriteIntentToolName(tool) {
106
+ const idx = typeof tool === 'string' ? tool.indexOf('.') : -1;
107
+ if (idx <= 0 || idx === tool.length - 1) return null;
108
+ return { providerId: tool.slice(0, idx), writeKind: tool.slice(idx + 1) };
109
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geraldmaron/construct",
3
- "version": "1.4.2",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "packageManager": "npm@11.5.1",
6
6
  "description": "Construct — agent orchestration layer for OpenCode, Claude Code, and other coding surfaces",
@@ -57,9 +57,10 @@
57
57
  "mcp": "node lib/mcp/server.mjs",
58
58
  "doctor": "node ./bin/construct doctor",
59
59
  "test": "node scripts/run-tests.mjs",
60
- "test:functional": "XDG_CONFIG_HOME= XDG_STATE_HOME= XDG_CACHE_HOME= node --test --test-timeout=120000 --test-concurrency=1 tests/functional/*.functional.test.mjs",
61
- "test:visual": "node -e \"console.log('visual surface tests removed')\"",
60
+ "test:functional": "XDG_CONFIG_HOME= XDG_STATE_HOME= XDG_CACHE_HOME= ANTHROPIC_API_KEY= OPENAI_API_KEY= OPENROUTER_API_KEY= CX_MODEL_REASONING= CX_MODEL_STANDARD= CX_MODEL_FAST= CONSTRUCT_MODEL_REASONING= CONSTRUCT_MODEL_STANDARD= CONSTRUCT_MODEL_FAST= CONSTRUCT_PROVIDER_TIMEOUT_MS= WEB_SEARCH_URL= CX_USER_ENV_PATH= CONSTRUCT_TELEMETRY_URL= node --test --test-timeout=120000 --test-concurrency=1 tests/functional/*.functional.test.mjs",
61
+ "test:visual": "node --test --test-timeout=120000 tests/visual/*.test.mjs",
62
62
  "test:unit": "node scripts/run-tests.mjs --exclude=tests/functional",
63
+ "ci:local": "bash scripts/ci-repro/run.sh",
63
64
  "lint:js": "eslint bin/construct \"lib/**/*.mjs\" \"scripts/**/*.mjs\" \"tests/**/*.mjs\"",
64
65
  "coverage": "c8 --reporter=text-summary --reporter=lcov --src=lib --src=bin node scripts/run-tests.mjs --exclude=tests/functional",
65
66
  "docs:init": "node -e \"console.error('docs:init is deprecated — use: construct init --docs-preset=lean|product|full'); process.exit(1)\"",
@@ -70,33 +71,38 @@
70
71
  "docs:build": "node scripts/npm-run.mjs npm --prefix apps/docs run build",
71
72
  "lint:comments": "node ./bin/construct lint:comments",
72
73
  "lint:contracts": "node ./bin/construct lint:contracts",
74
+ "graph:gate": "node scripts/run-graph-gate.mjs",
73
75
  "lint:agents": "node ./bin/construct lint:agents",
74
76
  "gates:audit": "node ./bin/construct gates:audit",
75
77
  "evals": "node ./bin/construct evals",
76
78
  "certify:demos": "node ./bin/construct certify demos",
77
79
  "build:sea": "esbuild bin/construct --bundle --platform=node --target=node20 --packages=external --outfile=dist/construct-bundle.cjs 2>&1 || (echo 'esbuild not found — install with: npm install -g esbuild' && exit 1)",
80
+ "build:binary": "node scripts/build-binary.mjs",
81
+ "build:binary:fallback": "node scripts/build-sea.mjs",
78
82
  "examples:deck": "node scripts/generate-deck-examples.mjs",
79
83
  "examples:distribution": "node scripts/generate-distribution-examples.mjs",
80
84
  "clean:artifacts": "node scripts/clean-artifacts.mjs",
81
85
  "lint:scopes": "node scripts/lint-scopes.mjs",
82
86
  "catalog:regen": "node scripts/catalog-regen.mjs",
83
87
  "catalog:validate": "node scripts/catalog-validate.mjs",
88
+ "workflow-defs:check": "node scripts/check-workflow-defs-drift.mjs --check",
84
89
  "docs:sync": "node scripts/docs-sync.mjs",
85
90
  "learning:status": "node scripts/learning-status.mjs",
86
91
  "lint:templates": "node scripts/lint-commits-pr.mjs",
87
92
  "eval:routing": "node scripts/eval/score-intent-classifier.mjs",
88
93
  "adapters": "node lib/adapters-sync.mjs",
89
- "release:check": "npm run doctor && node ./bin/construct registry:validate --unified && npm run catalog:validate -- --check && npm test && npm run docs:update -- --check && npm run docs:site -- --check && npm run docs:sync -- --check && node ./bin/construct registry:generate-docs --check && npm run docs:verify -- --strict && node scripts/alignment/census.mjs --ratchet && npm run lint:comments && node ./bin/construct certify gate && npm run lint:templates",
94
+ "release:check": "npm run doctor && node ./bin/construct registry:validate --unified && npm run catalog:validate -- --check && npm run workflow-defs:check && npm test && node scripts/release-evidence-gate.mjs --skip-tests && npm run docs:update -- --check && npm run docs:site -- --check && npm run docs:sync -- --check && node ./bin/construct registry:generate-docs --check && npm run docs:verify -- --strict && node scripts/alignment/census.mjs --ratchet && npm run lint:comments && node ./bin/construct certify gate && npm run graph:gate && npm run lint:templates",
90
95
  "release:gate": "node --test tests/functional/release-gate.functional.test.mjs",
91
96
  "audit:published": "node scripts/audit-published-artifact.mjs",
92
97
  "version": "node scripts/sync-construct-version.mjs && git add -f .construct/version",
93
98
  "release:preflight": "node scripts/pre-release-check.mjs",
94
99
  "release:preflight:no-auth": "node scripts/pre-release-check.mjs --skip-auth",
95
100
  "npm:publish": "npm run release:check && npm publish --access public",
96
- "postinstall": "node ./bin/construct-postinstall.mjs"
101
+ "postinstall": "node ./bin/construct-postinstall.mjs",
102
+ "deps:check": "node scripts/validate-dep-intent.mjs"
97
103
  },
98
104
  "dependencies": {
99
- "@lancedb/lancedb": "^0.30.0",
105
+ "@lancedb/lancedb": "^0.31.0",
100
106
  "@modelcontextprotocol/sdk": "^1.12.0",
101
107
  "apache-arrow": "^18.1.0",
102
108
  "js-yaml": "^4.2.0"
@@ -110,6 +116,7 @@
110
116
  "ai": "^6.0.208",
111
117
  "ink": "^7.1.0",
112
118
  "mammoth": "^1.12.0",
119
+ "postgres": "^3.4.9",
113
120
  "pptx-embed-fonts": "^0.0.6",
114
121
  "pptxgenjs": "^4.0.1",
115
122
  "react": "^19.2.7",
@@ -124,9 +131,10 @@
124
131
  "@eslint/js": "^9.39.4",
125
132
  "c8": "^11.0.0",
126
133
  "esbuild": "^0.28.1",
127
- "postject": "1.0.0-alpha.6",
128
134
  "eslint": "^10.4.1",
129
135
  "globals": "^17.6.0",
130
- "ink-testing-library": "^4.0.0"
136
+ "ink-testing-library": "^4.0.0",
137
+ "playwright": "^1.61.1",
138
+ "postject": "1.0.0-alpha.6"
131
139
  }
132
140
  }
@@ -25,9 +25,9 @@ Use the single-writer rule whenever multiple sessions are active: if two session
25
25
 
26
26
  ## Classify before acting <!-- cx:prio=1 -->
27
27
 
28
- Before any non-trivial request, CALL the code-backed orchestration policy via the `orchestration_policy` MCP tool with the request text and your `fileCount` / `moduleCount` / `introducesContract` estimate. Do not classify from memory. Honor the returned `track` and `specialists`. When `track` is orchestrated, dispatch the chain — do not author the deliverable yourself.
28
+ Before any non-trivial request, CALL the code-backed orchestration policy via the `orchestration_policy` MCP tool with the request text and your `fileCount` / `moduleCount` / `introducesContract` estimate. Do not classify from memory. Honor the returned `track`. When `track` is not immediate, dispatch through `orchestration_delegation_next` (below) — do not author the deliverable yourself and do not self-sequence off `orchestration_policy`'s specialist list from memory across turns.
29
29
 
30
- Tracks: immediate (act directly), focused (one bounded specialist), orchestrated (plan → challenge → build → validate, tracker-backed). cx-devil-advocate is mandatory whenever `riskFlags` include architecture, security, dataIntegrity, or ai.
30
+ Tracks: immediate (act directly), focused (one bounded specialist), orchestrated (plan → challenge → build → validate, tracker-backed). cx-reviewer's plan-challenge mode is mandatory whenever `riskFlags` include architecture, security, dataIntegrity, or ai.
31
31
 
32
32
  Orchestrated dispatches emit a task-packet with `goal`, `intent`, `workCategory`, `riskFlags`, `acceptanceCriteria` before naming specialists (`specialists/contracts.json:construct-to-orchestrator`).
33
33
 
@@ -45,9 +45,18 @@ General conversation is still valid for scoping, clarification, and lightweight
45
45
 
46
46
  1. **Gates**. `framingChallenge`, `externalResearch`, `docAuthoring`
47
47
  2. **Contract chain**. typed handoffs from `specialists/contracts.json`. Call `agent_contract` with `handoffPacket` from `orchestration_policy`.
48
- 3. **Specialist sequence**. dispatch plan with ordering/parallel markers.
48
+ 3. **Specialist sequence**. the engine's job, not yours — see below.
49
49
  4. **Team routing**. name `teamRouting.primaryTeam` in the dispatch plan; route through `teamRouting.requiredApprovals` before DONE; if `teamRouting.blockedStatus` is set, stop and escalate along its `escalationPath` rather than proceeding.
50
50
 
51
+ ## Dispatch one step at a time <!-- cx:prio=1 -->
52
+
53
+ Sequencing a multi-specialist chain is the flow engine's job (ADR-0067), not something to hold in your own context across turns. Once `orchestration_policy` says the track is not immediate, drive dispatch through `orchestration_delegation_next`, not by reading a full plan and self-sequencing:
54
+
55
+ - Mint a `run_id` for this dispatch (a session or task id is fine) and call `orchestration_delegation_next` with the same `request`/`fileCount`/`moduleCount` you gave `orchestration_policy`, plus that `run_id`.
56
+ - Act on exactly the returned `currentDelegation` — its `role`, `reason`, and `handoffContract` — and nothing else. Do not pre-plan the rest of the chain from a remembered dispatch plan.
57
+ - Call again with the same `run_id` for the next specialist. Repeat until `done: true`.
58
+ - The chain survives a restart: calling again with the same `run_id` in a later turn or session continues from wherever it left off, never re-running a specialist already dispatched.
59
+
51
60
  Before DONE: postconditions met · sources cited · framing logged · ADRs have Rejected alternatives.
52
61
 
53
62
  ## Branch + commit approval <!-- cx:prio=1 -->
@@ -1,16 +1,19 @@
1
1
  {
2
2
  "version": 1,
3
3
  "catalog": {
4
- "generatedAt": "2026-07-01T01:09:33.824Z",
4
+ "generatedAt": "2026-07-06T22:40:56.862Z",
5
5
  "npmScripts": [
6
6
  "adapters",
7
7
  "audit:published",
8
+ "build:binary",
9
+ "build:binary:fallback",
8
10
  "build:sea",
9
11
  "catalog:regen",
10
12
  "catalog:validate",
11
13
  "certify:demos",
12
14
  "clean:artifacts",
13
15
  "coverage",
16
+ "deps:check",
14
17
  "docs:build",
15
18
  "docs:dev",
16
19
  "docs:init",
@@ -24,6 +27,7 @@
24
27
  "examples:deck",
25
28
  "examples:distribution",
26
29
  "gates:audit",
30
+ "graph:gate",
27
31
  "learning:status",
28
32
  "lint:agents",
29
33
  "lint:comments",
@@ -42,7 +46,8 @@
42
46
  "test:functional",
43
47
  "test:unit",
44
48
  "test:visual",
45
- "version"
49
+ "version",
50
+ "workflow-defs:check"
46
51
  ],
47
52
  "cliCommands": [
48
53
  {
@@ -57,6 +62,12 @@
57
62
  "core": false,
58
63
  "internal": true
59
64
  },
65
+ {
66
+ "name": "approvals",
67
+ "category": "Core",
68
+ "core": true,
69
+ "internal": false
70
+ },
60
71
  {
61
72
  "name": "artifact",
62
73
  "category": "Work",
@@ -159,6 +170,12 @@
159
170
  "core": false,
160
171
  "internal": false
161
172
  },
173
+ {
174
+ "name": "db",
175
+ "category": "Models & Integrations",
176
+ "core": false,
177
+ "internal": false
178
+ },
162
179
  {
163
180
  "name": "decisions",
164
181
  "category": "Advanced",
@@ -309,6 +326,12 @@
309
326
  "core": false,
310
327
  "internal": false
311
328
  },
329
+ {
330
+ "name": "flow",
331
+ "category": "Models & Integrations",
332
+ "core": false,
333
+ "internal": false
334
+ },
312
335
  {
313
336
  "name": "gates:audit",
314
337
  "category": "Advanced",
@@ -519,6 +542,12 @@
519
542
  "core": false,
520
543
  "internal": true
521
544
  },
545
+ {
546
+ "name": "pack",
547
+ "category": "Work",
548
+ "core": false,
549
+ "internal": false
550
+ },
522
551
  {
523
552
  "name": "plugin",
524
553
  "category": "Models & Integrations",
@@ -801,6 +830,12 @@
801
830
  "core": false,
802
831
  "internal": false
803
832
  },
833
+ {
834
+ "name": "workers",
835
+ "category": "Core",
836
+ "core": true,
837
+ "internal": false
838
+ },
804
839
  {
805
840
  "name": "workflow",
806
841
  "category": "Work",
@@ -815,15 +850,25 @@
815
850
  }
816
851
  ],
817
852
  "workflows": [
853
+ {
854
+ "type": "architecture-review",
855
+ "description": "Review an architecture or design for trade-offs, failure modes, and security exposure.",
856
+ "tier": "reasoning"
857
+ },
858
+ {
859
+ "type": "data-structure",
860
+ "description": "Parse, validate, and profile a raw dataset into a structured, described shape.",
861
+ "tier": "standard"
862
+ },
818
863
  {
819
864
  "type": "evidence-ingest",
820
865
  "description": "Ingest and structure raw evidence (notes, documents, signals) into a normalized summary.",
821
866
  "tier": "fast"
822
867
  },
823
868
  {
824
- "type": "proposal-review",
825
- "description": "Review a proposal for correctness, risk, and hidden assumptions before acceptance.",
826
- "tier": "standard"
869
+ "type": "memo-draft",
870
+ "description": "Draft a decision or status memo from a problem statement and context.",
871
+ "tier": "fast"
827
872
  },
828
873
  {
829
874
  "type": "prd-draft",
@@ -831,8 +876,13 @@
831
876
  "tier": "standard"
832
877
  },
833
878
  {
834
- "type": "architecture-review",
835
- "description": "Review an architecture or design for trade-offs, failure modes, and security exposure.",
879
+ "type": "proposal-review",
880
+ "description": "Review a proposal for correctness, risk, and hidden assumptions before acceptance.",
881
+ "tier": "standard"
882
+ },
883
+ {
884
+ "type": "research-synthesis",
885
+ "description": "Synthesize multiple sources into a cited, evidence-graded research summary.",
836
886
  "tier": "reasoning"
837
887
  },
838
888
  {
@@ -841,9 +891,9 @@
841
891
  "tier": "reasoning"
842
892
  },
843
893
  {
844
- "type": "research-synthesis",
845
- "description": "Synthesize multiple sources into a cited, evidence-graded research summary.",
846
- "tier": "reasoning"
894
+ "type": "structure-notes",
895
+ "description": "Structure an unclassified brain-dump or rough notes into a normalized summary with extracted intents.",
896
+ "tier": "fast"
847
897
  },
848
898
  {
849
899
  "type": "transcript-process",
@@ -851,32 +901,23 @@
851
901
  "tier": "fast"
852
902
  },
853
903
  {
854
- "type": "data-structure",
855
- "description": "Parse, validate, and profile a raw dataset into a structured, described shape.",
856
- "tier": "standard"
857
- },
858
- {
859
- "type": "memo-draft",
860
- "description": "Draft a decision or status memo from a problem statement and context.",
861
- "tier": "fast"
862
- },
863
- {
864
- "type": "structure-notes",
865
- "description": "Structure an unclassified brain-dump or rough notes into a normalized summary with extracted intents.",
904
+ "type": "triage",
905
+ "description": "Classify and route unstructured input to the appropriate workflow.",
866
906
  "tier": "fast"
867
907
  }
868
908
  ],
869
909
  "workflowTypes": [
910
+ "architecture-review",
911
+ "data-structure",
870
912
  "evidence-ingest",
871
- "proposal-review",
913
+ "memo-draft",
872
914
  "prd-draft",
873
- "architecture-review",
874
- "risk-review",
915
+ "proposal-review",
875
916
  "research-synthesis",
917
+ "risk-review",
918
+ "structure-notes",
876
919
  "transcript-process",
877
- "data-structure",
878
- "memo-draft",
879
- "structure-notes"
920
+ "triage"
880
921
  ]
881
922
  },
882
923
  "capabilities": [
@@ -1073,7 +1114,10 @@
1073
1114
  "workflow",
1074
1115
  "workflow invoke"
1075
1116
  ],
1076
- "npmScripts": [],
1117
+ "npmScripts": [
1118
+ "release:check",
1119
+ "workflow-defs:check"
1120
+ ],
1077
1121
  "workflows": [
1078
1122
  "evidence-ingest"
1079
1123
  ]
@@ -1193,7 +1237,10 @@
1193
1237
  "workflow",
1194
1238
  "workflow invoke"
1195
1239
  ],
1196
- "npmScripts": [],
1240
+ "npmScripts": [
1241
+ "release:check",
1242
+ "workflow-defs:check"
1243
+ ],
1197
1244
  "workflows": [
1198
1245
  "prd-draft"
1199
1246
  ]
@@ -1234,7 +1281,10 @@
1234
1281
  "workflow",
1235
1282
  "workflow invoke"
1236
1283
  ],
1237
- "npmScripts": [],
1284
+ "npmScripts": [
1285
+ "release:check",
1286
+ "workflow-defs:check"
1287
+ ],
1238
1288
  "workflows": [
1239
1289
  "architecture-review"
1240
1290
  ]
@@ -1274,7 +1324,10 @@
1274
1324
  "workflow",
1275
1325
  "workflow invoke"
1276
1326
  ],
1277
- "npmScripts": [],
1327
+ "npmScripts": [
1328
+ "release:check",
1329
+ "workflow-defs:check"
1330
+ ],
1278
1331
  "workflows": [
1279
1332
  "proposal-review"
1280
1333
  ]
@@ -1315,7 +1368,10 @@
1315
1368
  "workflow",
1316
1369
  "workflow invoke"
1317
1370
  ],
1318
- "npmScripts": [],
1371
+ "npmScripts": [
1372
+ "release:check",
1373
+ "workflow-defs:check"
1374
+ ],
1319
1375
  "workflows": [
1320
1376
  "risk-review"
1321
1377
  ]
@@ -1396,7 +1452,10 @@
1396
1452
  "workflow",
1397
1453
  "workflow invoke"
1398
1454
  ],
1399
- "npmScripts": [],
1455
+ "npmScripts": [
1456
+ "release:check",
1457
+ "workflow-defs:check"
1458
+ ],
1400
1459
  "workflows": [
1401
1460
  "transcript-process"
1402
1461
  ]
@@ -1436,7 +1495,10 @@
1436
1495
  "workflow",
1437
1496
  "workflow invoke"
1438
1497
  ],
1439
- "npmScripts": [],
1498
+ "npmScripts": [
1499
+ "release:check",
1500
+ "workflow-defs:check"
1501
+ ],
1440
1502
  "workflows": [
1441
1503
  "data-structure"
1442
1504
  ]
@@ -1476,13 +1538,58 @@
1476
1538
  "workflow",
1477
1539
  "workflow invoke"
1478
1540
  ],
1479
- "npmScripts": [],
1541
+ "npmScripts": [
1542
+ "release:check",
1543
+ "workflow-defs:check"
1544
+ ],
1480
1545
  "workflows": [
1481
1546
  "memo-draft"
1482
1547
  ]
1483
1548
  },
1484
1549
  "_semanticDigest": "{\"description\":\"Draft a decision or status memo from a problem statement and context.\",\"criticality\":\"P2\",\"verification\":{\"functional\":\"tests/functional/embedded-contract-workflow-invoke.functional.test.mjs\"}}"
1485
1550
  },
1551
+ {
1552
+ "id": "workflow.triage",
1553
+ "kind": "workflow",
1554
+ "name": "Triage Workflow",
1555
+ "description": "Classify and route unstructured input to the appropriate workflow.",
1556
+ "criticality": "P2",
1557
+ "ownerSpecialists": [
1558
+ "orchestrator",
1559
+ "researcher"
1560
+ ],
1561
+ "embeddedWorkflow": "triage",
1562
+ "surfaces": {
1563
+ "mcp": {
1564
+ "supported": true,
1565
+ "primary": true,
1566
+ "tool": "workflow_invoke"
1567
+ },
1568
+ "cli": {
1569
+ "supported": true,
1570
+ "command": "construct workflow invoke",
1571
+ "jsonTwin": true
1572
+ }
1573
+ },
1574
+ "verification": {
1575
+ "functional": "tests/functional/embedded-contract-triage.functional.test.mjs"
1576
+ },
1577
+ "humanGate": "proposal-only",
1578
+ "edges": {
1579
+ "cliCommands": [
1580
+ "workflow",
1581
+ "workflow invoke"
1582
+ ],
1583
+ "npmScripts": [
1584
+ "release:check",
1585
+ "workflow-defs:check"
1586
+ ],
1587
+ "workflows": [
1588
+ "triage"
1589
+ ]
1590
+ },
1591
+ "_semanticDigest": "{\"description\":\"Classify and route unstructured input to the appropriate workflow.\",\"criticality\":\"P2\",\"verification\":{\"functional\":\"tests/functional/embedded-contract-triage.functional.test.mjs\"}}"
1592
+ },
1486
1593
  {
1487
1594
  "id": "document-type.research-brief",
1488
1595
  "kind": "document-type",
@@ -42,6 +42,7 @@ The blank line between the comment and the code is required. It signals "this co
42
42
  - **Narrative voice** (`// We weight BM25`, `// Now test the keys`, `// This correctly scores`) delete them
43
43
  - **Point-in-time notes** (`// X removed`, `// previously`, `// no longer`) belongs in git log
44
44
  - **Noise sentinels** (`// ok`, `// best effort`, `// skip`) delete them; use `/* non-critical */` inline only when the catch clause would otherwise look like a bug
45
+ - **Other-project comparisons** (`// per the LangGraph thread-vs-store split`) delete them; describe the behavior on its own terms. A prior-art comparison belongs in a decision document (`docs/decisions/**`, `docs/notes/**`) where it can carry a citation
45
46
 
46
47
  ## SLA annotations (hooks only)
47
48