@aiwg/cli 2026.10.1 → 2026.10.3

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 (166) hide show
  1. package/agentic/code/providers/capability-matrix.yaml +270 -0
  2. package/agentic/code/providers/model-capabilities.v1.json +3091 -24
  3. package/bin/aiwg.mjs +86 -21
  4. package/dist/src/a2a/codecs.js +9 -0
  5. package/dist/src/artifacts/corpus-tools/vision-extract.js +105 -15
  6. package/dist/src/artifacts/repair.js +9 -4
  7. package/dist/src/channel/manager.mjs +59 -10
  8. package/dist/src/cli/child-process-result.js +40 -0
  9. package/dist/src/cli/env.js +38 -16
  10. package/dist/src/cli/flag-parsing.js +236 -0
  11. package/dist/src/cli/handlers/decision.js +210 -4
  12. package/dist/src/cli/handlers/diagnose.js +9 -2
  13. package/dist/src/cli/handlers/feedback.js +14 -5
  14. package/dist/src/cli/handlers/init.js +245 -30
  15. package/dist/src/cli/handlers/mc.js +23 -0
  16. package/dist/src/cli/handlers/models.js +69 -6
  17. package/dist/src/cli/handlers/ralph.js +3 -0
  18. package/dist/src/cli/handlers/refresh.js +16 -0
  19. package/dist/src/cli/handlers/regenerate.js +14 -0
  20. package/dist/src/cli/handlers/runtime-info.js +24 -9
  21. package/dist/src/cli/handlers/script-runner.js +16 -6
  22. package/dist/src/cli/handlers/session.js +396 -62
  23. package/dist/src/cli/handlers/sessions.js +146 -40
  24. package/dist/src/cli/handlers/setup-manifest.js +439 -39
  25. package/dist/src/cli/handlers/setup.js +139 -39
  26. package/dist/src/cli/handlers/subcommands.js +3 -1
  27. package/dist/src/cli/handlers/team.js +18 -8
  28. package/dist/src/cli/handlers/use.js +13 -0
  29. package/dist/src/cli/handlers/utilities.js +106 -23
  30. package/dist/src/cli/prompt-utils.js +72 -0
  31. package/dist/src/cli/provider-resolution.js +11 -0
  32. package/dist/src/config/aiwg-config.js +268 -4
  33. package/dist/src/config/cli.js +146 -19
  34. package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
  35. package/dist/src/config/project-artifacts-health.mjs +14 -3
  36. package/dist/src/config/user-config.js +36 -10
  37. package/dist/src/decision/adapters/jev.js +75 -27
  38. package/dist/src/decision/driver.js +3 -1
  39. package/dist/src/decision/entry.js +38 -6
  40. package/dist/src/decision/heldout/collector.js +10 -1
  41. package/dist/src/decision/index.js +1 -0
  42. package/dist/src/decision/interop.js +60 -8
  43. package/dist/src/decision/ledger.js +839 -0
  44. package/dist/src/decision/validate.js +6 -3
  45. package/dist/src/effects/dispatch-verifier.js +252 -0
  46. package/dist/src/effects/index.js +1 -0
  47. package/dist/src/features/installer.js +2 -2
  48. package/dist/src/flow/graph-metadata.js +5 -0
  49. package/dist/src/gates/providers/loader.js +3 -1
  50. package/dist/src/installation/manager-command.mjs +1 -1
  51. package/dist/src/installation/manager.mjs +17 -2
  52. package/dist/src/lint/runner.js +2 -2
  53. package/dist/src/mcp/adapters/codex-runtime.js +360 -56
  54. package/dist/src/mcp/cli.mjs +587 -77
  55. package/dist/src/mcp/config-file.mjs +279 -0
  56. package/dist/src/mcp/config-layers.mjs +348 -0
  57. package/dist/src/mcp/credentials.mjs +484 -0
  58. package/dist/src/mcp/grok-build-config.mjs +16 -26
  59. package/dist/src/mcp/helpers.mjs +106 -2
  60. package/dist/src/mcp/omp-config.mjs +50 -29
  61. package/dist/src/mcp/profiles.js +97 -23
  62. package/dist/src/mcp/profiles.mjs +99 -27
  63. package/dist/src/mcp/registry.js +264 -57
  64. package/dist/src/mcp/registry.mjs +198 -45
  65. package/dist/src/mcp/server.mjs +403 -20
  66. package/dist/src/mcp/toml-string.mjs +9 -0
  67. package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
  68. package/dist/src/mcp/tool-filters.mjs +357 -0
  69. package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
  70. package/dist/src/mcp/tools/decision.mjs +21 -3
  71. package/dist/src/mcp/tools/orchestration.mjs +38 -0
  72. package/dist/src/mcp/tools/subsystems.mjs +39 -8
  73. package/dist/src/mcp/tools/worker-invoke.mjs +1539 -0
  74. package/dist/src/mcp/tools/worker-shell-control.mjs +258 -0
  75. package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
  76. package/dist/src/memory/project-registry.js +2 -2
  77. package/dist/src/mission-protocol/codecs.js +639 -1
  78. package/dist/src/mission-protocol/types.js +110 -0
  79. package/dist/src/mission-protocol/worker-status.js +2 -0
  80. package/dist/src/models/config-loader.js +70 -13
  81. package/dist/src/models/grok-build-models.js +93 -41
  82. package/dist/src/models/model-capabilities.v1.json +3091 -24
  83. package/dist/src/models/model-discovery.js +862 -63
  84. package/dist/src/models/provider-policy.js +625 -11
  85. package/dist/src/models/qualification-digest.mjs +17 -0
  86. package/dist/src/models/resolver.js +259 -0
  87. package/dist/src/models/worker-direct-readiness.js +529 -0
  88. package/dist/src/models/worker-dispatch-offer.js +169 -0
  89. package/dist/src/models/worker-health-readiness.js +131 -0
  90. package/dist/src/models/worker-installation.mjs +879 -0
  91. package/dist/src/models/wrapper-route.js +18 -0
  92. package/dist/src/ops/registry.js +9 -14
  93. package/dist/src/plugins/standalone-packager.js +4 -3
  94. package/dist/src/process/bounded-child-process.mjs +387 -0
  95. package/dist/src/process/cli-command.mjs +75 -0
  96. package/dist/src/providers/capability-matrix.js +8 -0
  97. package/dist/src/providers/capability-matrix.yaml +270 -0
  98. package/dist/src/providers/grok-build-headless.js +43 -21
  99. package/dist/src/providers/provider-definitions.js +9 -1
  100. package/dist/src/providers/provider-definitions.mjs +9 -2
  101. package/dist/src/serve/executor-registry.js +16 -24
  102. package/dist/src/serve/fleet-mission-conductor.js +9 -0
  103. package/dist/src/serve/mission-conductor.js +9 -0
  104. package/dist/src/serve/shared-host-scheduler.js +2 -0
  105. package/dist/src/serve/worker-invocation.js +538 -0
  106. package/dist/src/serve/worker-stdin-frame.mjs +107 -0
  107. package/dist/src/sessions/adapter-registry.js +45 -0
  108. package/dist/src/sessions/adapters/generic.js +37 -3
  109. package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
  110. package/dist/src/sessions/adapters/grokbot.js +423 -24
  111. package/dist/src/sessions/adapters/muse-workspace-scan.js +108 -0
  112. package/dist/src/sessions/adapters/muse.js +68 -29
  113. package/dist/src/sessions/adapters/pi.js +1 -0
  114. package/dist/src/sessions/batch-contracts.js +13 -1
  115. package/dist/src/sessions/batch-import.js +23 -42
  116. package/dist/src/sessions/candidates.js +47 -11
  117. package/dist/src/sessions/contracts.js +35 -0
  118. package/dist/src/sessions/coverage-preflight.js +134 -0
  119. package/dist/src/sessions/discovery.js +3 -0
  120. package/dist/src/sessions/grok-build-cli.js +67 -5
  121. package/dist/src/sessions/importer.js +24 -8
  122. package/dist/src/sessions/index.js +2 -0
  123. package/dist/src/sessions/repository.js +54 -13
  124. package/dist/src/sessions/workspace-discovery.js +99 -37
  125. package/dist/src/skills/adapters/clawhub.js +10 -8
  126. package/dist/src/skills/adapters/openclaw.js +10 -7
  127. package/dist/src/smiths/context-pipeline/parallelism-section.js +192 -3
  128. package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
  129. package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
  130. package/dist/src/smiths/mcpsmith/example.js +1 -1
  131. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +10 -14
  132. package/dist/src/storage/backends/logseq.js +68 -7
  133. package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
  134. package/dist/src/testing/generators/test-code-generator.js +57 -30
  135. package/dist/src/uhp/client.js +11 -1
  136. package/dist/src/uhp/mission.js +5 -0
  137. package/dist/src/update/checker.mjs +5 -5
  138. package/dist/src/update/notifier.mjs +54 -2
  139. package/dist/src/writing/fidelity.js +18 -1
  140. package/package.json +18 -1
  141. package/schemas/mission-v1.schema.json +2429 -0
  142. package/schemas/models/model-catalog.v1.schema.json +301 -0
  143. package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
  144. package/schemas/models/model-policy.v1.schema.json +14 -0
  145. package/schemas/models/provider-model-capabilities.v1.schema.json +1066 -0
  146. package/tools/_resolve-impl.mjs +39 -0
  147. package/tools/agents/deploy-agents.mjs +15 -2
  148. package/tools/agents/providers/base.mjs +49 -32
  149. package/tools/agents/providers/grokbot.mjs +11 -12
  150. package/tools/agents/providers/hermes.mjs +6 -3
  151. package/tools/agents/providers/omp.mjs +5 -2
  152. package/tools/agents/providers/openclaw-translator.mjs +19 -5
  153. package/tools/providers/deepseek-harness-transport.mjs +358 -0
  154. package/tools/providers/omp-transport.mjs +192 -0
  155. package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
  156. package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
  157. package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
  158. package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
  159. package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
  160. package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
  161. package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
  162. package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
  163. package/tools/ralph-external/lib/pi-adapter.mjs +333 -0
  164. package/tools/ralph-external/lib/provider-adapter.mjs +690 -0
  165. package/tools/ralph-external/lib/worker-health.mjs +439 -0
  166. package/vscode-extension/schemas/aiwg.config.v1.json +1953 -0
