@aiwg/cli 2026.9.18 → 2026.9.19

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 (35) hide show
  1. package/dist/src/api/index.d.ts +1 -0
  2. package/dist/src/api/index.js +1 -0
  3. package/dist/src/artifacts/index-builder.js +44 -9
  4. package/dist/src/artifacts/query-engine.js +4 -1
  5. package/dist/src/artifacts/types.js +3 -0
  6. package/dist/src/cli/handlers/bot-handoff.js +35 -0
  7. package/dist/src/cli/handlers/build-verify.js +50 -0
  8. package/dist/src/cli/handlers/index.js +5 -1
  9. package/dist/src/cli/handlers/provider-command-options.js +24 -0
  10. package/dist/src/cli/services/deployment-verification.js +8 -5
  11. package/dist/src/decision/adapters/jev.js +515 -0
  12. package/dist/src/decision/adapters/llm-subagent.js +174 -0
  13. package/dist/src/decision/compose.js +54 -0
  14. package/dist/src/decision/convert.js +14 -0
  15. package/dist/src/decision/entry.js +183 -0
  16. package/dist/src/decision/evaluate.js +508 -0
  17. package/dist/src/decision/export.js +16 -0
  18. package/dist/src/decision/index.js +12 -0
  19. package/dist/src/decision/predicates.js +74 -0
  20. package/dist/src/decision/receipts.js +291 -0
  21. package/dist/src/decision/types.js +3 -0
  22. package/dist/src/decision/validate.js +303 -0
  23. package/dist/src/extensions/commands/definitions.js +20 -0
  24. package/dist/src/providers/bot-handoff.js +83 -0
  25. package/dist/src/providers/grokbot-handoff-guidance.js +26 -0
  26. package/dist/src/providers/grokbot-natives/connector-install-profile.js +59 -0
  27. package/dist/src/providers/grokbot-natives/create-agent.js +54 -0
  28. package/dist/src/providers/grokbot-natives/evidence.js +92 -0
  29. package/dist/src/providers/grokbot-natives/flags.js +47 -0
  30. package/dist/src/providers/grokbot-natives/index.js +67 -0
  31. package/dist/src/providers/grokbot-natives/memory-reference-helper.js +114 -0
  32. package/dist/src/providers/grokbot-natives/registered-machine-health.js +51 -0
  33. package/dist/src/providers/grokbot-natives/routines.js +57 -0
  34. package/dist/src/providers/grokbot-natives/types.js +20 -0
  35. package/package.json +1 -1
@@ -24,6 +24,7 @@ export * from '../writing/contextual-diagnostics.js';
24
24
  export * from '../schema/index.js';
25
25
  export * from '../dataset/index.js';
26
26
  export * from '../network-analysis/index.js';
27
+ export * from '../decision/index.js';
27
28
  export { ARTIFACT_TRUST_ROOT_MEDIA_TYPE, ARTIFACT_TRUST_ROOT_SCHEMA_VERSION, ARTIFACT_TRUST_STATE_SCHEMA_VERSION, bootstrapTrustRoot, parseTrustRoot, parseTrustState, readTrustState, validateTrustRoot, validateTrustState, verifyRootTransition, writeTrustState, channelStateKey, canonicalJson, dssePae, publicKeyFingerprint, sha256, type ArtifactTrustRoot, type ArtifactTrustState, type RootBootstrapResult, type RootTransitionResult, type ArtifactTrustPolicySettings, type TrustedChannelState, } from '../security/artifact-trust.js';
28
29
  export * from '../writing/writer-profile.js';
29
30
  export * from '../writing/writer-profile-store.js';
@@ -24,6 +24,7 @@ export * from '../writing/contextual-diagnostics.js';
24
24
  export * from '../schema/index.js';
25
25
  export * from '../dataset/index.js';
26
26
  export * from '../network-analysis/index.js';
27
+ export * from '../decision/index.js';
27
28
  export { ARTIFACT_TRUST_ROOT_MEDIA_TYPE, ARTIFACT_TRUST_ROOT_SCHEMA_VERSION, ARTIFACT_TRUST_STATE_SCHEMA_VERSION, bootstrapTrustRoot, parseTrustRoot, parseTrustState, readTrustState, validateTrustRoot, validateTrustState, verifyRootTransition, writeTrustState, channelStateKey, canonicalJson, dssePae, publicKeyFingerprint, sha256, } from '../security/artifact-trust.js';
