@aiwg/cli 2026.10.1 → 2026.10.4

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 (361) hide show
  1. package/README.md +2 -2
  2. package/agentic/code/providers/capability-matrix.yaml +270 -0
  3. package/agentic/code/providers/model-capabilities.v1.json +3183 -24
  4. package/bin/aiwg.mjs +135 -47
  5. package/dist/src/a2a/codecs.js +9 -0
  6. package/dist/src/agents/grounding/knowledge-base.js +54 -6
  7. package/dist/src/artifacts/browser-export.js +6 -0
  8. package/dist/src/artifacts/checksum-manifest.js +1 -0
  9. package/dist/src/artifacts/citation-parser.js +173 -92
  10. package/dist/src/artifacts/citation-table-schema.js +59 -0
  11. package/dist/src/artifacts/cli.js +57 -18
  12. package/dist/src/artifacts/corpus-tools/snapshot.js +1 -1
  13. package/dist/src/artifacts/corpus-tools/vision-extract.js +107 -15
  14. package/dist/src/artifacts/corpus-views/ref-parser.js +3 -1
  15. package/dist/src/artifacts/corpus-views/renderers.js +3 -3
  16. package/dist/src/artifacts/discovery-eval.js +6 -4
  17. package/dist/src/artifacts/fortemi-core-query-adapter.js +36 -3
  18. package/dist/src/artifacts/fortemi-core-sync.js +166 -40
  19. package/dist/src/artifacts/framework-capabilities.js +171 -0
  20. package/dist/src/artifacts/framework-index-paths.js +73 -0
  21. package/dist/src/artifacts/framework-source-digest.js +75 -0
  22. package/dist/src/artifacts/index-builder.js +285 -131
  23. package/dist/src/artifacts/index-files.js +132 -18
  24. package/dist/src/artifacts/index-preparation.js +65 -0
  25. package/dist/src/artifacts/index-refresh.js +576 -0
  26. package/dist/src/artifacts/index-worker.mjs +9 -0
  27. package/dist/src/artifacts/prebuilt-build-lock.js +47 -4
  28. package/dist/src/artifacts/prebuilt-deployment.js +46 -0
  29. package/dist/src/artifacts/prebuilt-relations.js +80 -0
  30. package/dist/src/artifacts/query-engine.js +410 -88
  31. package/dist/src/artifacts/relations-builder.js +168 -0
  32. package/dist/src/artifacts/relations.js +148 -0
  33. package/dist/src/artifacts/repair.js +9 -4
  34. package/dist/src/artifacts/stats.js +5 -2
  35. package/dist/src/artifacts/types.js +30 -10
  36. package/dist/src/artifacts/watcher.js +1 -1
  37. package/dist/src/auth/credential-store.js +2 -1
  38. package/dist/src/catalog/cli.d.mts +5 -0
  39. package/dist/src/channel/manager.d.mts +20 -0
  40. package/dist/src/channel/manager.mjs +78 -12
  41. package/dist/src/cli/child-process-result.js +40 -0
  42. package/dist/src/cli/command-log.js +2 -3
  43. package/dist/src/cli/env.js +38 -16
  44. package/dist/src/cli/flag-parsing.js +236 -0
  45. package/dist/src/cli/handlers/artifacts.js +3 -0
  46. package/dist/src/cli/handlers/auth.js +3 -0
  47. package/dist/src/cli/handlers/decision.js +218 -5
  48. package/dist/src/cli/handlers/diagnose.js +13 -5
  49. package/dist/src/cli/handlers/effect.js +4 -2
  50. package/dist/src/cli/handlers/evidence.js +3 -0
  51. package/dist/src/cli/handlers/feedback.js +14 -5
  52. package/dist/src/cli/handlers/help.js +1 -0
  53. package/dist/src/cli/handlers/index.js +3 -1
  54. package/dist/src/cli/handlers/init.js +248 -30
  55. package/dist/src/cli/handlers/lint.js +5 -0
  56. package/dist/src/cli/handlers/mc.js +23 -0
  57. package/dist/src/cli/handlers/models.js +169 -10
  58. package/dist/src/cli/handlers/ralph-launcher.js +2 -0
  59. package/dist/src/cli/handlers/ralph.js +3 -0
  60. package/dist/src/cli/handlers/refresh.js +28 -0
  61. package/dist/src/cli/handlers/regenerate.js +14 -0
  62. package/dist/src/cli/handlers/resource-versions.js +3 -0
  63. package/dist/src/cli/handlers/rules.js +195 -0
  64. package/dist/src/cli/handlers/run.js +4 -0
  65. package/dist/src/cli/handlers/runtime-info.js +25 -11
  66. package/dist/src/cli/handlers/script-runner.js +19 -8
  67. package/dist/src/cli/handlers/session.js +406 -62
  68. package/dist/src/cli/handlers/sessions.js +243 -76
  69. package/dist/src/cli/handlers/setup-manifest.js +474 -79
  70. package/dist/src/cli/handlers/setup.js +180 -39
  71. package/dist/src/cli/handlers/steward.js +11 -0
  72. package/dist/src/cli/handlers/subcommands.js +60 -3
  73. package/dist/src/cli/handlers/team.js +18 -8
  74. package/dist/src/cli/handlers/uhp.js +3 -0
  75. package/dist/src/cli/handlers/use.js +307 -55
  76. package/dist/src/cli/handlers/utilities.js +125 -26
  77. package/dist/src/cli/handlers/version.js +8 -0
  78. package/dist/src/cli/prompt-utils.js +72 -0
  79. package/dist/src/cli/provider-resolution.js +11 -0
  80. package/dist/src/cli/router.js +15 -1
  81. package/dist/src/cli/services/deployment-verification.js +19 -9
  82. package/dist/src/cli/services/provider-prepare-coordinator.js +24 -0
  83. package/dist/src/cli/skill-usage.js +2 -3
  84. package/dist/src/config/aiwg-config.js +349 -35
  85. package/dist/src/config/cli.js +256 -23
  86. package/dist/src/config/decision-config.js +106 -0
  87. package/dist/src/config/dispatch-thresholds-runtime.d.mts +8 -0
  88. package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
  89. package/dist/src/config/gitignore.js +50 -0
  90. package/dist/src/config/index-graph-overrides.js +36 -0
  91. package/dist/src/config/project-artifacts-health.d.mts +37 -0
  92. package/dist/src/config/project-artifacts-health.mjs +14 -3
  93. package/dist/src/config/project-artifacts-runtime.d.mts +16 -0
  94. package/dist/src/config/user-config-dir.d.mts +9 -0
  95. package/dist/src/config/user-config.js +38 -11
  96. package/dist/src/config/user-registry.js +23 -15
  97. package/dist/src/config/user-state.js +7 -0
  98. package/dist/src/decision/adapters/jev.js +75 -27
  99. package/dist/src/decision/ask.js +203 -43
  100. package/dist/src/decision/context-live-qualification.js +2 -2
  101. package/dist/src/decision/driver.js +14 -7
  102. package/dist/src/decision/ensemble/aggregate.js +23 -10
  103. package/dist/src/decision/ensemble-study/multifact-study.js +6 -2
  104. package/dist/src/decision/entry.js +25 -6
  105. package/dist/src/decision/graph-live-qualification.js +1 -1
  106. package/dist/src/decision/graph-run.js +9 -0
  107. package/dist/src/decision/heldout/collector.js +15 -14
  108. package/dist/src/decision/heldout/contract.js +30 -7
  109. package/dist/src/decision/index.js +1 -0
  110. package/dist/src/decision/interop.js +60 -8
  111. package/dist/src/decision/jev-credentials.js +15 -1
  112. package/dist/src/decision/ledger.js +942 -0
  113. package/dist/src/decision/offload-activation.js +137 -0
  114. package/dist/src/decision/offload.js +550 -0
  115. package/dist/src/decision/qualification/load.js +4 -6
  116. package/dist/src/decision/savings.js +28 -0
  117. package/dist/src/decision/validate.js +6 -3
  118. package/dist/src/effects/dispatch-verifier.js +252 -0
  119. package/dist/src/effects/index.js +1 -0
  120. package/dist/src/effects/types.js +5 -1
  121. package/dist/src/effects/verifiers/git.js +2 -1
  122. package/dist/src/effects/verifiers/tracker.js +26 -14
  123. package/dist/src/extensions/commands/definitions.js +19 -0
  124. package/dist/src/extensions/project-local-remove.js +36 -1
  125. package/dist/src/features/installer.js +2 -2
  126. package/dist/src/flow/graph-metadata.js +5 -0
  127. package/dist/src/gates/providers/loader.js +64 -18
  128. package/dist/src/installation/manager-command.d.mts +18 -0
  129. package/dist/src/installation/manager-command.mjs +15 -3
  130. package/dist/src/installation/manager.d.mts +49 -0
  131. package/dist/src/installation/manager.mjs +95 -5
  132. package/dist/src/issues/cli.js +4 -4
  133. package/dist/src/issues/local.js +24 -5
  134. package/dist/src/jobs/runner.js +1 -1
  135. package/dist/src/lint/cli.js +27 -1
  136. package/dist/src/lint/loader.js +2 -1
  137. package/dist/src/lint/reporters.js +25 -1
  138. package/dist/src/lint/rule-activation.js +43 -0
  139. package/dist/src/lint/runner.js +137 -62
  140. package/dist/src/mcp/adapters/codex-runtime.js +366 -56
  141. package/dist/src/mcp/claude-install.d.mts +4 -0
  142. package/dist/src/mcp/claude-install.mjs +41 -0
  143. package/dist/src/mcp/cli.d.mts +1 -0
  144. package/dist/src/mcp/cli.mjs +620 -85
  145. package/dist/src/mcp/config-file.d.mts +28 -0
  146. package/dist/src/mcp/config-file.mjs +279 -0
  147. package/dist/src/mcp/config-layers.d.mts +36 -0
  148. package/dist/src/mcp/config-layers.mjs +348 -0
  149. package/dist/src/mcp/credentials.d.mts +51 -0
  150. package/dist/src/mcp/credentials.mjs +484 -0
  151. package/dist/src/mcp/grok-build-config.d.mts +6 -0
  152. package/dist/src/mcp/grok-build-config.mjs +17 -27
  153. package/dist/src/mcp/helpers.mjs +109 -4
  154. package/dist/src/mcp/muse-native-config.d.mts +13 -0
  155. package/dist/src/mcp/muse-native-config.mjs +1 -0
  156. package/dist/src/mcp/omp-config.d.mts +4 -0
  157. package/dist/src/mcp/omp-config.mjs +50 -29
  158. package/dist/src/mcp/profiles.js +97 -23
  159. package/dist/src/mcp/profiles.mjs +99 -27
  160. package/dist/src/mcp/registry.js +248 -131
  161. package/dist/src/mcp/registry.mjs +169 -100
  162. package/dist/src/mcp/server-config.d.mts +3 -0
  163. package/dist/src/mcp/server-config.mjs +89 -0
  164. package/dist/src/mcp/server.mjs +127 -82
  165. package/dist/src/mcp/test-simple.mjs +2 -1
  166. package/dist/src/mcp/toml-editor.d.mts +4 -0
  167. package/dist/src/mcp/toml-string.d.mts +1 -0
  168. package/dist/src/mcp/toml-string.mjs +9 -0
  169. package/dist/src/mcp/toml-strip-mcp.d.mts +1 -0
  170. package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
  171. package/dist/src/mcp/tool-filters.d.mts +46 -0
  172. package/dist/src/mcp/tool-filters.mjs +357 -0
  173. package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
  174. package/dist/src/mcp/tools/decision.mjs +22 -3
  175. package/dist/src/mcp/tools/discovery.mjs +62 -55
  176. package/dist/src/mcp/tools/orchestration.mjs +50 -2
  177. package/dist/src/mcp/tools/subsystems.mjs +39 -8
  178. package/dist/src/mcp/tools/worker-invoke.mjs +2856 -0
  179. package/dist/src/mcp/tools/worker-shell-control.mjs +289 -0
  180. package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
  181. package/dist/src/memory/project-registry.js +2 -2
  182. package/dist/src/mission-protocol/codecs.js +647 -1
  183. package/dist/src/mission-protocol/types.js +110 -0
  184. package/dist/src/mission-protocol/worker-status.js +2 -0
  185. package/dist/src/models/config-loader.js +76 -14
  186. package/dist/src/models/grok-build-models.js +93 -41
  187. package/dist/src/models/model-capabilities.v1.json +3183 -24
  188. package/dist/src/models/model-discovery.js +931 -67
  189. package/dist/src/models/provider-policy.js +719 -11
  190. package/dist/src/models/qualification-digest.d.mts +2 -0
  191. package/dist/src/models/qualification-digest.mjs +17 -0
  192. package/dist/src/models/resolver.js +261 -0
  193. package/dist/src/models/worker-direct-readiness.js +550 -0
  194. package/dist/src/models/worker-dispatch-offer.js +169 -0
  195. package/dist/src/models/worker-health-readiness.js +144 -0
  196. package/dist/src/models/worker-installation.d.mts +39 -0
  197. package/dist/src/models/worker-installation.mjs +986 -0
  198. package/dist/src/models/wrapper-route.js +18 -0
  199. package/dist/src/ops/registry.js +9 -14
  200. package/dist/src/plugins/standalone-packager.js +4 -3
  201. package/dist/src/process/bounded-child-process.d.mts +84 -0
  202. package/dist/src/process/bounded-child-process.mjs +430 -0
  203. package/dist/src/process/cli-command.d.mts +16 -0
  204. package/dist/src/process/cli-command.mjs +75 -0
  205. package/dist/src/process/signal-child.d.mts +6 -0
  206. package/dist/src/process/signal-child.mjs +7 -0
  207. package/dist/src/providers/capability-matrix.js +8 -0
  208. package/dist/src/providers/capability-matrix.yaml +270 -0
  209. package/dist/src/providers/deployed-skill-roots.js +20 -0
  210. package/dist/src/providers/grok-build-acp.js +3 -2
  211. package/dist/src/providers/grok-build-headless.js +53 -23
  212. package/dist/src/providers/grok-build-inspect.js +1 -0
  213. package/dist/src/providers/omp-agent.d.mts +8 -0
  214. package/dist/src/providers/omp-diagnostics.d.mts +1 -0
  215. package/dist/src/providers/omp-paths.d.mts +13 -0
  216. package/dist/src/providers/provider-definitions.js +9 -1
  217. package/dist/src/providers/provider-definitions.mjs +9 -2
  218. package/dist/src/providers/skill-ownership.d.mts +9 -0
  219. package/dist/src/providers/skill-ownership.mjs +88 -0
  220. package/dist/src/rules/activation.d.mts +21 -0
  221. package/dist/src/rules/activation.mjs +62 -0
  222. package/dist/src/rules/inline-budget.d.mts +26 -0
  223. package/dist/src/rules/inline-budget.mjs +66 -0
  224. package/dist/src/rules/inventory.js +129 -0
  225. package/dist/src/rules/pin-state.js +73 -0
  226. package/dist/src/rules/pins.d.mts +14 -0
  227. package/dist/src/rules/pins.mjs +112 -0
  228. package/dist/src/rules/rule-frontmatter.schema.json +197 -0
  229. package/dist/src/serve/executor-registry.js +16 -24
  230. package/dist/src/serve/fleet-mission-conductor.js +9 -0
  231. package/dist/src/serve/mission-conductor.js +47 -12
  232. package/dist/src/serve/shared-host-scheduler.js +2 -0
  233. package/dist/src/serve/worker-invocation.js +558 -0
  234. package/dist/src/serve/worker-stdin-frame.d.mts +10 -0
  235. package/dist/src/serve/worker-stdin-frame.mjs +107 -0
  236. package/dist/src/sessions/adapter-registry.js +49 -0
  237. package/dist/src/sessions/adapters/claude.js +39 -54
  238. package/dist/src/sessions/adapters/codex.js +82 -67
  239. package/dist/src/sessions/adapters/copilot.js +4 -4
  240. package/dist/src/sessions/adapters/cursor.js +40 -57
  241. package/dist/src/sessions/adapters/deepseek-harness.js +15 -12
  242. package/dist/src/sessions/adapters/factory.js +31 -27
  243. package/dist/src/sessions/adapters/generic.js +43 -9
  244. package/dist/src/sessions/adapters/grok-build.js +11 -11
  245. package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
  246. package/dist/src/sessions/adapters/grokbot.js +434 -24
  247. package/dist/src/sessions/adapters/hermes.js +27 -29
  248. package/dist/src/sessions/adapters/muse-workspace-scan.js +128 -0
  249. package/dist/src/sessions/adapters/muse.js +200 -104
  250. package/dist/src/sessions/adapters/omp.js +28 -14
  251. package/dist/src/sessions/adapters/openclaw.js +89 -79
  252. package/dist/src/sessions/adapters/opencode.js +27 -24
  253. package/dist/src/sessions/adapters/openhuman.js +18 -60
  254. package/dist/src/sessions/adapters/pi.js +30 -14
  255. package/dist/src/sessions/adapters/warp.js +3 -3
  256. package/dist/src/sessions/adapters/windsurf.js +19 -48
  257. package/dist/src/sessions/batch-contracts.js +25 -5
  258. package/dist/src/sessions/batch-import.js +72 -51
  259. package/dist/src/sessions/candidates.js +47 -11
  260. package/dist/src/sessions/contracts.js +75 -2
  261. package/dist/src/sessions/coverage-preflight.js +134 -0
  262. package/dist/src/sessions/discovery.js +3 -0
  263. package/dist/src/sessions/export-plan.js +4 -3
  264. package/dist/src/sessions/grok-build-cli.js +67 -5
  265. package/dist/src/sessions/import-exclusions.js +72 -0
  266. package/dist/src/sessions/import-lease.js +34 -18
  267. package/dist/src/sessions/import-limits.js +37 -0
  268. package/dist/src/sessions/importer.js +84 -46
  269. package/dist/src/sessions/index.js +2 -0
  270. package/dist/src/sessions/lifecycle.js +45 -0
  271. package/dist/src/sessions/policy.js +133 -25
  272. package/dist/src/sessions/readers.js +106 -53
  273. package/dist/src/sessions/refresh.js +106 -0
  274. package/dist/src/sessions/repository.js +199 -63
  275. package/dist/src/sessions/workspace-discovery.js +315 -88
  276. package/dist/src/sessions/workspace-matching.js +107 -0
  277. package/dist/src/skills/adapters/clawhub.js +10 -8
  278. package/dist/src/skills/adapters/openclaw.js +10 -7
  279. package/dist/src/skills/importer.js +1 -0
  280. package/dist/src/smiths/context-pipeline/aiwg-md.js +11 -0
  281. package/dist/src/smiths/context-pipeline/claude-hook.js +3 -26
  282. package/dist/src/smiths/context-pipeline/finalization.js +6 -5
  283. package/dist/src/smiths/context-pipeline/generator.js +21 -4
  284. package/dist/src/smiths/context-pipeline/parallelism-section.js +195 -14
  285. package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
  286. package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
  287. package/dist/src/smiths/mcpsmith/example.js +1 -1
  288. package/dist/src/smiths/mcpsmith/generator.js +1 -1
  289. package/dist/src/smiths/toolsmith/runtime-discovery.d.mts +10 -0
  290. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +85 -31
  291. package/dist/src/storage/backends/fs.js +18 -76
  292. package/dist/src/storage/backends/logseq.js +68 -7
  293. package/dist/src/storage/backends/obsidian.js +1 -0
  294. package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
  295. package/dist/src/testing/generators/test-code-generator.js +57 -30
  296. package/dist/src/tracker/forge-http.js +2 -1
  297. package/dist/src/uhp/client.js +11 -1
  298. package/dist/src/uhp/mission.js +5 -0
  299. package/dist/src/update/checker.d.mts +2 -0
  300. package/dist/src/update/checker.mjs +5 -5
  301. package/dist/src/update/notifier.mjs +54 -2
  302. package/dist/src/update/service.d.mts +22 -0
  303. package/dist/src/utils/contained-filesystem.d.mts +37 -0
  304. package/dist/src/utils/contained-filesystem.mjs +683 -0
  305. package/dist/src/utils/temporary-directory.js +36 -0
  306. package/dist/src/writing/example-generator.js +1 -1
  307. package/dist/src/writing/fidelity.js +18 -1
  308. package/package.json +32 -2
  309. package/schemas/mission-v1.schema.json +2429 -0
  310. package/schemas/models/model-catalog.v1.schema.json +301 -0
  311. package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
  312. package/schemas/models/model-policy.v1.schema.json +14 -0
  313. package/schemas/models/provider-model-capabilities.v1.schema.json +1072 -0
  314. package/tools/_resolve-impl.mjs +39 -2
  315. package/tools/agents/deploy-agents.mjs +64 -23
  316. package/tools/agents/providers/base.mjs +153 -166
  317. package/tools/agents/providers/claude.mjs +8 -24
  318. package/tools/agents/providers/codex.mjs +18 -11
  319. package/tools/agents/providers/cursor.mjs +19 -18
  320. package/tools/agents/providers/grok-build.mjs +3 -1
  321. package/tools/agents/providers/grokbot.mjs +11 -12
  322. package/tools/agents/providers/hermes.mjs +62 -49
  323. package/tools/agents/providers/omp.mjs +5 -2
  324. package/tools/agents/providers/openclaw-translator.mjs +19 -5
  325. package/tools/agents/providers/openclaw.mjs +9 -4
  326. package/tools/agents/providers/pi.mjs +5 -0
  327. package/tools/agents/providers/provider-prepare-channel.mjs +5 -0
  328. package/tools/agents/providers/provider-prepare-coordinator.mjs +247 -0
  329. package/tools/agents/providers/provider-prepare-worker.mjs +84 -0
  330. package/tools/agents/providers/rule-delivery.mjs +1270 -0
  331. package/tools/agents/providers/warp.mjs +20 -26
  332. package/tools/cli/decision-offload-report.mjs +40 -0
  333. package/tools/cli/workspace-status.mjs +862 -0
  334. package/tools/plugin/package-plugins.mjs +186 -8
  335. package/tools/plugin/plugin-links.mjs +114 -0
  336. package/tools/providers/antigravity-transport.mjs +3 -1
  337. package/tools/providers/deepseek-harness-transport.mjs +360 -0
  338. package/tools/providers/omp-transport.mjs +194 -0
  339. package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
  340. package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
  341. package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +1748 -0
  342. package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
  343. package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
  344. package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +55 -0
  345. package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
  346. package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
  347. package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
  348. package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
  349. package/tools/ralph-external/lib/pi-adapter.mjs +329 -0
  350. package/tools/ralph-external/lib/provider-adapter.mjs +748 -0
  351. package/tools/ralph-external/lib/recovery-probe.mjs +72 -0
  352. package/tools/ralph-external/lib/session-environment.mjs +28 -0
  353. package/tools/ralph-external/lib/systemd-client.mjs +49 -0
  354. package/tools/ralph-external/lib/worker-health.mjs +439 -0
  355. package/tools/ralph-external/lib/worker-isolation.mjs +717 -0
  356. package/tools/ralph-external/lib/worker-overflow.mjs +50 -0
  357. package/tools/ralph-external/process-monitor.mjs +1017 -0
  358. package/tools/ralph-external/session-launcher.mjs +5057 -0
  359. package/tools/scripts/resource-preflight.mjs +541 -0
  360. package/tools/skills/deploy-skills-codex.mjs +2 -1
  361. package/vscode-extension/schemas/aiwg.config.v1.json +2916 -0
