@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
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Direct-worker dispatch opt-in offer (#3050).
3
+ *
4
+ * `parallelism.worker_dispatch` is off by default (#1359) and nothing told a
5
+ * user it exists, showed whether their machine could use it, or offered to
6
+ * turn it on. This module is the single shared place that decides whether
7
+ * any setup surface should offer it, and renders the matching prompt/hint
8
+ * text — every surface (`aiwg init`, `aiwg setup project`, `aiwg regenerate`,
9
+ * `aiwg refresh`, `aiwg doctor --probe-workers`) calls it instead of growing
10
+ * its own copy.
11
+ *
12
+ * Detection is presence-only: each known worker-CLI executable (from the
13
+ * shipped provider capability registry's `workerAdapter` /
14
+ * `workerHealthAdapter` process invocations — the same provider ->
15
+ * executable mapping `resolveDirectBinding()` in `worker-direct-readiness.ts`
16
+ * resolves bindings from) is checked for a match on `PATH` only. No process
17
+ * is spawned and no network call is made. This is deliberately narrower
18
+ * than `worker-direct-readiness.ts`'s version probes
19
+ * (`probeDirectWorkerVersion` / `boundedVersionProbe`), which spawn
20
+ * `<executable> ...versionArgv` and are opt-in behind `--probe-workers`;
21
+ * the offer only needs to know a CLI is present, so it never pays that cost
22
+ * or crosses that trust boundary.
23
+ */
24
+ import { accessSync, constants as fsConstants, statSync } from 'node:fs';
25
+ import { delimiter, join } from 'node:path';
26
+ import { loadProviderModelCapabilities } from './provider-policy.js';
27
+ /**
28
+ * The one command every hint/prompt points at to flip the setting on — this
29
+ * is also the real re-enable path after a decline: enabling dispatch
30
+ * directly always clears the offer (see {@link evaluateWorkerDispatchOffer}),
31
+ * so there is no separate "undo the decline" command to document.
32
+ */
33
+ export const WORKER_DISPATCH_ENABLE_COMMAND = 'aiwg config set --project parallelism.worker_dispatch true';
34
+ /** Readiness check shared by setup hints and dispatch refusals. */
35
+ export const WORKER_DISPATCH_READINESS_COMMAND = 'aiwg doctor --probe-workers';
36
+ /**
37
+ * Dotted config path a decline is recorded at. A setup/onboarding
38
+ * preference, not worker policy — kept out of `parallelism`, which is a
39
+ * frozen contract fragment (B-OG-29, #3050 review).
40
+ */
41
+ export const WORKER_DISPATCH_DECLINE_FIELD = 'setup.worker_dispatch_offer';
42
+ /** Minimum number of distinct detected worker CLIs before any surface offers. */
43
+ const MIN_DETECTED_FOR_OFFER = 2;
44
+ /**
45
+ * Presence-only PATH check for one executable name: no spawn, no network.
46
+ * Requires a regular file (symlinks are followed by `statSync`) before the
47
+ * execute-permission check — an `X_OK` search-permission bit also succeeds
48
+ * for a directory, so without this a directory on `PATH` that merely shares
49
+ * a worker CLI's name would count as installed (#3050 review item 8).
50
+ */
51
+ function executableOnPath(name, pathEnv) {
52
+ const dirs = (pathEnv ?? '').split(delimiter).filter(Boolean);
53
+ const candidates = process.platform === 'win32' ? [`${name}.exe`, `${name}.cmd`, `${name}.bat`, name] : [name];
54
+ return dirs.some(dir => candidates.some(candidate => {
55
+ const target = join(dir, candidate);
56
+ try {
57
+ if (!statSync(target).isFile())
58
+ return false;
59
+ accessSync(target, fsConstants.X_OK);
60
+ return true;
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ }));
66
+ }
67
+ /**
68
+ * Every known worker-CLI executable name declared by the shipped capability
69
+ * registry, deduplicated and sorted. Mirrors the same provider -> executable
70
+ * mapping `worker-direct-readiness.ts`'s `resolveDirectBinding()` resolves
71
+ * at dispatch time (`workerAdapter` falling back to `workerHealthAdapter`),
72
+ * so this list can never drift from what the resolver would actually bind.
73
+ */
74
+ export function knownWorkerCliExecutables(registry = loadProviderModelCapabilities()) {
75
+ const names = new Set();
76
+ for (const provider of Object.values(registry.providers)) {
77
+ const adapter = provider.workerAdapter ?? provider.workerHealthAdapter;
78
+ if (adapter?.invocation.kind === 'process')
79
+ names.add(adapter.invocation.executable);
80
+ }
81
+ return [...names].sort();
82
+ }
83
+ /**
84
+ * Which known worker CLIs are present on `PATH` right now. Presence-only:
85
+ * never spawns a process and never makes a network call. `registry` and
86
+ * `pathEnv` are both injectable so callers (and tests) never depend on
87
+ * whichever CLIs happen to be installed on the running host.
88
+ */
89
+ export function detectInstalledWorkerClis(options = {}) {
90
+ const executables = knownWorkerCliExecutables(options.registry);
91
+ const pathEnv = options.pathEnv ?? process.env.PATH;
92
+ return executables.filter(executable => executableOnPath(executable, pathEnv));
93
+ }
94
+ /**
95
+ * Should any setup surface offer or hint turning `worker_dispatch` on?
96
+ * `false` whenever it is already on, or the offer was previously declined
97
+ * (`setup.worker_dispatch_offer === 'declined'`) — a user who said no is
98
+ * not asked again on every run (#3050 item 3). Otherwise `true` once two or
99
+ * more known worker CLIs are detected.
100
+ *
101
+ * `parallelism` and `setup` are deliberately separate parameters, not one
102
+ * merged config object: `parallelism` is the frozen worker-policy contract
103
+ * fragment (B-OG-29) and must never gain fields for setup preferences; the
104
+ * decline itself lives in `setup`, a plain onboarding-preferences block.
105
+ */
106
+ export function evaluateWorkerDispatchOffer(parallelism, setup, detected) {
107
+ if (parallelism?.worker_dispatch === true)
108
+ return { shouldOffer: false, detected };
109
+ if (setup?.worker_dispatch_offer === 'declined')
110
+ return { shouldOffer: false, detected };
111
+ return { shouldOffer: detected.length >= MIN_DETECTED_FOR_OFFER, detected };
112
+ }
113
+ /**
114
+ * One-line interactive yes/no question naming the detected CLIs. Callers
115
+ * MUST default the answer to `false` (no) — see #3050's "never enable
116
+ * without an explicit yes" constraint.
117
+ */
118
+ export function workerDispatchOfferQuestion(detected) {
119
+ return ` Detected worker CLIs (${detected.join(', ')}). Enable direct worker dispatch so AIWG `
120
+ + `can dispatch tasks to them directly, using their own accounts' quota? [y/N]: `;
121
+ }
122
+ /**
123
+ * One-line non-interactive / regenerate / refresh / doctor hint. Never
124
+ * prompts and never changes anything by itself — it only names the enable
125
+ * command and the readiness check that confirms the CLIs are actually
126
+ * launchable.
127
+ */
128
+ export function workerDispatchOfferHint(detected) {
129
+ return `Direct worker dispatch is off; detected worker CLIs: ${detected.join(', ')}. `
130
+ + `Enable with \`${WORKER_DISPATCH_ENABLE_COMMAND}\` (then check readiness with \`${WORKER_DISPATCH_READINESS_COMMAND}\`).`;
131
+ }
132
+ /**
133
+ * Accepted values for the `--worker-dispatch` argument (#3062). Only
134
+ * `aiwg init` and `aiwg setup project` accept this argument directly — it
135
+ * answers the same question `askWorkerDispatchOffer`/`applyInteractivePrompts`
136
+ * would otherwise ask interactively, so those two commands can be run
137
+ * headless without leaving the offer unanswerable.
138
+ */
139
+ export const WORKER_DISPATCH_ARG_VALUES = ['enable', 'decline'];
140
+ /**
141
+ * Parse a raw `--worker-dispatch` flag value. `undefined` in means the flag
142
+ * was not given at all (not an error — the question is still asked/hinted
143
+ * as before). Any other value that isn't exactly `enable`/`decline` throws,
144
+ * naming the accepted values; callers should map that to a non-zero exit.
145
+ *
146
+ * This is accepted even when fewer than two worker CLIs are detected — an
147
+ * explicit `--worker-dispatch` choice is honored regardless of the
148
+ * presence-only CLI detection `evaluateWorkerDispatchOffer` otherwise gates
149
+ * the interactive question/hint on.
150
+ */
151
+ export function parseWorkerDispatchArg(raw) {
152
+ if (raw === undefined)
153
+ return undefined;
154
+ if (!WORKER_DISPATCH_ARG_VALUES.includes(raw)) {
155
+ throw new Error(`--worker-dispatch must be one of: ${WORKER_DISPATCH_ARG_VALUES.join(', ')} (got ${JSON.stringify(raw)})`);
156
+ }
157
+ return raw;
158
+ }
159
+ /**
160
+ * Hint variant for the two surfaces (`aiwg init`, `aiwg setup project`) that
161
+ * accept `--worker-dispatch` directly (#3062): same base hint, plus the
162
+ * argument itself, so a headless run without a terminal and without the
163
+ * argument names both the config command and the argument that would have
164
+ * answered the question directly.
165
+ */
166
+ export function workerDispatchOfferHintWithArg(detected) {
167
+ return `${workerDispatchOfferHint(detected)} Or pass --worker-dispatch enable|decline to this command directly.`;
168
+ }
169
+ //# sourceMappingURL=worker-dispatch-offer.js.map
@@ -0,0 +1,131 @@
1
+ /** Offline S1 health readiness projection; never launch authority or a probe. */
2
+ import { validateParallelismConfig, resolveWorkerGroupInstallation, workerConfigDigest } from '../config/aiwg-config.js';
3
+ import { assertWorkerHealthQualification } from './provider-policy.js';
4
+ import { resolveWorkerPlan } from './resolver.js';
5
+ import { resolveWorkerEffectiveHealth } from '../serve/worker-invocation.js';
6
+ const repairAction = (code, pointer) => {
7
+ if (pointer === '/worker/observedAt')
8
+ return 'refresh-worker-catalog';
9
+ if (code === 'OG_EFFORT_DENIED')
10
+ return 'select-qualified-effort';
11
+ if (code === 'OG_MODEL_UNAPPROVED')
12
+ return 'review-model-policy-and-freshness';
13
+ if (code === 'OG_PIN_MISMATCH')
14
+ return 'review-exact-wrapper-pin';
15
+ if (code === 'OG_BUDGET_UNMEASURABLE')
16
+ return 'qualify-budget-enforcement';
17
+ if (code === 'OG_ADAPTER_UNQUALIFIED')
18
+ return 'qualify-installation-and-profile';
19
+ return 'review-worker-configuration';
20
+ };
21
+ export function diagnoseWorkerHealthReadiness(snapshot, request) {
22
+ const p = snapshot.config.parallelism;
23
+ const report = { enabled: p?.worker_dispatch === true,
24
+ ready: true, contextDigest: null, findings: [], thresholds: [] };
25
+ const add = (finding) => { report.findings.push(finding); };
26
+ if (!report.enabled) {
27
+ add({ code: 'WORKER_HEALTH_DISABLED', status: 'info', pointer: '/parallelism/worker_dispatch',
28
+ message: 'Group dispatch is disabled; legacy execution has no worker health readiness requirement.',
29
+ nextAction: 'none', role: null });
30
+ return report;
31
+ }
32
+ report.contextDigest = workerConfigDigest({ context: request.context, modelDigests: snapshot.modelDigests });
33
+ const errors = validateParallelismConfig(p);
34
+ if (errors.length) {
35
+ report.ready = false;
36
+ for (const message of errors)
37
+ add({ code: 'OG_CONFIG_REFERENCE', status: 'error',
38
+ pointer: '/parallelism', message, nextAction: 'review-worker-configuration', role: null });
39
+ return report;
40
+ }
41
+ if (p?.worker_mode === 'managed') {
42
+ add({ code: 'WORKER_HEALTH_MANAGED_DEFERRED', status: 'info', pointer: '/parallelism/worker_mode',
43
+ message: 'Managed admission and health enforcement are deferred to S2+; this check covers direct readiness.',
44
+ nextAction: 'use-direct-checkpoint', role: null });
45
+ return report;
46
+ }
47
+ const enabledGroups = Object.values(p?.groups ?? {});
48
+ const required = new Set(enabledGroups.flatMap(group => group.requiredRoles ?? []));
49
+ const roles = new Set([...Object.keys(snapshot.models.defaults.workerSelection?.roleGuidance ?? {}), ...required]);
50
+ if (!roles.size) {
51
+ report.ready = false;
52
+ add({ code: 'OG_CONFIG_REFERENCE', status: 'error', pointer: '/defaults/workerSelection/roleGuidance',
53
+ message: 'No worker role guidance is configured; onboarding cannot offer a qualified route.',
54
+ nextAction: 'configure-role-guidance', role: null });
55
+ }
56
+ const installations = new Set(enabledGroups.flatMap(group => group.members.filter(member => member.enabled !== false).map(member => member.cli)));
57
+ for (const cli of installations) {
58
+ if (!p?.clis?.[cli]?.quotaScope)
59
+ add({ code: 'WORKER_QUOTA_SCOPE_UNKNOWN', status: 'warn', role: null,
60
+ pointer: `/parallelism/clis/${cli}/quotaScope`,
61
+ message: 'No explicit quota/account correlation scope; shared aliases cannot establish independent upstream capacity.',
62
+ nextAction: 'configure-qualified-quota-scope' });
63
+ }
64
+ for (const role of roles) {
65
+ const plan = resolveWorkerPlan(snapshot, { ...request, role: role });
66
+ const isRequired = required.has(role);
67
+ const diagnostics = [...plan.diagnostics, ...plan.exclusions.flatMap(item => item.diagnostics)];
68
+ const seen = new Set();
69
+ for (const diagnostic of diagnostics) {
70
+ const key = `${diagnostic.code}:${diagnostic.pointer}:${diagnostic.message}`;
71
+ if (seen.has(key))
72
+ continue;
73
+ seen.add(key);
74
+ add({ ...diagnostic, status: diagnostic.blocking === false ? 'info' : 'warn', role,
75
+ nextAction: repairAction(diagnostic.code, diagnostic.pointer) });
76
+ }
77
+ if (!plan.selected) {
78
+ if (isRequired)
79
+ report.ready = false;
80
+ add({ code: 'WORKER_ROLE_NOT_READY', status: isRequired ? 'error' : 'warn', role,
81
+ pointer: `/defaults/workerSelection/roleGuidance/${role}`,
82
+ message: `${isRequired ? 'Required' : 'Optional'} role has no qualified route; request-time launch remains blocked.`,
83
+ nextAction: 'qualify-role-route' });
84
+ continue;
85
+ }
86
+ const tuple = plan.selected;
87
+ try {
88
+ const { adapter } = resolveWorkerGroupInstallation(p, tuple.cli, snapshot.registry);
89
+ const profile = adapter.invocationProfiles[tuple.profile];
90
+ const binding = snapshot.installations[tuple.cli];
91
+ const model = snapshot.catalog.discovery?.instances?.[tuple.cli]?.models.find(row => row.id === tuple.model || row.apiModelId === tuple.model);
92
+ assertWorkerHealthQualification(profile, { profileRef: tuple.profile, cliVersion: binding.cliVersion,
93
+ accountScope: binding.accountScope, inferenceProvider: tuple.inferenceProvider, model: model?.apiModelId ?? tuple.model, effort: tuple.effort });
94
+ const nativeSteps = profile.controls.stepCap?.support === 'native';
95
+ if (p?.health?.requireStepCap && !nativeSteps) {
96
+ if (isRequired)
97
+ report.ready = false;
98
+ add({ code: 'WORKER_STEP_CAP_NOT_READY', status: isRequired ? 'error' : 'warn', role,
99
+ pointer: '/parallelism/health/requireStepCap',
100
+ message: 'Required step cap lacks native enforcement or qualified runtime pre-step admission evidence.',
101
+ nextAction: 'qualify-step-enforcement' });
102
+ continue;
103
+ }
104
+ // External admission needs runtime gate evidence; a config declaration alone cannot prove it.
105
+ const health = resolveWorkerEffectiveHealth(p?.health, { role, effort: tuple.effort,
106
+ modelKey: tuple.modelKey, profileRef: tuple.profile, wallSeconds: plan.ceilings.wallSeconds ?? 1800,
107
+ stepEnforcement: nativeSteps ? 'native' : 'unavailable' });
108
+ report.thresholds.push({ role, group: tuple.group, member: tuple.member, health });
109
+ if (!profile.health || profile.health.handshake !== 'semantic' || profile.health.coverage !== 'full') {
110
+ add({ code: 'WORKER_HEALTH_DEGRADED', status: 'warn', role,
111
+ pointer: `/parallelism/clis/${tuple.cli}/invocationProfile`,
112
+ message: 'Profile has degraded or unobserved health coverage; progress and stop evidence may be unavailable.',
113
+ nextAction: 'qualify-health-signals' });
114
+ }
115
+ add({ code: 'WORKER_ROLE_ELIGIBLE', status: 'ok', role,
116
+ pointer: `/defaults/workerSelection/roleGuidance/${role}`,
117
+ message: 'Policy route is eligible; launch still requires current installation and task qualification.',
118
+ nextAction: 'resolve-current-task' });
119
+ }
120
+ catch {
121
+ if (isRequired)
122
+ report.ready = false;
123
+ add({ code: 'WORKER_HEALTH_UNQUALIFIED', status: isRequired ? 'error' : 'warn', role,
124
+ pointer: `/parallelism/clis/${tuple.cli}/invocationProfile`,
125
+ message: 'Health profile scope or effective settings are invalid; requalify the exact version/account/model/effort.',
126
+ nextAction: 'qualify-health-signals' });
127
+ }
128
+ }
129
+ return report;
130
+ }
131
+ //# sourceMappingURL=worker-health-readiness.js.map