28
29
  export * from '../writing/writer-profile.js';
29
30
  export * from '../writing/writer-profile-store.js';
@@ -13,6 +13,8 @@ import fs from 'fs';
13
13
  import path from 'path';
14
14
  import { createHash } from 'crypto';
15
15
  import { load as loadYaml } from 'js-yaml';
16
+ import { validateDecisionDocument } from '../decision/validate.js';
17
+ import { parseDecisionJson, parseDecisionYaml } from '../decision/entry.js';
16
18
  import { DEFAULT_INDEX_EXTENSIONS, INDEX_EXTRACTOR_VERSION, INDEX_VERSION, INDEX_DIR, OPERATIONAL_DISCOVERY_TYPES, PHASE_DIRECTORIES, GRAPH_CONFIGS, TEMPLATE_INDEX_EXTENSIONS, resolveGraphScanDir, loadUserGraphConfigs, loadGlobalGraphConfigs, } from './types.js';
17
19
  import { parseCitationSidecar, citationResultToEdges, buildRefToPathMap } from './citation-parser.js';
18
20
  import { writeIndexFile, resolveIndexDir, loadGraphIndexFile } from './index-reader.js';
@@ -163,6 +165,38 @@ function extractSummary(data, body) {
163
165
  const lines = body.split('\n').filter(l => l.trim() && !l.startsWith('#'));
164
166
  return lines.slice(0, 5).join(' ').slice(0, 500).trim();
165
167
  }