@@ -0,0 +1,112 @@
1
+ /** Operator-local activation overrides. Canonical rule sources are never mutated. */
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { userConfigFile } from '../config/user-config-dir.mjs';
6
+ import { validateRulesConfig } from './inline-budget.mjs';
7
+
8
+ export const RULE_PIN_TIERS = ['critical', 'high', 'medium', 'low'];
9
+ const read = file => fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf8')) : {};
10
+ export function rulePinConfigPath(cwd, source = 'project', userConfigDir) {
11
+ return source === 'user' ? userConfigFile('aiwg.config', { configDir: userConfigDir }) : path.join(cwd, '.aiwg', 'aiwg.config');
12
+ }
13
+ export function loadRulePinConfigs(cwd, project, userConfigDir) {
14
+ return { project: project ?? read(rulePinConfigPath(cwd)), user: read(rulePinConfigPath(cwd, 'user', userConfigDir)) };
15
+ }
16
+ export const capabilityId = id => id?.replace(/^(framework|addon|extension|plugin):/, '');
17
+ let bundledCapabilities;
18
+ function packageCapabilities() {
19
+ if (bundledCapabilities) return bundledCapabilities;
20
+ let root = path.dirname(fileURLToPath(import.meta.url));
21
+ while (!fs.existsSync(path.join(root, 'package.json')) && path.dirname(root) !== root) root = path.dirname(root);
22
+ const legacy = { 'sdlc-complete': ['sdlc'], 'media-marketing-kit': ['marketing', 'mmk'] };
23
+ bundledCapabilities = [];
24
+ for (const kind of ['frameworks', 'addons', 'extensions', 'plugins']) {
25
+ const dir = path.join(root, 'agentic/code', kind);
26
+ if (!fs.existsSync(dir)) continue;
27
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true }).filter(entry => entry.isDirectory())) {
28
+ let manifest;
29
+ try { manifest = read(path.join(dir, entry.name, 'manifest.json')); } catch { manifest = {}; }
30
+ if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) manifest = {};
31
+ bundledCapabilities.push({ id: entry.name,
32
+ aliases: [...(Array.isArray(manifest.modeAliases) ? manifest.modeAliases : []), ...(Array.isArray(manifest.aliases) ? manifest.aliases : []), ...(legacy[entry.name] || [])],
33
+ bulk: kind !== 'plugins' && entry.name !== 'aiwg-dev' && !manifest.devOnly && !manifest.explicitInstall });
34
+ }
35
+ }
36
+ return bundledCapabilities;
37
+ }
38
+ export function installedRuleCapabilities(configs) {
39
+ const registry = read(process.env.AIWG_USER_REGISTRY_PATH || userConfigFile('installed.json'));
40
+ const entries = { ...registry.installed, ...configs.user?.installed, ...configs.project?.installed };
41
+ if (!Object.keys(entries).length) return [];
42
+ const bundled = Object.values(entries).some(entry => entry?.source !== 'project-local') ? packageCapabilities() : [];
43
+ return [...new Set(Object.entries(entries).flatMap(([id, entry]) => {
44
+ if (entry?.source === 'project-local') return [id];
45
+ if (id === 'all') return bundled.filter(capability => capability.bulk).map(capability => capability.id);
46
+ return [bundled.find(capability => capability.id === id || capability.aliases.includes(id))?.id || id];
47
+ }))].sort();
48
+ }
49
+ export function validateRulePinCapabilities(rules, installed, groups = {}) {
50
+ const errors = validateRulesConfig(rules);
51
+ if (errors.length || !rules) return errors;
52
+ const available = new Set(installed);
53
+ const check = (ids, label) => {
54
+ for (const id of ids || []) if (!available.has(id)) errors.push(`${label}: unknown or uninstalled capability '${id}'. Installed ids: ${installed.join(', ') || '(none)'}`);
55
+ };
56
+ for (const [group, ids] of Object.entries(rules.pin_groups || {})) check(ids, `rules.pin_groups.${group}`);
57
+ for (const selector of rules.always_load || []) {
58
+ check(selector.capabilities, 'rules.always_load');
59
+ if (selector.group) {
60
+ const merged = { ...groups, ...rules.pin_groups };
61
+ if (!Object.hasOwn(merged, selector.group)) errors.push(`rules.always_load: unknown pin group '${selector.group}'`);
62
+ else check(merged[selector.group], `rules.always_load.group.${selector.group}`);
63
+ }
64
+ }
65
+ return errors;
66
+ }
67
+ export function selectorKey(selector) {
68
+ return JSON.stringify(Object.fromEntries(Object.entries(selector).sort(([a], [b]) => a.localeCompare(b))
69
+ .map(([key, value]) => [key, Array.isArray(value) ? [...new Set(value)].sort() : value])));
70
+ }
71
+
72
+ /** OR across selectors, AND within each selector; one result per rule identity.
73
+ * A RelationsReader narrows capability/tier candidates without the full index. */
74
+ export function resolveRulePins({ rules, configs, installed = installedRuleCapabilities(configs), relations = null }) {
75
+ const warnings = [];
76
+ const groups = { ...configs.user?.rules?.pin_groups, ...configs.project?.rules?.pin_groups };
77
+ const pins = new Map();
78
+ const available = new Set(installed);
79
+ const indexedPaths = new Set(Object.values(relations?.index.rules || {}).map(rule => rule.path));
80
+ for (const source of ['user', 'project']) {
81
+ const config = configs[source]?.rules;
82
+ const errors = validateRulesConfig(config);
83
+ if (errors.length) throw new Error(errors.join('\n'));
84
+ for (const error of validateRulePinCapabilities(config, installed, groups)) warnings.push(`${source}: ${error}; inactive capability pins ignored`);
85
+ for (const selector of config?.always_load || []) {
86
+ for (const id of selector.rules || []) if (!rules.some(rule => available.has(capabilityId(rule.capability)) && [rule.id, rule.name, rule.path, rule.file].includes(id))) warnings.push(`${source}: pinned rule '${id}' is absent from installed capabilities; ignored`);
87
+ const capabilities = selector.group ? groups[selector.group] || [] : selector.capabilities || installed;
88
+ const selectedCaps = capabilities.filter(id => available.has(id));
89
+ let candidates;
90
+ if (relations && (selector.enforcement || selector.capabilities || selector.group)) {
91
+ candidates = new Set(selectedCaps.flatMap(id => {
92
+ const keys = Object.keys(relations.index.capabilities).filter(key => capabilityId(key) === id);
93
+ return keys.flatMap(key => relations.rulesForCapability(key, selector.enforcement));
94
+ }).map(id => relations.index.rules[id]?.path));
95
+ }
96
+ for (const rule of rules) {
97
+ if (rule.type === 'behavior' || rule.behavior) continue;
98
+ const cap = capabilityId(rule.capability);
99
+ if (!available.has(cap)) continue;
100
+ if (!selectedCaps.includes(cap)) continue;
101
+ if (selector.rules && !selector.rules.some(id => [rule.id, rule.name, rule.path, rule.file].includes(id))) continue;
102
+ if (selector.enforcement && !selector.enforcement.includes(rule.enforcement?.toLowerCase())) continue;
103
+ if (candidates && selector.enforcement && indexedPaths.has(rule.indexedPath || rule.path) && !candidates.has(rule.path) && !candidates.has(rule.indexedPath)) continue;
104
+ const id = rule.id || rule.path || rule.file || rule.name;
105
+ const pin = pins.get(id) || { ...rule, id, canonical_activation: rule.activation, activation: 'kernel', matches: [] };
106
+ if (!pin.matches.some(match => match.source === source && selectorKey(match.selector) === selectorKey(selector))) pin.matches.push({ source, selector });
107
+ pins.set(id, pin);
108
+ }
109
+ }
110
+ }
111
+ return { rules: [...pins.values()].sort((a, b) => a.id.localeCompare(b.id)), warnings: [...new Set(warnings)] };
112
+ }
@@ -0,0 +1,197 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://aiwg.io/schemas/rules/rule-frontmatter.v1.schema.json",
4
+ "title": "Rule activation frontmatter",
5
+ "description": "ADR rule activation contract. Other existing discovery metadata is preserved. Missing activation is permitted only by the migration parser, which warns and infers tier delivery.",
6
+ "type": "object",
7
+ "required": [
8
+ "activation"
9
+ ],
10
+ "additionalProperties": true,
11
+ "properties": {
12
+ "activation": {
13
+ "type": "string",
14
+ "enum": [
15
+ "kernel",
16
+ "summary",
17
+ "bound",
18
+ "paths",
19
+ "on-demand"
20
+ ]
21
+ },
22
+ "summary": {
23
+ "type": "string",
24
+ "pattern": "^[^\\r\\n\\u0085\\u2028\\u2029]*\\S[^\\r\\n\\u0085\\u2028\\u2029]*$",
25
+ "description": "A nonempty single-line imperative, <=240 Unicode code points after trimming. Imperative mood is reviewed by authors.",
26
+ "allOf": [
27
+ {
28
+ "pattern": "^\\s*\\S(?:[^\\r\\n\\u0085\\u2028\\u2029]{0,238}\\S)?\\s*$"
29
+ }
30
+ ]
31
+ },
32
+ "bound_to": {
33
+ "type": "object",
34
+ "additionalProperties": false,
35
+ "properties": {
36
+ "skills": {
37
+ "type": "array",
38
+ "items": {
39
+ "type": "string",
40
+ "pattern": "^(?!.*(?:^|/)\\.\\.?(/|$))[A-Za-z0-9_][A-Za-z0-9_.:-]*(?:/[A-Za-z0-9_][A-Za-z0-9_.:-]*)*$"
41
+ }
42
+ },
43
+ "agents": {
44
+ "type": "array",
45
+ "items": {
46
+ "type": "string",
47
+ "pattern": "^(?!.*(?:^|/)\\.\\.?(/|$))[A-Za-z0-9_][A-Za-z0-9_.:-]*(?:/[A-Za-z0-9_][A-Za-z0-9_.:-]*)*$"
48
+ }
49
+ },
50
+ "flows": {
51
+ "type": "array",
52
+ "items": {
53
+ "type": "string",
54
+ "pattern": "^(?!.*(?:^|/)\\.\\.?(/|$))[A-Za-z0-9_][A-Za-z0-9_.:-]*(?:/[A-Za-z0-9_][A-Za-z0-9_.:-]*)*$"
55
+ }
56
+ }
57
+ }
58
+ },
59
+ "paths": {
60
+ "type": "array",
61
+ "minItems": 1,
62
+ "items": {
63
+ "type": "string",
64
+ "pattern": "^(?![A-Za-z]:)(?!/)(?!.*\\\\)(?!.*(?:^|/)\\.\\.(?:/|$))(?=.*\\S)[^\\r\\n]+$"
65
+ }
66
+ },
67
+ "enforcedBy": {
68
+ "description": "Opaque reserved metadata for #2839. Has no activation or runtime enforcement effect."
69
+ }
70
+ },
71
+ "allOf": [
72
+ {
73
+ "if": {
74
+ "properties": {
75
+ "activation": {
76
+ "enum": [
77
+ "summary",
78
+ "bound",
79
+ "paths"
80
+ ]
81
+ }
82
+ }
83
+ },
84
+ "then": {
85
+ "required": [
86
+ "summary"
87
+ ],
88
+ "properties": {
89
+ "summary": {}
90
+ }
91
+ }
92
+ },
93
+ {
94
+ "if": {
95
+ "properties": {
96
+ "activation": {
97
+ "enum": [
98
+ "kernel",
99
+ "on-demand"
100
+ ]
101
+ }
102
+ }
103
+ },
104
+ "then": {
105
+ "not": {
106
+ "required": [
107
+ "bound_to"
108
+ ],
109
+ "properties": {
110
+ "bound_to": {}
111
+ }
112
+ }
113
+ }
114
+ },
115
+ {
116
+ "if": {
117
+ "properties": {
118
+ "activation": {
119
+ "const": "paths"
120
+ }
121
+ }
122
+ },
123
+ "then": {
124
+ "required": [
125
+ "paths"
126
+ ],
127
+ "properties": {
128
+ "paths": {}
129
+ }
130
+ },
131
+ "else": {
132
+ "not": {
133
+ "required": [
134
+ "paths"
135
+ ],
136
+ "properties": {
137
+ "paths": {}
138
+ }
139
+ }
140
+ }
141
+ },
142
+ {
143
+ "if": {
144
+ "properties": {
145
+ "activation": {
146
+ "const": "bound"
147
+ }
148
+ }
149
+ },
150
+ "then": {
151
+ "required": [
152
+ "bound_to"
153
+ ],
154
+ "properties": {
155
+ "bound_to": {
156
+ "type": "object",
157
+ "anyOf": [
158
+ {
159
+ "required": [
160
+ "skills"
161
+ ],
162
+ "properties": {
163
+ "skills": {
164
+ "type": "array",
165
+ "minItems": 1
166
+ }
167
+ }
168
+ },
169
+ {
170
+ "required": [
171
+ "agents"
172
+ ],
173
+ "properties": {
174
+ "agents": {
175
+ "type": "array",
176
+ "minItems": 1
177
+ }
178
+ }
179
+ },
180
+ {
181
+ "required": [
182
+ "flows"
183
+ ],
184
+ "properties": {
185
+ "flows": {
186
+ "type": "array",
187
+ "minItems": 1
188
+ }
189
+ }
190
+ }
191
+ ]
192
+ }
193
+ }
194
+ }
195
+ }
196
+ ]
197
+ }
@@ -646,37 +646,29 @@ export class ExecutorRegistry extends EventEmitter {
646
646
  pickByFilter(filter, longRunning = false) {
647
647
  const candidates = [...this.executors.values()].filter((e) => e.connected);
648
648
  const rejected = [];
649
- // If executor_id is pinned, target it directly
649
+ // A pin selects an identity; it cannot waive the same controls used by automatic routing.
650
+ const rejection = (executor) => {
651
+ if (longRunning && !executor.capabilities.includes('resumable')) {
652
+ return 'long_running requires resumable capability';
653
+ }
654
+ const missing = (filter.capabilities ?? []).filter(capability => !executor.capabilities.includes(capability));
655
+ if (missing.length > 0)
656
+ return `missing capabilities: ${missing.join(', ')}`;
657
+ return undefined;
658
+ };
650
659
  if (filter.executor_id) {
651
660
  const pinned = this.executors.get(filter.executor_id);
652
- if (!pinned) {
653
- return null;
654
- }
655
- if (!pinned.connected) {
656
- return null;
657
- }
658
- if (longRunning && !pinned.capabilities.includes('resumable')) {
661
+ if (!pinned?.connected || rejection(pinned))
659
662
  return null;
660
- }
661
663
  return { executor: pinned, reason: 'pinned by executor_id', rejected: [] };
662
664
  }
663
- // Filter by required capabilities
664
665
  const filtered = [];
665
666
  for (const executor of candidates) {
666
- // Long-running requires resumable
667
- if (longRunning && !executor.capabilities.includes('resumable')) {
668
- rejected.push({ executorId: executor.executorId, reason: 'long_running requires resumable capability' });
669
- continue;
670
- }
671
- // All requested capabilities must be present
672
- if (filter.capabilities && filter.capabilities.length > 0) {
673
- const missing = filter.capabilities.filter((c) => !executor.capabilities.includes(c));
674
- if (missing.length > 0) {
675
- rejected.push({ executorId: executor.executorId, reason: `missing capabilities: ${missing.join(', ')}` });
676
- continue;
677
- }
678
- }
679
- filtered.push(executor);
667
+ const reason = rejection(executor);
668
+ if (reason)
669
+ rejected.push({ executorId: executor.executorId, reason });
670
+ else
671
+ filtered.push(executor);
680
672
  }
681
673
  if (filtered.length === 0)
682
674
  return null;
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { routeMission } from './agent-router.js';
12
12
  import { StackAdapterRegistry } from './stack-adapters.js';
13
+ import { assertMissionWorkerHandoff } from '../mission-protocol/codecs.js';
13
14
  const terminalFailures = new Set(['failed', 'cancelled', 'timed-out']);
14
15
  const reviewStates = new Set(['unknown', 'operator-review-required']);
15
16
  function lifecycleSatisfied(kind, state, health) {
@@ -114,6 +115,14 @@ export class FleetMissionConductor {
114
115
  this.ledgerStore = options.ledgerStore;
115
116
  }
116
117
  async conduct(plan, pool, resumeFrom) {
118
+ assertMissionWorkerHandoff(plan, 'fleet-conductor');
119
+ for (const cycle of plan.cycles)
120
+ assertMissionWorkerHandoff(cycle, 'fleet-conductor');
121
+ if (resumeFrom) {
122
+ assertMissionWorkerHandoff(resumeFrom, 'fleet-conductor');
123
+ for (const cycle of resumeFrom.cycles)
124
+ assertMissionWorkerHandoff(cycle, 'fleet-conductor');
125
+ }
117
126
  const priorById = new Map((resumeFrom?.cycles ?? []).map((cycle) => [cycle.cycleId, cycle]));
118
127
  const ledger = {
119
128
  missionId: plan.missionId,
@@ -24,8 +24,7 @@
24
24
  */
25
25
  import { routeMission } from './agent-router.js';
26
26
  import { StackAdapterRegistry } from './stack-adapters.js';
27
- const defaultRunWorker = () => ({ output: undefined, cost: 0 });
28
- const defaultScore = (r) => (r.output ? r.output.length : 0);
27
+ import { assertMissionWorkerHandoff } from '../mission-protocol/codecs.js';
29
28
  /**
30
29
  * The cross-stack Mission conductor. Decomposes a Mission into worker cycles,
31
30
  * dispatches each to an executor of the chosen runtime via `routeMission`, and
@@ -35,10 +34,12 @@ export class MissionConductor {
35
34
  adapters;
36
35
  runWorker;
37
36
  scoreOutput;
37
+ scorerId;
38
38
  constructor(opts = {}) {
39
39
  this.adapters = opts.adapters ?? new StackAdapterRegistry();
40
- this.runWorker = opts.runWorker ?? defaultRunWorker;
41
- this.scoreOutput = opts.scoreOutput ?? defaultScore;
40
+ this.runWorker = opts.runWorker;
41
+ this.scoreOutput = opts.scoreOutput;
42
+ this.scorerId = opts.scoreOutput ? (opts.scorerId ?? 'custom') : null;
42
43
  }
43
44
  /**
44
45
  * Conduct a Mission across the given executor pool. Returns the ledger.
@@ -46,6 +47,14 @@ export class MissionConductor {
46
47
  * crash-resilient resume path; their prior results are carried forward.
47
48
  */
48
49
  async conduct(plan, pool, resumeFrom) {
50
+ assertMissionWorkerHandoff(plan, 'mission-conductor');
51
+ for (const cycle of plan.cycles)
52
+ assertMissionWorkerHandoff(cycle, 'mission-conductor');
53
+ if (resumeFrom) {
54
+ assertMissionWorkerHandoff(resumeFrom, 'mission-conductor');
55
+ for (const cycle of resumeFrom.cycles)
56
+ assertMissionWorkerHandoff(cycle, 'mission-conductor');
57
+ }
49
58
  if (plan.cycles.some((cycle) => cycle.graph) && !plan.graph) {
50
59
  throw new Error('Graph-projected worker cycles require MissionPlan.graph identity.');
51
60
  }
@@ -60,6 +69,8 @@ export class MissionConductor {
60
69
  missionId: plan.missionId,
61
70
  goal: plan.goal,
62
71
  completionCriterion: plan.completionCriterion,
72
+ executionMode: this.runWorker ? 'executed' : 'plan-only',
73
+ scorerId: this.scorerId,
63
74
  activityLog: [],
64
75
  cycles: [],
65
76
  totalCost: 0,
@@ -68,6 +79,7 @@ export class MissionConductor {
68
79
  ...(plan.graph ? { graph: structuredClone(plan.graph) } : {}),
69
80
  };
70
81
  ledger.activityLog.push(`mission ${plan.missionId} start — goal: ${plan.goal} — ${plan.cycles.length} cycle(s)` +
82
+ ` — mode: ${ledger.executionMode}, scorer: ${ledger.scorerId ?? '(none)'}` +
71
83
  (resumeFrom ? ` (resume: ${carried.size} carried)` : ''));
72
84
  for (const cycle of plan.cycles) {
73
85
  const graph = plan.graph && cycle.graph ? {
@@ -125,6 +137,20 @@ export class MissionConductor {
125
137
  const executor = routing.selected.executor;
126
138
  const invocation = adapter.invoke(cycle.prompt, graph);
127
139
  ledger.activityLog.push(`cycle ${cycle.id} → executor ${executor.name} (${executor.executorId}) on ${cycle.runtime}: ${invocation.describe}`);
140
+ if (!this.runWorker) {
141
+ ledger.cycles.push({
142
+ cycleId: cycle.id,
143
+ runtime: cycle.runtime,
144
+ primitive: adapter.primitive,
145
+ executorId: executor.executorId,
146
+ routed: true,
147
+ reason: 'plan-only: worker not configured; execution pending',
148
+ cost: 0,
149
+ ...(graph ? { graph } : {}),
150
+ });
151
+ ledger.activityLog.push(`cycle ${cycle.id} PLANNED on ${cycle.runtime} — execution pending`);
152
+ continue;
153
+ }
128
154
  let output;
129
155
  let cost = 0;
130
156
  try {
@@ -164,23 +190,32 @@ export class MissionConductor {
164
190
  ledger.totalCost += cost;
165
191
  ledger.activityLog.push(`cycle ${cycle.id} done on ${cycle.runtime} (cost ${cost})`);
166
192
  }
167
- // Pending = cycles neither completed nor failed (none, here — full pass).
193
+ // Planned cycles remain pending until a worker executes them.
168
194
  const accounted = new Set([...ledger.checkpoint.completed, ...ledger.checkpoint.failed]);
169
195
  ledger.checkpoint.pending = plan.cycles.map((c) => c.id).filter((id) => !accounted.has(id));
170
196
  // Cross-stack aggregation: distinct runtimes that actually ran a worker.
171
197
  ledger.runtimesUsed = [
172
- ...new Set(ledger.cycles.filter((c) => c.routed).map((c) => c.runtime)),
198
+ ...new Set(ledger.cycles.filter((c) => c.routed && accounted.has(c.cycleId)).map((c) => c.runtime)),
173
199
  ];
174
200
  // Best-output selection (REF-015) — conductor-side, across stacks.
175
201
  let best;
176
- for (const c of ledger.cycles) {
177
- if (!c.output)
178
- continue;
179
- const score = this.scoreOutput(c);
180
- if (!best || score > best.score) {
181
- best = { cycleId: c.cycleId, runtime: c.runtime, output: c.output, score };
202
+ if (this.scoreOutput) {
203
+ for (const c of ledger.cycles) {
204
+ if (c.output === undefined)
205
+ continue;
206
+ const score = this.scoreOutput(c);
207
+ if (!Number.isFinite(score)) {
208
+ ledger.activityLog.push(`cycle ${c.cycleId} UNSCORED — scorer ${this.scorerId} returned a non-finite score`);
209
+ continue;
210
+ }
211
+ if (!best || score > best.score) {
212
+ best = { cycleId: c.cycleId, runtime: c.runtime, output: c.output, score };
213
+ }
182
214
  }
183
215
  }
216
+ else {
217
+ ledger.activityLog.push('best-output unavailable: no scorer configured');
218
+ }
184
219
  ledger.bestOutput = best;
185
220
  ledger.activityLog.push(`mission ${plan.missionId} end — completed ${ledger.checkpoint.completed.length}, ` +
186
221
  `failed ${ledger.checkpoint.failed.length}, runtimes [${ledger.runtimesUsed.join(', ')}], ` +
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from 'node:fs';
12
12
  import { dirname } from 'node:path';
13
+ import { assertMissionWorkerHandoff } from '../mission-protocol/codecs.js';
13
14
  export class InMemoryAdmissionStore {
14
15
  snapshot = { revision: 0, records: {} };
15
16
  transact(mutate) {
@@ -88,6 +89,7 @@ export class SharedHostScheduler {
88
89
  }
89
90
  }
90
91
  submit(request) {
92
+ assertMissionWorkerHandoff(request, 'managed-admission');
91
93
  this.validateRequest(request);
92
94
  return this.store.transact(snapshot => {
93
95
  const existing = snapshot.records[request.requestId];