@@ -15,6 +15,22 @@ version: "1.0"
15
15
  providers:
16
16
  claude-code:
17
17
  display_name: Claude Code
18
+ aliases:
19
+ - claude
20
+ route_feasibility:
21
+ scope: in
22
+ identity: runtime-configured-only
23
+ evidence: H
24
+ channel: "claude -p --output-format stream-json --verbose; terminal result extraction"
25
+ fanout: unknown
26
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
27
+ coverage:
28
+ profile_issue: "roctinam/aiwg#2900"
29
+ source_date: "2026-10-08"
30
+ live_qualified: false
31
+ sources:
32
+ - "host-help: claude 2.1.295 on titan (--version/--help only)"
33
+ - "tools/ralph-external/lib/claude-adapter.mjs"
18
34
  status: stable
19
35
  daemon_tier: unsupported
20
36
  daemon_pty_adapter: false
@@ -77,6 +93,20 @@ providers:
77
93
 
78
94
  codex:
79
95
  display_name: OpenAI Codex
96
+ route_feasibility:
97
+ scope: in
98
+ identity: runtime-configured-only
99
+ evidence: H
100
+ channel: "codex debug models + exec --json -o F thread/turn/item/error event stream"
101
+ fanout: unknown
102
+ probe_budget: { status: authorized, calls: 3, tokens: 50000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
103
+ coverage:
104
+ profile_issue: "roctinam/aiwg#2897"
105
+ source_date: "2026-10-08"
106
+ live_qualified: false
107
+ sources:
108
+ - "host-help: codex-cli 0.161.0 on titan (--version/--help only); `codex mcp-server --help` still prints root help"
109
+ - "tools/ralph-external/lib/codex-adapter.mjs"
80
110
  aliases:
81
111
  - openai
82
112
  status: stable
@@ -146,6 +176,21 @@ providers:
146
176
 
147
177
  copilot:
148
178
  display_name: GitHub Copilot
179
+ aliases:
180
+ - github-copilot
181
+ route_feasibility:
182
+ scope: in
183
+ identity: runtime-configured-only
184
+ evidence: D
185
+ channel: "copilot -p --output-format json; scoped --allow-tool permissions"
186
+ fanout: unknown
187
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
188
+ coverage:
189
+ profile_issue: "roctinam/aiwg#2901"
190
+ source_date: "2026-10-08"
191
+ live_qualified: false
192
+ sources:
193
+ - "https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-programmatic-reference"
149
194
  status: stable
150
195
  daemon_tier: unsupported
151
196
  daemon_pty_adapter: false
@@ -181,6 +226,21 @@ providers:
181
226
 
182
227
  factory:
183
228
  display_name: Factory AI
229
+ aliases:
230
+ - factory-ai
231
+ route_feasibility:
232
+ scope: in
233
+ identity: runtime-configured-only
234
+ evidence: R
235
+ channel: "droid exec --output-format stream-json; terminal parser to qualify"
236
+ fanout: unknown
237
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
238
+ coverage:
239
+ profile_issue: "roctinam/aiwg#2902"
240
+ source_date: "2026-10-07"
241
+ live_qualified: false
242
+ sources:
243
+ - "tools/ralph-external/lib/factory-adapter.mjs"
184
244
  status: stable
185
245
  # droid CLI runs headless via `droid exec`; AIWG daemon provides persistence layer
186
246
  daemon_tier: unsupported
@@ -217,6 +277,20 @@ providers:
217
277
 
218
278
  cursor:
219
279
  display_name: Cursor IDE
280
+ route_feasibility:
281
+ scope: in
282
+ identity: runtime-configured-only
283
+ evidence: D
284
+ channel: "agent -p --output-format json; sandbox/permission profile to qualify"
285
+ fanout: unknown
286
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
287
+ coverage:
288
+ profile_issue: "roctinam/aiwg#2903"
289
+ source_date: "2026-10-08"
290
+ live_qualified: false
291
+ sources:
292
+ - "https://cursor.com/docs/cli/overview"
293
+ - "https://cursor.com/docs/cli/reference/output-format"
220
294
  status: stable
221
295
  # Cursor requires a display server (VS Code extension host) — daemon not supported
222
296
  daemon_tier: unsupported
@@ -253,6 +327,20 @@ providers:
253
327
 
254
328
  opencode:
255
329
  display_name: OpenCode
330
+ route_feasibility:
331
+ scope: in
332
+ identity: runtime-configured-only
333
+ evidence: R
334
+ channel: "opencode run --format json; JSONL framing to qualify"
335
+ fanout: unknown
336
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
337
+ coverage:
338
+ profile_issue: "roctinam/aiwg#2904"
339
+ source_date: "2026-10-07"
340
+ live_qualified: false
341
+ sources:
342
+ - "tools/ralph-external/lib/opencode-adapter.mjs"
343
+ - "https://opencode.ai/docs/cli/"
256
344
  status: stable
257
345
  daemon_tier: unsupported
258
346
  daemon_pty_adapter: false
@@ -288,6 +376,19 @@ providers:
288
376
 
289
377
  warp:
290
378
  display_name: Warp Terminal
379
+ route_feasibility:
380
+ scope: in
381
+ identity: runtime-configured-only
382
+ evidence: D
383
+ channel: "oz agent run --prompt/--model/--cwd/--profile; stdout capture"
384
+ fanout: unknown
385
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
386
+ coverage:
387
+ profile_issue: "roctinam/aiwg#2905"
388
+ source_date: "2026-10-08"
389
+ live_qualified: false
390
+ sources:
391
+ - "https://docs.warp.dev/agents/cli/oz-cli/"
291
392
  status: stable
292
393
  daemon_tier: unsupported
293
394
  daemon_pty_adapter: false
@@ -324,6 +425,28 @@ providers:
324
425
 
325
426
  windsurf:
326
427
  display_name: Devin Desktop
428
+ aliases:
429
+ - devin
430
+ - devin-desktop
431
+ - devin-local
432
+ - cascade
433
+ route_feasibility:
434
+ scope: out
435
+ identity: unavailable
436
+ evidence: R
437
+ channel: "none - no verified headless Desktop worker command; recheck B-OG-47"
438
+ fanout: unknown
439
+ probe_budget: { status: authorized, calls: 1, tokens: 0, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
440
+ coverage:
441
+ profile_issue: null
442
+ source_date: "2026-10-08"
443
+ live_qualified: false
444
+ sources:
445
+ - "src/providers/provider-definitions.ts#windsurf"
446
+ - "https://docs.devin.ai/cli/reference/commands.md"
447
+ - "https://docs.devin.ai/_llms/en/desktop.md"
448
+ exclusion_gap: "Devin Desktop documents no headless worker command and no worker-serving MCP tool; its MCP settings configure clients, IDE startup is not inference."
449
+ recheck: "Rechecked 2026-10-08: Desktop unchanged, still OUT. Devin CLI documents `devin -p/--print`, `--model`, `--prompt-file`, `--permission-mode` and `--sandbox` (no JSON output or effort flag found; `devin acp` is ACP, `devin mcp` manages client servers). Devin CLI stays a distinct future-provider surface, not a windsurf alias, until registry support exists."
327
450
  status: stable
328
451
  # Devin Desktop uses the Windsurf compatibility surface and requires a VS Code host — daemon not supported
329
452
  daemon_tier: unsupported
@@ -361,6 +484,25 @@ providers:
361
484
 
362
485
  grokbot:
363
486
  display_name: Grok Bot
487
+ route_feasibility:
488
+ scope: out
489
+ identity: unavailable
490
+ evidence: R
491
+ channel: "none - desktop CreateAgent is not a headless subprocess contract; recheck B-OG-47"
492
+ fanout: unknown
493
+ probe_budget: { status: authorized, calls: 1, tokens: 0, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
494
+ coverage:
495
+ profile_issue: null
496
+ source_date: "2026-10-08"
497
+ live_qualified: false
498
+ sources:
499
+ - "src/providers/provider-definitions.ts#grokbot"
500
+ - "https://docs.x.ai/grok-bot/overview.md"
501
+ - "https://docs.x.ai/grok-bot/skills-routines-and-automations.md"
502
+ - "https://docs.x.ai/grok-bot/computer-and-apps.md"
503
+ - "https://docs.x.ai/grok-bot/faq.md"
504
+ exclusion_gap: "Grok Bot runs Bots on xAI-hosted computers driven from desktop/mobile chat, routines and connectors; no documented local CLI, headless subprocess or worker-serving MCP tool."
505
+ recheck: "Rechecked 2026-10-08 against the official Grok Bot docs: no change, still OUT. Third-party bridges are not official interfaces and were not evaluated; desktop CreateAgent names are never synthesized into a command."
364
506
  status: stable
365
507
  # Multi-agent desktop assistant runtime. Distinct from Cursor IDE and from
366
508
  # xAI Grok Build / API. Native skill root is operator-configured via
@@ -403,6 +545,19 @@ providers:
403
545
 
404
546
  grok-build:
405
547
  display_name: Grok Build
548
+ route_feasibility:
549
+ scope: in
550
+ identity: runtime-configured-only
551
+ evidence: R
552
+ channel: "grok -p --output-format streaming-json; bounded parser + model/effort pinning"
553
+ fanout: unknown
554
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
555
+ coverage:
556
+ profile_issue: "roctinam/aiwg#2906"
557
+ source_date: "2026-10-07"
558
+ live_qualified: false
559
+ sources:
560
+ - "src/providers/grok-build-headless.ts"
406
561
  status: experimental
407
562
  # xAI Grok Build CLI/TUI. Distinct from Grok Bot (`grokbot`).
408
563
  # #2577: fixture-backed native subagents and background tasks; see
@@ -448,6 +603,20 @@ providers:
448
603
 
449
604
  hermes:
450
605
  display_name: Hermes
606
+ route_feasibility:
607
+ scope: in
608
+ identity: runtime-configured-only
609
+ evidence: H
610
+ channel: "hermes -z plain final + --usage-file; session-filtered log binding"
611
+ fanout: unknown
612
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
613
+ coverage:
614
+ profile_issue: "roctinam/aiwg#2912"
615
+ source_date: "2026-10-07"
616
+ live_qualified: false
617
+ sources:
618
+ - "host-help: hermes 0.20.6 on titan (2026-10-07 observation; not rechecked in this pass)"
619
+ - "/usr/local/lib/hermes-agent/mcp_serve.py"
451
620
  status: stable
452
621
  daemon_tier: unsupported
453
622
  daemon_pty_adapter: false
@@ -488,6 +657,22 @@ providers:
488
657
 
489
658
  muse:
490
659
  display_name: Muse Code
660
+ route_feasibility:
661
+ scope: in
662
+ identity: runtime-configured-only
663
+ evidence: H
664
+ channel: "model-catalog JSON + exec --json invocation-bound session logs"
665
+ fanout: unknown
666
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
667
+ coverage:
668
+ profile_issue: "roctinam/aiwg#2898"
669
+ source_date: "2026-10-08"
670
+ live_qualified: false
671
+ sources:
672
+ - "host-help: Muse Code 1.4.4 (1.4.4-R5419.1) on titan (--version/--help only)"
673
+ - "tools/ralph-external/lib/muse-adapter.mjs"
674
+ - "test/fixtures/providers/muse/direct-manifest.json (synthetic only; strict finals/live controls remain unqualified)"
675
+ - "docs/providers/muse-ralph-exec.md (manual smoke run and S1 blockers)"
491
676
  status: stable
492
677
  # Meta's terminal/CI coding agent (Muse Spark-powered). Explicitly not a
493
678
  # model-API surface: Glimmer/Image/Voice are out of scope.
@@ -534,6 +719,19 @@ providers:
534
719
 
535
720
  openclaw:
536
721
  display_name: OpenClaw
722
+ route_feasibility:
723
+ scope: in
724
+ identity: runtime-configured-only
725
+ evidence: D
726
+ channel: "openclaw agent exec --json; workspace/settings mapping to qualify"
727
+ fanout: unknown
728
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
729
+ coverage:
730
+ profile_issue: "roctinam/aiwg#2907"
731
+ source_date: "2026-10-08"
732
+ live_qualified: false
733
+ sources:
734
+ - "https://docs.openclaw.ai/cli/agent"
537
735
  status: stable
538
736
  daemon_tier: unsupported
539
737
  daemon_pty_adapter: false
@@ -567,6 +765,25 @@ providers:
567
765
 
568
766
  openhuman:
569
767
  display_name: OpenHuman
768
+ aliases:
769
+ - tinyhumansai
770
+ route_feasibility:
771
+ scope: in
772
+ identity: runtime-configured-only
773
+ evidence: D
774
+ channel: "openhuman-core --model M call --method openhuman.agent_chat --params-stdin; conductor-framed params JSON on stdin to EOF, final JSON stdout, no event stream"
775
+ fanout: unknown
776
+ probe_budget: { status: proposed, calls: 3, tokens: 30000 }
777
+ coverage:
778
+ profile_issue: "roctinam/aiwg#2911"
779
+ source_date: "2026-10-08"
780
+ live_qualified: false
781
+ sources:
782
+ - "https://github.com/tinyhumansai/openhuman/blob/216ea322a3c1269dada70751ac5c08eac7dc7596/crates/openhuman-core/src/core/cli.rs"
783
+ - "https://github.com/tinyhumansai/openhuman/blob/216ea322a3c1269dada70751ac5c08eac7dc7596/crates/openhuman-core/src/agent/schemas.rs"
784
+ - "https://github.com/tinyhumansai/openhuman/blob/216ea322a3c1269dada70751ac5c08eac7dc7596/crates/openhuman-core/src/mcp/server/tools/specs.rs"
785
+ - "https://github.com/tinyhumansai/openhuman/releases/tag/v0.64.14"
786
+ recheck: "Rechecked 2026-10-08 and promoted into S1 (doc/source-only, unqualified): `openhuman-core --model M call --method openhuman.agent_chat --params-stdin` reads the `message`, `model_override` and `cwd` params as JSON from stdin until EOF, runs one in-process agent turn and prints the JSON result on stdout; the conductor frames the params from the brief so prompt text never enters argv. Profile pinned to 0.64.14; live qualification is an open S1 blocker (not installed on an authorized host, budget proposed). Effort, step cap, approval/sandbox mapping and child fan-out are unknown. Native `openhuman-core mcp` `agent.run_subagent` takes only `agent_id`/`prompt` (no model, effort or workspace pin) and may nest subagents, so it is not a qualifying worker MCP tool."
570
787
  status: experimental
571
788
  # tinyhumansai/openhuman — OSS personal-AI runtime (Rust core + Tauri shell).
572
789
  # AIWG-convention-aware out of the box (.agents/, AGENTS.md, .claude/, .codex/).
@@ -605,6 +822,20 @@ providers:
605
822
 
606
823
  antigravity:
607
824
  display_name: Google Antigravity CLI
825
+ route_feasibility:
826
+ scope: in
827
+ identity: runtime-configured-only
828
+ evidence: R
829
+ channel: "agy -p stream-json per provider-contract; fixture-qualified flags only"
830
+ fanout: unknown
831
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
832
+ coverage:
833
+ profile_issue: "roctinam/aiwg#2908"
834
+ source_date: "2026-10-07"
835
+ live_qualified: false
836
+ sources:
837
+ - "agentic/code/providers/antigravity/provider-contract.v1.json"
838
+ - "https://antigravity.google/docs/cli/headless/"
608
839
  aliases:
609
840
  - agy
610
841
  status: experimental
@@ -650,6 +881,19 @@ providers:
650
881
 
651
882
  deepseek-harness:
652
883
  display_name: DeepSeek Harness
884
+ route_feasibility:
885
+ scope: in
886
+ identity: runtime-configured-only
887
+ evidence: R
888
+ channel: "dsh --profile headless + validated Cordis route patch; no guessed --model flag"
889
+ fanout: unknown
890
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
891
+ coverage:
892
+ profile_issue: "roctinam/aiwg#2909"
893
+ source_date: "2026-10-07"
894
+ live_qualified: false
895
+ sources:
896
+ - "tools/ralph-external/lib/deepseek-harness-adapter.mjs"
653
897
  aliases:
654
898
  - dsh
655
899
  status: experimental
@@ -692,6 +936,19 @@ providers:
692
936
 
693
937
  pi:
694
938
  display_name: Pi Coding Agent
939
+ route_feasibility:
940
+ scope: in
941
+ identity: runtime-configured-only
942
+ evidence: R
943
+ channel: "pi --mode json --model/--thinking/--tools; closed stdin, no RPC abort"
944
+ fanout: unknown
945
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
946
+ coverage:
947
+ profile_issue: "roctinam/aiwg#2910"
948
+ source_date: "2026-10-07"
949
+ live_qualified: false
950
+ sources:
951
+ - "tools/ralph-external/lib/pi-adapter.mjs"
695
952
  aliases:
696
953
  - pi-coding-agent
697
954
  status: experimental
@@ -733,6 +990,19 @@ providers:
733
990
 
734
991
  omp:
735
992
  display_name: Oh My Pi
993
+ route_feasibility:
994
+ scope: in
995
+ identity: runtime-configured-only
996
+ evidence: R
997
+ channel: "omp --mode json --model/--thinking/--profile; --no-tools for text-only"
998
+ fanout: unknown
999
+ probe_budget: { status: authorized, calls: 3, tokens: 30000, authorized_by: operator, authorized_at: "2026-10-07", hosts: [titan, noodle] }
1000
+ coverage:
1001
+ profile_issue: "roctinam/aiwg#2910"
1002
+ source_date: "2026-10-07"
1003
+ live_qualified: false
1004
+ sources:
1005
+ - "tools/ralph-external/lib/omp-adapter.mjs"
736
1006
  aliases:
737
1007
  - oh-my-pi
738
1008
  status: experimental
@@ -20,10 +20,12 @@ function scrubEvent(event, env) {
20
20
  return JSON.parse(redactGrokOutput(JSON.stringify(event), env));
21
21
  }
22
22
  function isTerminal(event) {
23
- return ['result', 'error', 'complete', 'completed'].includes(String(event.type ?? event.event ?? ''));
23
+ return event.type === 'end' || event.type === 'error';
24
24
  }
25
25
  function isError(event) {
26
- return event.is_error === true || event.error !== undefined || ['error', 'failed'].includes(String(event.type ?? event.event ?? ''));
26
+ return event.type === 'error' || event.is_error === true || event.error != null
27
+ || (event.type === 'end' && event.stopReason !== 'end_turn')
28
+ || (['tool_call', 'tool_call_update'].includes(String(event.type)) && event.status === 'failed');
27
29
  }
28
30
  function stopProcess(child) {
29
31
  if (child.pid && process.platform !== 'win32') {
@@ -44,7 +46,7 @@ export async function runGrokHeadless(options) {
44
46
  const timeoutMs = Math.min(Math.max(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, 1), MAX_TIMEOUT_MS);
45
47
  const maxBytes = Math.min(Math.max(options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT, 1024), DEFAULT_MAX_OUTPUT);
46
48
  const env = options.env ?? process.env;
47
- const args = [...(options.prefixArgs ?? []), '--no-auto-update', ...(options.disableSubagents ? ['--no-subagents'] : []), '-p', options.prompt, '--output-format', format];
49
+ const args = [...(options.prefixArgs ?? []), ...(options.disableSubagents ? ['--no-subagents'] : []), '-p', options.prompt, '--output-format', format];
48
50
  return new Promise((resolve, reject) => {
49
51
  const child = spawn(options.command ?? 'grok', args, {
50
52
  cwd: options.cwd,
@@ -88,7 +90,7 @@ export async function runGrokHeadless(options) {
88
90
  if (format === 'json') {
89
91
  try {
90
92
  const parsed = JSON.parse(cleanStdout);
91
- if (isError(parsed))
93
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed) || isError(parsed) || parsed.stopReason !== 'end_turn')
92
94
  throw new Error('Grok Build returned a JSON error result');
93
95
  events.push(parsed);
94
96
  }
@@ -105,7 +107,40 @@ export async function runGrokHeadless(options) {
105
107
  if (options.signal?.aborted)
106
108
  abort();
107
109
  child.on('error', error => finish(new Error(`Grok Build headless launch failed: ${error.message}`)));
110
+ const acceptEvent = (event) => {
111
+ if (settled)
112
+ return;
113
+ if (!event || typeof event !== 'object' || Array.isArray(event)) {
114
+ finish(new Error('Invalid Grok Build streaming-json event'));
115
+ return;
116
+ }
117
+ // ACP end is always last. Failure is latched across the whole stream.
118
+ if (terminalSeen) {
119
+ finish(new Error('Grok Build event after terminal event'));
120
+ return;
121
+ }
122
+ const safe = scrubEvent(event, env);
123
+ events.push(safe);
124
+ options.onEvent?.(safe);
125
+ if (isError(safe))
126
+ terminalError = true;
127
+ if (isTerminal(safe)) {
128
+ terminalSeen = true;
129
+ // Some builds leave background work attached after end. Allow a
130
+ // short drain, then terminate the process group.
131
+ drainTimer ??= setTimeout(() => {
132
+ if (pending.trim()) {
133
+ finish(new Error('Invalid trailing Grok Build streaming-json event'));
134
+ return;
135
+ }
136
+ stopProcess(child);
137
+ finish(undefined, terminalError ? 1 : 0);
138
+ }, 300);
139
+ }
140
+ };
108
141
  child.stdout.on('data', (chunk) => {
142
+ if (settled)
143
+ return;
109
144
  bytes += chunk.length;
110
145
  if (bytes > maxBytes) {
111
146
  finish(new Error(`Grok Build headless output exceeded ${maxBytes} bytes`));
@@ -130,17 +165,9 @@ export async function runGrokHeadless(options) {
130
165
  finish(new Error('Invalid Grok Build streaming-json event'));
131
166
  return;
132
167
  }
133
- const safe = scrubEvent(event, env);
134
- events.push(safe);
135
- options.onEvent?.(safe);
136
- if (isError(safe))
137
- terminalError = true;
138
- if (isTerminal(safe)) {
139
- terminalSeen = true;
140
- // Some provider builds leave background work attached after the
141
- // result. Allow a short drain, then terminate the process group.
142
- drainTimer ??= setTimeout(() => { stopProcess(child); finish(undefined, terminalError ? 1 : 0); }, 300);
143
- }
168
+ acceptEvent(event);
169
+ if (settled)
170
+ return;
144
171
  }
145
172
  });
146
173
  child.stderr.on('data', (chunk) => {
@@ -151,12 +178,7 @@ export async function runGrokHeadless(options) {
151
178
  child.on('close', code => {
152
179
  if (format === 'streaming-json' && pending.trim()) {
153
180
  try {
154
- const event = scrubEvent(JSON.parse(pending), env);
155
- events.push(event);
156
- if (isError(event))
157
- terminalError = true;
158
- if (isTerminal(event))
159
- terminalSeen = true;
181
+ acceptEvent(JSON.parse(pending));
160
182
  }
161
183
  catch {
162
184
  finish(new Error('Invalid trailing Grok Build streaming-json event'));
@@ -362,7 +362,15 @@ const BUILT_IN_SEEDS = [
362
362
  builtIn: true,
363
363
  surfaces: { primary: 'claude-code', compatibility: ['claude'], precedence: ['.claude/', 'CLAUDE.md'], related: [] },
364
364
  detection: {
365
- env: ['CLAUDE_CODE_VERSION', 'ANTHROPIC_API_KEY'],
365
+ // CLAUDECODE / CLAUDE_CODE_ENTRYPOINT / CLAUDE_CODE_DESKTOP_APP_VERSION
366
+ // are the markers current Claude Code (CLI and Desktop Code tab)
367
+ // actually sets; confirmed empirically in both a CLI session and a
368
+ // Desktop Code-tab session (docs/planning/claude-desktop-provider/
369
+ // assessment-and-issue-plan.md §2.1). `CLAUDE_CODE_VERSION` is not set
370
+ // by current Claude Code, and `ANTHROPIC_API_KEY` is a false-positive
371
+ // signal — any non-Claude session with that key set would otherwise
372
+ // identify as `claude` (#2627).
373
+ env: ['CLAUDECODE', 'CLAUDE_CODE_ENTRYPOINT', 'CLAUDE_CODE_DESKTOP_APP_VERSION'],
366
374
  process: ['claude-code', 'claude'],
367
375
  capabilityId: 'claude-code',
368
376
  runtimeEnvPriority: 100,
@@ -26,9 +26,9 @@ const MCP_INJECTION_DEFINITIONS = [
26
26
  providerId: 'claude-code',
27
27
  includeInSupportedProviders: true,
28
28
  configFormat: 'json',
29
- serverConfigFormat: 'standard',
29
+ serverConfigFormat: 'claude-code',
30
30
  serversKey: 'mcpServers',
31
- configPath: { scope: 'project', path: '.claude/settings.local.json' },
31
+ configPath: { scope: 'project', path: '.mcp.json' },
32
32
  supportsEphemeral: true,
33
33
  },
34
34
  },
@@ -178,10 +178,17 @@ export function listMcpInjectProviderIds() {
178
178
  }
179
179
 
180
180
  export function resolveMcpConfigPath(provider, projectDir = '.', options = {}) {
181
+ if (normalizeRuntimeProviderId(provider) === 'codex' && process.env.CODEX_HOME) {
182
+ return resolve(process.env.CODEX_HOME, 'config.toml');
183
+ }
181
184
  if (normalizeRuntimeProviderId(provider) === 'antigravity' && options.scope === 'user') {
182
185
  const home = process.env.HOME || process.env.USERPROFILE || homedir();
183
186
  return resolve(home, '.gemini/config/mcp_config.json');
184
187
  }
188
+ if (normalizeRuntimeProviderId(provider) === 'claude-code' && options.scope === 'user') {
189
+ const home = process.env.HOME || process.env.USERPROFILE || homedir();
190
+ return resolve(home, '.claude.json');
191
+ }
185
192
  if (normalizeRuntimeProviderId(provider) === 'omp' && options.scope === 'user') {
186
193
  return resolve(resolveOmpPaths(options).agentDir, 'mcp.json');
187
194
  }
@@ -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,6 +24,7 @@
24
24
  */
25
25
  import { routeMission } from './agent-router.js';
26
26
  import { StackAdapterRegistry } from './stack-adapters.js';
27
+ import { assertMissionWorkerHandoff } from '../mission-protocol/codecs.js';
27
28
  const defaultRunWorker = () => ({ output: undefined, cost: 0 });
28
29
  const defaultScore = (r) => (r.output ? r.output.length : 0);
29
30
  /**
@@ -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
  }
@@ -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];