168
+ /** Classify and schema-check authored decision-system documents. */
169
+ export function parseDecisionDoc(content, relativePath) {
170
+ if (!/\.(json|ya?ml)$/i.test(relativePath))
171
+ return null;
172
+ if (Buffer.byteLength(content, 'utf8') > 262_144)
173
+ return null;
174
+ let document;
175
+ try {
176
+ document = /\.json$/i.test(relativePath) ? parseDecisionJson(content) : parseDecisionYaml(content);
177
+ validateDecisionDocument(document);
178
+ }
179
+ catch {
180
+ return null;
181
+ }
182
+ const value = document;
183
+ if (!['DecisionDefinition', 'DecisionRuleset', 'DecisionBinding'].includes(value.kind))
184
+ return null;
185
+ const type = {
186
+ DecisionDefinition: 'decision-definition',
187
+ DecisionRuleset: 'decision-ruleset',
188
+ DecisionBinding: 'decision-binding',
189
+ }[value.kind];
190
+ const purpose = typeof value.spec.purpose === 'string' ? value.spec.purpose : value.metadata.description;
191
+ const terms = new Set([
192
+ value.kind, value.metadata.id, value.metadata.version, purpose,
193
+ ...Object.keys(value.spec),
194
+ ]);
195
+ return {
196
+ type, kind: value.kind, name: value.metadata.id, description: value.metadata.description,
197
+ capability: purpose.slice(0, 240), tags: ['decision-system', value.kind], searchTerms: [...terms],
198
+ };
199
+ }
166
200
  function parseSchemaDoc(content, relativePath) {
167
201
  if (!/\.(json|ya?ml)$/i.test(relativePath))
168
202
  return null;
@@ -929,15 +963,16 @@ export async function buildIndex(cwd, options = {}) {
929
963
  // markdown+frontmatter — detect them up front so they classify and
930
964
  // become discoverable (#1540).
931
965
  const flow = parseFlowDoc(content, relativePath);
966
+ const decision = flow ? null : parseDecisionDoc(content, relativePath);
932
967
  const inferredType = inferType(data, relativePath);
933
968
  const physicalType = inferType({ ...data, type: undefined }, relativePath);
934
- const runbook = flow ? null : parseRunbookDoc(data, body, relativePath);
969
+ const runbook = flow || decision ? null : parseRunbookDoc(data, body, relativePath);
935
970
  const schemaDoc = inferredType === 'schema' ? parseSchemaDoc(content, relativePath) : null;
936
- const title = flow?.name ?? schemaDoc?.title ?? extractTitle(data, body);
971
+ const title = flow?.name ?? decision?.name ?? schemaDoc?.title ?? extractTitle(data, body);
937
972
  const phase = typeof data.phase === 'string' ? data.phase : inferPhase(relativePath);
938
- const type = flow?.type ?? (runbook ? 'runbook' : inferredType);
939
- const tags = flow ? flow.tags : (Array.isArray(data.tags) ? data.tags.map(String) : []);
940
- const summary = flow?.description ?? schemaDoc?.capability ?? runbook?.capability ?? extractSummary(data, body);
973
+ const type = flow?.type ?? decision?.type ?? (runbook ? 'runbook' : inferredType);
974
+ const tags = flow?.tags ?? decision?.tags ?? (Array.isArray(data.tags) ? data.tags.map(String) : []);
975
+ const summary = flow?.description ?? decision?.description ?? schemaDoc?.capability ?? runbook?.capability ?? extractSummary(data, body);
941
976
  const dependencies = extractMentions(content);
942
977
  const markdownLinks = extractMarkdownLinks(content);
943
978
  // Discovery metadata (#1214, #1540, #1792) — meaningful for operational
@@ -947,10 +982,10 @@ export async function buildIndex(cwd, options = {}) {
947
982
  // Declarative processes have no trigger phrases — they rely on their
948
983
  // capability and structure-aware search terms.
949
984
  const triggers = isDiscoverable && !flow ? extractTriggers(body, data) : undefined;
950
- const capability = flow?.capability ?? schemaDoc?.capability ?? runbook?.capability ?? (isDiscoverable ? extractCapability(data, body) : undefined);
951
- const kind = flow?.kind ?? runbook?.kind;
985
+ const capability = flow?.capability ?? decision?.capability ?? schemaDoc?.capability ?? runbook?.capability ?? (isDiscoverable ? extractCapability(data, body) : undefined);
986
+ const kind = flow?.kind ?? decision?.kind ?? runbook?.kind;
952
987
  const sourceType = runbook && physicalType !== 'runbook' ? physicalType : undefined;
953
- const searchTerms = flow?.searchTerms ?? schemaDoc?.searchTerms ?? runbook?.searchTerms;
988
+ const searchTerms = flow?.searchTerms ?? decision?.searchTerms ?? schemaDoc?.searchTerms ?? runbook?.searchTerms;
954
989
  const kernel = data.kernel === true || data.kernel === 'true' ? true : undefined;
955
990
  // Script entrypoint metadata is meaningful for skills only (#1227).
956
991
  const script = type === 'skill' ? extractSkillScript(data) : undefined;
@@ -959,7 +994,7 @@ export async function buildIndex(cwd, options = {}) {
959
994
  // Canonical short name (#1233) — used by the scorer to floor exact-name
960
995
  // queries to 1.0 so hyphenated kernel-skill names like `aiwg-doctor`
961
996
  // remain searchable even when the rendered title strips the hyphen.
962
- const name = flow ? flow.name : schemaDoc?.name ?? (isDiscoverable ? extractCanonicalName(data, relativePath) : undefined);
997
+ const name = flow?.name ?? decision?.name ?? schemaDoc?.name ?? (isDiscoverable ? extractCanonicalName(data, relativePath) : undefined);
963
998
  entry = {
964
999
  path: relativePath,
965
1000
  type,
@@ -1549,6 +1549,9 @@ async function findCorpusArtifact(aiwgRoot, name, typeFilter) {
1549
1549
  { sub: 'behaviors', type: 'behavior', layout: 'flat' },
1550
1550
  { sub: 'flows', type: 'flow', layout: 'flat' },
1551
1551
  { sub: 'runbooks', type: 'runbook', layout: 'flat' },
1552
+ { sub: 'decisions', type: 'decision-definition', layout: 'flat', extension: '.json' },
1553
+ { sub: 'rulesets', type: 'decision-ruleset', layout: 'flat', extension: '.json' },
1554
+ { sub: 'bindings', type: 'decision-binding', layout: 'flat', extension: '.json' },
1552
1555
  ];
1553
1556
  for (const group of groups) {
1554
1557
  let bundles;
@@ -1566,7 +1569,7 @@ async function findCorpusArtifact(aiwgRoot, name, typeFilter) {
1566
1569
  continue;
1567
1570
  const candidate = t.layout === 'slug'
1568
1571
  ? path.join(group.dir, bundle, t.sub, name, 'SKILL.md')
1569
- : path.join(group.dir, bundle, t.sub, `${name}.md`);
1572
+ : path.join(group.dir, bundle, t.sub, `${name}${t.extension ?? '.md'}`);
1570
1573
  try {
1571
1574
  const stat = await fsp.stat(candidate);
1572
1575
  if (stat.isFile()) {
@@ -25,6 +25,9 @@ export const OPERATIONAL_DISCOVERY_TYPES = [
25
25
  'command',
26
26
  'rule',
27
27
  'schema',
28
+ 'decision-definition',
29
+ 'decision-ruleset',
30
+ 'decision-binding',
28
31
  'flow',
29
32
  'runbook',
30
33
  'template',
@@ -0,0 +1,35 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { renderBotHandoff } from '../../providers/bot-handoff.js';
4
+ import { providerCommandOptions } from './provider-command-options.js';
5
+ export const botHandoffHandler = {
6
+ id: 'bot-handoff', name: 'Bot Handoff', category: 'utility', aliases: [],
7
+ description: 'Generate provider-aware review drafts and let the selected provider handle native execution',
8
+ async help() {
9
+ return { exitCode: 0, rawOutput: true, message: [
10
+ 'aiwg bot-handoff --input <proposal.json> [--provider <id>] [--dry-run]',
11
+ 'Supports every registered provider. Uses the active provider if unambiguous; specify --provider in CI.',
12
+ 'Prints a Markdown review draft to stdout. Does not write provider state or call a product API.',
13
+ 'Fields: surface (routines|teammates|connectors|memory), name, summary (max 280 characters), references (1–10 pointers).',
14
+ 'Routines also require schedule and timezone. Use an IANA timezone, e.g. America/New_York.',
15
+ 'References: file paths, HTTP(S) URLs without credentials/query/fragment, or aiwg show pointers.',
16
+ 'Only the supplied JSON is read. Referenced sources are never read or executed. Do not include secrets.',
17
+ 'See docs/integrations/bot-handoff.md for examples and artifact export.',
18
+ ].join('\n') };
19
+ },
20
+ async execute(ctx) {
21
+ try {
22
+ const { provider, flags } = await providerCommandOptions(ctx.args.filter(arg => arg !== '--dry-run'), ctx.cwd, ['--input']);
23
+ if (!flags['--input'])
24
+ throw new Error('Input is required');
25
+ const source = await readFile(path.resolve(ctx.cwd, flags['--input']), 'utf8');
26
+ if (Buffer.byteLength(source) > 16_384)
27
+ throw new Error('Proposal too large');
28
+ return { exitCode: 0, rawOutput: true, message: renderBotHandoff(JSON.parse(source), provider) };
29
+ }
30
+ catch {
31
+ return { exitCode: 1, message: 'Cannot generate handoff: select a registered --provider and check the proposal file/options with --help. Input content is omitted.' };
32
+ }
33
+ },
34
+ };
35
+ //# sourceMappingURL=bot-handoff.js.map
@@ -0,0 +1,50 @@
1
+ import { providerCommandOptions } from './provider-command-options.js';
2
+ import { readAiwgConfig } from '../../config/aiwg-config.js';
3
+ import { verifyProviderDeployment } from '../services/deployment-verification.js';
4
+ export const buildVerifyHandler = {
5
+ id: 'build-verify', name: 'Build Verification', category: 'utility', aliases: [],
6
+ description: 'Verify AIWG deployment before a provider runs a build or CI task',
7
+ async help() {
8
+ return { exitCode: 0, rawOutput: true, message: [
9
+ 'aiwg build-verify [--provider <id>]',
10
+ 'Run from the project root. Uses the shared provider deployment, registry, context and discovery checks.',
11
+ 'Uses the active provider if unambiguous; specify --provider in CI.',
12
+ 'Documented native inspection is required when the provider adapter supports it.',
13
+ 'Other providers report deployment-only verification; no native execution or model compliance is claimed.',
14
+ 'Prints JSON and fails for missing deployment or blocking findings. Does not run build commands or inference.',
15
+ 'See docs/integrations/build-verify.md.',
16
+ ].join('\n') };
17
+ },
18
+ async execute(ctx) {
19
+ try {
20
+ if (ctx.dryRun)
21
+ throw new Error('Verification is already read-only');
22
+ const { provider } = await providerCommandOptions(ctx.args, ctx.cwd);
23
+ const config = await readAiwgConfig(ctx.cwd);
24
+ const bundles = Object.entries(config?.installed ?? {})
25
+ .filter(([, bundle]) => Boolean(bundle.deployedTo?.[provider.id])).map(([name]) => name);
26
+ if (!bundles.length) {
27
+ return { exitCode: 1, rawOutput: true, message: JSON.stringify({
28
+ schema: 'aiwg.build.verify.v1', provider: provider.id, status: 'failed',
29
+ message: `No project deployment recorded. Run aiwg use all --provider ${provider.id} --scope project first.`,
30
+ }) };
31
+ }
32
+ const result = await verifyProviderDeployment({
33
+ projectRoot: ctx.cwd, frameworkRoot: ctx.frameworkRoot, provider: provider.id,
34
+ scope: 'project', requestedBundles: bundles, requireNativeInspection: true,
35
+ });
36
+ const failed = result.findings.some(finding => finding.severity === 'blocking');
37
+ return { exitCode: failed ? 1 : 0, rawOutput: true, message: JSON.stringify({
38
+ schema: 'aiwg.build.verify.v1', provider: provider.id,
39
+ status: failed ? 'failed' : 'ready', verification: result.verificationLevel,
40
+ restartRequired: result.restartRequired, restartAction: result.restartAction,
41
+ // Do not echo raw provider output or configuration values into CI logs.
42
+ findings: result.findings.map(({ id, severity, message, remediation }) => ({ id, severity, message, remediation })),
43
+ }, null, 2) };
44
+ }
45
+ catch {
46
+ return { exitCode: 1, message: 'Cannot verify build readiness. Select a registered --provider, check project configuration, and see build-verify --help.' };
47
+ }
48
+ },
49
+ };
50
+ //# sourceMappingURL=build-verify.js.map
@@ -65,6 +65,8 @@ import { evidenceHandler } from './evidence.js';
65
65
  import { artifactVerifyHandler } from './artifact-verify.js';
66
66
  import { writingHandler } from './writing.js';
67
67
  import { writerProfileHandler } from './writer-profile.js';
68
+ import { botHandoffHandler } from './bot-handoff.js';
69
+ import { buildVerifyHandler } from './build-verify.js';
68
70
  import { outputModeHandler } from './output-mode.js';
69
71
  import { installationHandler } from './installation.js';
70
72
  import { uhpHandler } from './uhp.js';
@@ -75,7 +77,7 @@ export {
75
77
  // Maintenance
76
78
  helpHandler, versionHandler, authHandler, doctorHandler, contextFirewallHandler, updateHandler, refreshHandler, regenerateHandler, workspaceContextHandler,
77
79
  // Framework management
78
- useHandler, listHandler, removeHandler, promoteHandler, installHandler, packagesHandler, marketplaceHandler, initHandler, setupHandler, setupGenerateHandler, setupRunHandler, setupValidateHandler, issueHandler, issueAuditHandler, runHandler, jobHandler, costReportHandler, evidenceHandler, artifactVerifyHandler, outputModeHandler, writerProfileHandler, writingHandler, schemaHandler, datasetHandler, installationHandler,
80
+ useHandler, listHandler, removeHandler, promoteHandler, installHandler, packagesHandler, marketplaceHandler, initHandler, setupHandler, setupGenerateHandler, setupRunHandler, setupValidateHandler, issueHandler, issueAuditHandler, runHandler, jobHandler, costReportHandler, evidenceHandler, artifactVerifyHandler, outputModeHandler, writerProfileHandler, botHandoffHandler, buildVerifyHandler, writingHandler, schemaHandler, datasetHandler, installationHandler,
79
81
  // Project
80
82
  newBundleHandler, quickrefHandler, newProjectHandler, sessionHandler, sessionsHandler,
81
83
  // Workspace
@@ -161,6 +163,8 @@ export const allHandlers = [
161
163
  artifactVerifyHandler,
162
164
  outputModeHandler,
163
165
  writerProfileHandler,
166
+ botHandoffHandler,
167
+ buildVerifyHandler,
164
168
  writingHandler,
165
169
  schemaHandler,
166
170
  datasetHandler,
@@ -0,0 +1,24 @@
1
+ import { getProviderDefinition } from '../../providers/provider-definitions.js';
2
+ import { resolveActiveProvider } from '../provider-resolution.js';
3
+ /** Shared strict provider selection for commands that act on one provider. */
4
+ export async function providerCommandOptions(args, cwd, valueFlags = []) {
5
+ const flags = {};
6
+ for (let i = 0; i < args.length; i++) {
7
+ const flag = args[i];
8
+ if (![...valueFlags, '--provider'].includes(flag) || flags[flag] !== undefined)
9
+ throw new Error('Unknown or duplicate option');
10
+ const value = args[++i];
11
+ if (!value || value.startsWith('--'))
12
+ throw new Error('Missing option value');
13
+ flags[flag] = value;
14
+ }
15
+ // resolveActiveProvider falls back for unknown explicit IDs; commands must not.
16
+ if (flags['--provider'] && !getProviderDefinition(flags['--provider']))
17
+ throw new Error('Unknown provider');
18
+ const resolved = await resolveActiveProvider({ cwd, explicitProvider: flags['--provider'] });
19
+ const provider = resolved.provider && getProviderDefinition(resolved.provider);
20
+ if (!provider)
21
+ throw new Error('Select one provider with --provider');
22
+ return { provider, flags };
23
+ }
24
+ //# sourceMappingURL=provider-command-options.js.map
@@ -347,6 +347,7 @@ async function collectRegistryFindings(options, provider, actualCounts) {
347
347
  return findings;
348
348
  }
349
349
  export async function verifyProviderDeployment(options) {
350
+ let verificationLevel = 'deployment';
350
351
  const normalized = normalizeProviderDefinitionId(options.provider) ?? options.provider;
351
352
  const definition = getProviderDefinition(normalized);
352
353
  const findings = [];
@@ -462,19 +463,19 @@ export async function verifyProviderDeployment(options) {
462
463
  const inspect = runGrokInspect({
463
464
  cwd: options.projectRoot,
464
465
  expected: {
465
- instructionPaths: ['AGENTS.md'],
466
- skillNames: expectedSkillNames.slice(0, 32),
466
+ instructionPaths: options.requireNativeInspection ? [path.join(options.projectRoot, 'AGENTS.md')] : ['AGENTS.md'],
467
+ skillNames: options.requireNativeInspection ? expectedSkillNames : expectedSkillNames.slice(0, 32),
467
468
  },
468
469
  });
469
470
  if (inspect.status === 'absent') {
470
- findings.push(finding(normalized, 'grok-inspect-absent', 'advisory', 'Grok Build CLI (`grok`) is not on PATH; skipped `grok inspect`.', inspect.remediation, { grokHome: resolveGrokHome(), cwd: options.projectRoot }));
471
+ findings.push(finding(normalized, 'grok-inspect-absent', options.requireNativeInspection ? 'blocking' : 'advisory', 'Grok Build CLI (`grok`) is not on PATH; skipped `grok inspect`.', inspect.remediation, { grokHome: resolveGrokHome(), cwd: options.projectRoot }));
471
472
  }
472
473
  else if (inspect.status === 'failed') {
473
474
  const mismatchSummary = (inspect.mismatches ?? [])
474
475
  .slice(0, 8)
475
476
  .map((item) => `${item.kind}:${item.expected}`)
476
477
  .join('; ');
477
- findings.push(finding(normalized, 'grok-inspect-failed', 'advisory', mismatchSummary
478
+ findings.push(finding(normalized, 'grok-inspect-failed', options.requireNativeInspection ? 'blocking' : 'advisory', mismatchSummary
478
479
  ? `\`grok inspect\` did not confirm expected AIWG artifacts (${mismatchSummary}).`
479
480
  : `\`grok inspect\` exited ${inspect.exitCode ?? 'unknown'}.`, 'Fix the Grok Build installation or redeploy, then re-run aiwg status --probe or aiwg use for grok-build.', {
480
481
  exitCode: inspect.exitCode,
@@ -484,11 +485,12 @@ export async function verifyProviderDeployment(options) {
484
485
  }));
485
486
  }
486
487
  else {
488
+ verificationLevel = 'native-inspection';
487
489
  findings.push(finding(normalized, 'grok-inspect-ok', 'info', '`grok inspect` confirmed expected AIWG artifacts in the deployment target.', 'No action required; restart the Grok Build session if newly deployed skills are not visible.', {
488
490
  binary: inspect.binary,
489
491
  cwd: inspect.cwd,
490
492
  parsedKeys: Object.keys(inspect.parsed).slice(0, 20),
491
- checkedSkills: expectedSkillNames.slice(0, 32),
493
+ checkedSkills: options.requireNativeInspection ? expectedSkillNames : expectedSkillNames.slice(0, 32),
492
494
  }));
493
495
  }
494
496
  }
@@ -599,6 +601,7 @@ export async function verifyProviderDeployment(options) {
599
601
  ];
600
602
  return {
601
603
  provider: normalized,
604
+ verificationLevel,
602
605
  scope: options.scope,
603
606
  outcome,
604
607
  restartRequired,