agentic-workflow-manager 9.11.11 → 9.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/src/commands/doctor.js +23 -1
  2. package/dist/src/commands/hooks/claude.js +61 -8
  3. package/dist/src/commands/hooks/resync.js +1 -1
  4. package/dist/src/commands/job/index.js +39 -4
  5. package/dist/src/commands/model-policy/index.js +253 -0
  6. package/dist/src/commands/plan/index.js +53 -12
  7. package/dist/src/commands/preflight/checks.js +18 -0
  8. package/dist/src/commands/watch/apply.js +71 -5
  9. package/dist/src/commands/watch/supervisor.js +63 -3
  10. package/dist/src/core/admission/index.js +20 -6
  11. package/dist/src/core/journal/types.js +21 -5
  12. package/dist/src/core/model-policy/capabilities-v2.js +152 -0
  13. package/dist/src/core/model-policy/capabilities.js +7 -1
  14. package/dist/src/core/model-policy/claude-hook-events.js +120 -0
  15. package/dist/src/core/model-policy/event-store.js +221 -0
  16. package/dist/src/core/model-policy/hook-diagnostics.js +94 -0
  17. package/dist/src/core/model-policy/journal.js +125 -16
  18. package/dist/src/core/model-policy/local-claude-scope.js +41 -0
  19. package/dist/src/core/model-policy/local-codex-scope.js +33 -0
  20. package/dist/src/core/model-policy/local-event-scope.js +13 -0
  21. package/dist/src/core/model-policy/machine-key.js +56 -0
  22. package/dist/src/core/model-policy/native-claude-agent-definition.js +82 -0
  23. package/dist/src/core/model-policy/native-claude-config.js +107 -0
  24. package/dist/src/core/model-policy/native-claude-machine.js +58 -0
  25. package/dist/src/core/model-policy/native-claude-transcript.js +80 -0
  26. package/dist/src/core/model-policy/native-claude.js +41 -0
  27. package/dist/src/core/model-policy/native-codex-machine.js +116 -0
  28. package/dist/src/core/model-policy/native-codex-rollout.js +111 -0
  29. package/dist/src/core/model-policy/native-codex.js +302 -0
  30. package/dist/src/core/model-policy/native-routing-observe.js +106 -0
  31. package/dist/src/core/model-policy/native-routing-proof.js +52 -0
  32. package/dist/src/core/model-policy/native-runtime.js +86 -0
  33. package/dist/src/core/model-policy/resolve.js +117 -3
  34. package/dist/src/core/model-policy/selection-policy-digest.js +22 -0
  35. package/dist/src/core/model-policy/setup-readiness.js +77 -0
  36. package/dist/src/providers/index.js +3 -1
  37. package/dist/tests/commands/doctor-routing.test.js +22 -0
  38. package/dist/tests/commands/doctor.test.js +5 -0
  39. package/dist/tests/commands/hooks/install.test.js +6 -0
  40. package/dist/tests/commands/hooks/resync.test.js +3 -0
  41. package/dist/tests/commands/hooks/status.test.js +12 -1
  42. package/dist/tests/commands/job/routing-file.test.js +32 -0
  43. package/dist/tests/commands/job/routing-report-cli.test.js +12 -5
  44. package/dist/tests/commands/job/routing.test.js +2 -2
  45. package/dist/tests/commands/model-policy/claude-hook-flow.test.js +104 -0
  46. package/dist/tests/commands/model-policy/index.test.js +179 -0
  47. package/dist/tests/commands/plan/index.test.js +2 -2
  48. package/dist/tests/commands/preflight/preflight.test.js +65 -0
  49. package/dist/tests/commands/watch/apply.test.js +116 -10
  50. package/dist/tests/commands/watch/dispatch-routing-identity.test.js +23 -0
  51. package/dist/tests/core/admission/index.test.js +21 -0
  52. package/dist/tests/core/model-policy/capabilities-v2.test.js +42 -0
  53. package/dist/tests/core/model-policy/claude-hook-events.test.js +40 -0
  54. package/dist/tests/core/model-policy/event-store-claude.test.js +64 -0
  55. package/dist/tests/core/model-policy/event-store.test.js +151 -0
  56. package/dist/tests/core/model-policy/hook-diagnostics.test.js +34 -0
  57. package/dist/tests/core/model-policy/journal.test.js +165 -12
  58. package/dist/tests/core/model-policy/local-claude-scope.test.js +31 -0
  59. package/dist/tests/core/model-policy/machine-key.test.js +38 -0
  60. package/dist/tests/core/model-policy/native-claude-agent-definition.test.js +31 -0
  61. package/dist/tests/core/model-policy/native-claude-config.test.js +53 -0
  62. package/dist/tests/core/model-policy/native-claude-machine.test.js +18 -0
  63. package/dist/tests/core/model-policy/native-claude-transcript.test.js +45 -0
  64. package/dist/tests/core/model-policy/native-claude.test.js +21 -0
  65. package/dist/tests/core/model-policy/native-codex-machine.test.js +34 -0
  66. package/dist/tests/core/model-policy/native-codex-rollout.test.js +44 -0
  67. package/dist/tests/core/model-policy/native-codex.test.js +133 -0
  68. package/dist/tests/core/model-policy/native-routing-observe.test.js +60 -0
  69. package/dist/tests/core/model-policy/native-routing-proof.test.js +30 -0
  70. package/dist/tests/core/model-policy/native-runtime.test.js +14 -0
  71. package/dist/tests/core/model-policy/resolve-event.test.js +65 -0
  72. package/dist/tests/core/model-policy/resolve.test.js +17 -0
  73. package/dist/tests/core/model-policy/setup-readiness.test.js +83 -0
  74. package/dist/tests/helpers/routing-approval.js +14 -0
  75. package/dist/tests/providers/index.test.js +1 -1
  76. package/package.json +2 -2
  77. package/prebuilds/darwin-arm64/secure_fs.node +0 -0
  78. package/prebuilds/darwin-x64/secure_fs.node +0 -0
  79. package/prebuilds/win32-arm64/secure_fs.node +0 -0
  80. package/prebuilds/win32-x64/secure_fs.node +0 -0
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const os_1 = __importDefault(require("os"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const job_1 = require("../../../src/commands/job");
10
+ describe('bounded routing input', () => {
11
+ it('rejects a file that grows between metadata check and read', () => {
12
+ const dir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'awm-routing-input-'));
13
+ const file = path_1.default.join(dir, 'observation.json');
14
+ try {
15
+ fs_1.default.writeFileSync(file, JSON.stringify({ parentThreadId: 'a'.repeat(300 * 1024) }));
16
+ const original = fs_1.default.lstatSync;
17
+ const stat = jest.spyOn(fs_1.default, 'lstatSync').mockImplementation(((target, ...args) => {
18
+ const actual = original(target, ...args);
19
+ return String(target) === file ? Object.assign(Object.create(Object.getPrototypeOf(actual)), actual, { size: 1 }) : actual;
20
+ }));
21
+ try {
22
+ expect(() => (0, job_1.readBoundedJson)(file)).toThrow(/bound|256|size|regular|large/i);
23
+ }
24
+ finally {
25
+ stat.mockRestore();
26
+ }
27
+ }
28
+ finally {
29
+ fs_1.default.rmSync(dir, { recursive: true, force: true });
30
+ }
31
+ });
32
+ });
@@ -11,20 +11,26 @@ const commander_1 = require("commander");
11
11
  const job_1 = require("../../../src/commands/job");
12
12
  const store_1 = require("../../../src/core/journal/store");
13
13
  const journal_1 = require("../../../src/core/model-policy/journal");
14
- const envelope = { schema: 'routing-envelope/v1', runtime: { target: 'codex', kind: 'native', version: '1', accountScopeDigest: '0'.repeat(64) }, role: 'implementer', sliceId: 'S1', requestedProfile: 'mechanical', effectiveProfile: 'mechanical', resolved: { selector: { kind: 'model', id: 'model-private' }, effort: { kind: 'explicit', value: 'medium' } }, outcome: 'native', unavailableEvidence: [], policyDigest: 'a'.repeat(64), capabilityDigest: 'b'.repeat(64), planDigest: 'c'.repeat(64), executionDigest: 'd'.repeat(64) };
14
+ const capabilities_1 = require("../../../src/core/model-policy/capabilities");
15
+ const routing_approval_1 = require("../../helpers/routing-approval");
15
16
  function gitInit(repo) {
16
17
  (0, child_process_1.execFileSync)('git', ['-c', 'user.email=t@t.t', '-c', 'user.name=t', 'init', '-q', '-b', 'main'], { cwd: repo });
17
18
  fs_1.default.writeFileSync(path_1.default.join(repo, 'fixture'), 'x');
18
19
  (0, child_process_1.execFileSync)('git', ['add', '.'], { cwd: repo });
19
20
  (0, child_process_1.execFileSync)('git', ['-c', 'user.email=t@t.t', '-c', 'user.name=t', 'commit', '-qm', 'fixture'], { cwd: repo });
20
21
  }
21
- test('`job routing-report --json` emits only aggregate routing evidence', async () => {
22
+ test('`job routing-report --json` exposes selections but not native child identities or envelopes', async () => {
22
23
  const repo = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'awm-routing-report-'));
23
24
  try {
24
25
  gitInit(repo);
25
26
  (0, store_1.initJournal)(repo, 'main');
26
27
  const state = (0, store_1.readJournal)(repo, 'main').state;
27
- const reserved = (0, journal_1.reserveRoutingAttempt)(state, { obligationId: 'obligation', lineageId: 'lineage', envelope, fingerprint: 'e'.repeat(64) }, '2026-09-17T00:00:00.000Z');
28
+ const approved = (0, routing_approval_1.routingApproval)();
29
+ const privateSelection = { ...routing_approval_1.routingEnvelope.resolved, selector: { kind: 'model', id: 'model-private' } };
30
+ approved.policy.content.mappings[0].profiles.mechanical = privateSelection;
31
+ approved.capabilities.availableSelections.push(privateSelection);
32
+ const envelope = { ...routing_approval_1.routingEnvelope, resolved: privateSelection, capabilityDigest: (0, capabilities_1.capabilityReceiptDigest)(approved.capabilities) };
33
+ const reserved = (0, journal_1.reserveRoutingAttempt)(state, { obligationId: 'obligation', lineageId: 'lineage', envelope, fingerprint: 'e'.repeat(64), approval: () => approved }, '2026-09-17T00:00:00.000Z');
28
34
  (0, store_1.writeJournal)(repo, 'main', (0, journal_1.observeRoutingAttempt)(reserved.state, { attemptId: reserved.attemptId, nativeAgentId: 'native-private' }, '2026-09-17T00:01:00.000Z'));
29
35
  const program = new commander_1.Command();
30
36
  program.exitOverride();
@@ -34,9 +40,10 @@ test('`job routing-report --json` emits only aggregate routing evidence', async
34
40
  await program.parseAsync(['node', 'awm', 'job', 'routing-report', '--json']);
35
41
  const rendered = String(out.mock.calls[0][0]);
36
42
  const report = JSON.parse(rendered);
37
- expect(report).toMatchObject({ schema: 'routing-report/v1', attempts: 1, plannedByRole: { implementer: 1 }, actualByRole: { implementer: 1 }, byState: { active: 1 } });
43
+ expect(report).toMatchObject({ schema: 'routing-report/v1', attempts: 1, plannedByRole: { implementer: 1 }, actualByRole: { implementer: 1 }, byState: { active: 1 },
44
+ selections: [{ configured: privateSelection, accepted: 'unknown', backendModel: 'unknown' }] });
38
45
  expect(rendered).not.toContain('native-private');
39
- expect(rendered).not.toContain('model-private');
46
+ expect(rendered).not.toContain('obligation');
40
47
  cwd.mockRestore();
41
48
  out.mockRestore();
42
49
  }
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const types_1 = require("../../../src/core/journal/types");
4
4
  const journal_1 = require("../../../src/core/model-policy/journal");
5
- const envelope = { schema: 'routing-envelope/v1', runtime: { target: 'codex', kind: 'native', version: '1', accountScopeDigest: '0'.repeat(64) }, role: 'implementer', sliceId: 'S1', requestedProfile: 'mechanical', effectiveProfile: 'mechanical', resolved: { selector: { kind: 'model', id: 'm' }, effort: { kind: 'explicit', value: 'medium' } }, outcome: 'native', unavailableEvidence: [], policyDigest: 'a'.repeat(64), capabilityDigest: 'b'.repeat(64), planDigest: 'c'.repeat(64), executionDigest: 'd'.repeat(64) };
5
+ const routing_approval_1 = require("../../helpers/routing-approval");
6
6
  test('routing report remains read-only across an observed attempt', () => {
7
- const reserved = (0, journal_1.reserveRoutingAttempt)((0, types_1.emptyState)('main'), { obligationId: 'o1', lineageId: 'l1', envelope, fingerprint: 'e'.repeat(64) }, '2026-09-17T00:00:00.000Z');
7
+ const reserved = (0, journal_1.reserveRoutingAttempt)((0, types_1.emptyState)('main'), { obligationId: 'o1', lineageId: 'l1', envelope: routing_approval_1.routingEnvelope, fingerprint: 'e'.repeat(64), approval: routing_approval_1.routingApproval }, '2026-09-17T00:00:00.000Z');
8
8
  const observed = (0, journal_1.observeRoutingAttempt)(reserved.state, { attemptId: reserved.attemptId, nativeAgentId: 'native-id' }, '2026-09-17T00:01:00.000Z');
9
9
  expect((0, journal_1.routingReport)(observed)).toMatchObject({ attempts: 1, byState: { active: 1 } });
10
10
  expect(observed.routingAttempts[0].nativeAgentId).toBe('native-id');
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const os_1 = __importDefault(require("os"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const child_process_1 = require("child_process");
10
+ const store_1 = require("../../../src/core/model-policy/store");
11
+ const canonical_1 = require("../../../src/core/model-policy/canonical");
12
+ const machine_key_1 = require("../../../src/core/model-policy/machine-key");
13
+ const event_store_1 = require("../../../src/core/model-policy/event-store");
14
+ describe('Claude hook to event receipt integration', () => {
15
+ it('captures a real-format hook pair and assistant trace without paid inference', () => {
16
+ const root = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'awm-claude-hook-flow-'));
17
+ const previous = { home: process.env.HOME, awm: process.env.AWM_HOME, config: process.env.CLAUDE_CONFIG_DIR };
18
+ const awmHome = path_1.default.join(root, 'awm');
19
+ const project = path_1.default.join(root, 'project');
20
+ const configDir = path_1.default.join(root, 'claude');
21
+ const bin = path_1.default.join(root, 'bin');
22
+ fs_1.default.mkdirSync(awmHome);
23
+ fs_1.default.mkdirSync(project);
24
+ fs_1.default.mkdirSync(configDir);
25
+ fs_1.default.mkdirSync(bin);
26
+ process.env.HOME = root;
27
+ process.env.AWM_HOME = awmHome;
28
+ process.env.CLAUDE_CONFIG_DIR = configDir;
29
+ try {
30
+ (0, machine_key_1.ensureMachineKey)(awmHome);
31
+ const selected = { selector: { kind: 'model', id: 'claude-sonnet-4-6' }, effort: { kind: 'runtime-default' } };
32
+ const content = { schema: 'model-policy/v1', mappings: [{ target: 'claude-code', runtimeKind: 'native',
33
+ profiles: { mechanical: selected, integration: selected, judgment: selected }, fullCapability: selected,
34
+ degradation: { allowMissingModelOverride: false, allowMissingEffortOverride: false, allowMissingObservedIdentity: false } }],
35
+ implementationBudget: { maxAttempts: 3, escalation: ['mechanical', 'integration', 'judgment'], judgmentEfforts: ['medium', 'high'] } };
36
+ fs_1.default.writeFileSync(path_1.default.join(project, 'candidate.json'), JSON.stringify(content));
37
+ (0, store_1.approvePolicy)({ file: 'candidate.json', scope: 'project', cwd: project, expectedDigest: (0, canonical_1.canonicalPolicyDigest)(content) });
38
+ const executable = path_1.default.join(bin, process.platform === 'win32' ? 'claude.exe' : 'claude');
39
+ const authResponse = { loggedIn: true, authMethod: 'claude.ai', apiProvider: 'anthropic', email: 'test@example.invalid', orgId: 'org-test' };
40
+ let preload;
41
+ if (process.platform === 'win32') {
42
+ // A Unix shebang cannot be launched by CreateProcess. Use a real
43
+ // .exe and intercept only its auth-status invocation in Node.
44
+ fs_1.default.copyFileSync(process.execPath, executable);
45
+ preload = path_1.default.join(root, 'claude-preload.cjs');
46
+ fs_1.default.writeFileSync(preload, `if (require('path').basename(process.execPath).toLowerCase() === 'claude.exe' && require('path').basename(process.argv[1] || '') === 'auth') { process.stdout.write(${JSON.stringify(JSON.stringify(authResponse))}); process.exit(0); }\n`);
47
+ }
48
+ else {
49
+ fs_1.default.writeFileSync(executable, `#!${process.execPath}\nif (process.argv[2] === '--version') process.stdout.write('2.1.263\\n');\nelse if (process.argv[2] === 'auth') process.stdout.write(${JSON.stringify(JSON.stringify(authResponse))});\n`, { mode: 0o755 });
50
+ }
51
+ const timestamp = new Date().toISOString();
52
+ const transcript = path_1.default.join(configDir, 'projects', 'p', 's', 'subagents', 'agent-agent-1.jsonl');
53
+ fs_1.default.mkdirSync(path_1.default.dirname(transcript), { recursive: true });
54
+ fs_1.default.writeFileSync(transcript, `${JSON.stringify({ type: 'assistant', timestamp, message: { model: 'claude-sonnet-4-6', content: [] } })}\n`);
55
+ fs_1.default.mkdirSync(path_1.default.join(configDir, 'agents'));
56
+ fs_1.default.writeFileSync(path_1.default.join(configDir, 'agents', 'awm-integration.md'), '---\nname: awm-integration\ndescription: AWM integration agent\nmodel: claude-sonnet-4-6\n---\nPerform integration work.\n');
57
+ const start = { hook_event_name: 'SubagentStart', session_id: 'session-1', agent_id: 'agent-1', agent_type: 'awm-integration' };
58
+ const stop = { ...start, hook_event_name: 'SubagentStop', agent_transcript_path: transcript, stop_hook_active: false };
59
+ const cli = path_1.default.resolve(__dirname, '../../../dist/src/index.js');
60
+ const env = { ...process.env, PATH: `${bin}${path_1.default.delimiter}${process.env.PATH ?? ''}` };
61
+ if (preload)
62
+ env.NODE_OPTIONS = `${process.env.NODE_OPTIONS ?? ''} --require=${JSON.stringify(preload)}`;
63
+ const authProbe = (0, child_process_1.spawnSync)(executable, ['auth', 'status'], { env, encoding: 'utf8' });
64
+ expect(authProbe.status).toBe(0);
65
+ expect(JSON.parse(authProbe.stdout)).toMatchObject(authResponse);
66
+ const versionProbe = (0, child_process_1.spawnSync)(executable, ['--version'], { env, encoding: 'utf8' });
67
+ expect(versionProbe.status).toBe(0);
68
+ expect(versionProbe.stdout).toMatch(/\d+\.\d+\.\d+/);
69
+ const first = (0, child_process_1.spawnSync)(process.execPath, [cli, 'model-policy', 'hook-event', '--event', 'start', '--cwd', project], { cwd: project, env, input: JSON.stringify(start), encoding: 'utf8' });
70
+ expect(first.status).toBe(0);
71
+ expect(first.stdout).toBe('');
72
+ const second = (0, child_process_1.spawnSync)(process.execPath, [cli, 'model-policy', 'hook-event', '--event', 'stop', '--cwd', project], { cwd: project, env, input: JSON.stringify(stop), encoding: 'utf8' });
73
+ expect(second.status).toBe(0);
74
+ expect(second.stdout).toBe('');
75
+ expect(second.stderr).toBe('');
76
+ const files = fs_1.default.readdirSync(path_1.default.join(awmHome, 'routing-capabilities-v2', 'claude-code'));
77
+ expect(files).toEqual(['native.json']);
78
+ const raw = fs_1.default.readFileSync(path_1.default.join(awmHome, 'routing-capabilities-v2', 'claude-code', 'native.json'), 'utf8');
79
+ expect(raw).not.toContain('test@example.invalid');
80
+ const persisted = JSON.parse(raw);
81
+ expect((0, event_store_1.readStoredEventReceipt)(persisted.receipt.runtime)).toMatchObject({ state: 'present', receipt: { claims: [expect.objectContaining({ selection: selected, nativeAgentType: 'awm-integration', actualModel: expect.objectContaining({ id: 'claude-sonnet-4-6' }), tokenUsage: 'unknown' })] } });
82
+ const generic = { ...start, agent_id: 'other-agent', agent_type: 'general-purpose' };
83
+ const ignored = (0, child_process_1.spawnSync)(process.execPath, [cli, 'model-policy', 'hook-event', '--event', 'start', '--cwd', project, '--json'], { cwd: project, env, input: JSON.stringify(generic), encoding: 'utf8' });
84
+ expect(ignored.status).toBe(0);
85
+ expect(JSON.parse(ignored.stdout)).toMatchObject({ state: 'ignored' });
86
+ expect(fs_1.default.readFileSync(path_1.default.join(awmHome, 'routing-capabilities-v2', 'claude-code', 'native.json'), 'utf8')).toBe(raw);
87
+ }
88
+ finally {
89
+ if (previous.home === undefined)
90
+ delete process.env.HOME;
91
+ else
92
+ process.env.HOME = previous.home;
93
+ if (previous.awm === undefined)
94
+ delete process.env.AWM_HOME;
95
+ else
96
+ process.env.AWM_HOME = previous.awm;
97
+ if (previous.config === undefined)
98
+ delete process.env.CLAUDE_CONFIG_DIR;
99
+ else
100
+ process.env.CLAUDE_CONFIG_DIR = previous.config;
101
+ fs_1.default.rmSync(root, { recursive: true, force: true });
102
+ }
103
+ });
104
+ });
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  const commander_1 = require("commander");
4
37
  const model_policy_1 = require("../../../src/commands/model-policy");
@@ -114,4 +147,150 @@ describe('model-policy command', () => {
114
147
  await expect(program.parseAsync(['node', 'awm', 'model-policy', 'capabilities', 'approve', '--file', 'receipt.json', '--expected-digest', 'a'.repeat(64), '--replace-digest', ''])).rejects.toThrow(/requires a non-empty value/);
115
148
  expect(approveCapabilities).not.toHaveBeenCalled();
116
149
  });
150
+ it('discovers the Codex catalog explicitly without approving capabilities', async () => {
151
+ const queryCodexModelCatalog = jest.fn(async () => ({ provenance: 'native-catalog', selections: [], nativeDispatchVerified: false, actualModelVerified: false }));
152
+ const approveCapabilities = jest.fn();
153
+ const program = new commander_1.Command();
154
+ program.exitOverride();
155
+ program.configureOutput({ writeErr: () => undefined });
156
+ (0, model_policy_1.registerModelPolicyCommand)(program, { queryCodexModelCatalog, approveCapabilities: approveCapabilities });
157
+ await program.parseAsync(['node', 'awm', 'model-policy', 'discover', '--provider', 'codex', '--json']);
158
+ expect(queryCodexModelCatalog).toHaveBeenCalledTimes(1);
159
+ expect(JSON.parse(String(out.mock.calls[0][0]))).toMatchObject({ state: 'catalog-only', nativeDispatchVerified: false, actualModelVerified: false });
160
+ expect(approveCapabilities).not.toHaveBeenCalled();
161
+ });
162
+ it('reports missing machine selections from the approved Codex policy without certifying dispatch', async () => {
163
+ const available = { selector: { kind: 'model', id: 'gpt-6-sol' }, effort: { kind: 'explicit', value: 'high' } };
164
+ const missing = { selector: { kind: 'model', id: 'gpt-6-luna' }, effort: { kind: 'explicit', value: 'low' } };
165
+ const queryCodexModelCatalog = jest.fn(async () => ({ provenance: 'native-catalog', selections: [available], nativeDispatchVerified: false, actualModelVerified: false }));
166
+ const readEffectivePolicy = jest.fn(() => ({ state: 'approved', policy: { content: { mappings: [{ target: 'codex', runtimeKind: 'native', profiles: { mechanical: missing, integration: available, judgment: available }, fullCapability: available }] } } }));
167
+ const program = new commander_1.Command();
168
+ program.exitOverride();
169
+ program.configureOutput({ writeErr: () => undefined });
170
+ (0, model_policy_1.registerModelPolicyCommand)(program, { queryCodexModelCatalog, readEffectivePolicy: readEffectivePolicy });
171
+ await program.parseAsync(['node', 'awm', 'model-policy', 'discover', '--provider', 'codex', '--cwd', 'fixture-root', '--json']);
172
+ expect(readEffectivePolicy).toHaveBeenCalledWith('fixture-root');
173
+ expect(JSON.parse(String(out.mock.calls[0][0]))).toMatchObject({ state: 'catalog-only', policyCoverage: { state: 'missing', missing: [missing] }, nativeDispatchVerified: false, actualModelVerified: false });
174
+ expect(process.exitCode).toBe(2);
175
+ });
176
+ it('reports catalog coverage but still refuses to claim native dispatch or backend identity', async () => {
177
+ const selection = { selector: { kind: 'model', id: 'gpt-6-sol' }, effort: { kind: 'explicit', value: 'high' } };
178
+ const queryCodexModelCatalog = jest.fn(async () => ({ provenance: 'native-catalog', selections: [selection], nativeDispatchVerified: false, actualModelVerified: false }));
179
+ const readEffectivePolicy = jest.fn(() => ({ state: 'approved', policy: { content: { mappings: [{ target: 'codex', runtimeKind: 'native', profiles: { mechanical: selection, integration: selection, judgment: selection }, fullCapability: selection }] } } }));
180
+ const program = new commander_1.Command();
181
+ program.exitOverride();
182
+ program.configureOutput({ writeErr: () => undefined });
183
+ (0, model_policy_1.registerModelPolicyCommand)(program, { queryCodexModelCatalog, readEffectivePolicy: readEffectivePolicy });
184
+ await program.parseAsync(['node', 'awm', 'model-policy', 'discover', '--provider', 'codex', '--json']);
185
+ expect(JSON.parse(String(out.mock.calls[0][0]))).toMatchObject({ state: 'catalog-only', policyCoverage: { state: 'complete', missing: [] }, nativeDispatchVerified: false, actualModelVerified: false });
186
+ });
187
+ it('does not silently treat Claude as Codex during native discovery', async () => {
188
+ const queryCodexModelCatalog = jest.fn();
189
+ const program = new commander_1.Command();
190
+ program.exitOverride();
191
+ program.configureOutput({ writeErr: () => undefined });
192
+ (0, model_policy_1.registerModelPolicyCommand)(program, { queryCodexModelCatalog });
193
+ await program.parseAsync(['node', 'awm', 'model-policy', 'discover', '--provider', 'claude-code', '--json']);
194
+ expect(JSON.parse(String(out.mock.calls[0][0]))).toMatchObject({ state: 'unverified', provider: 'claude-code' });
195
+ expect(queryCodexModelCatalog).not.toHaveBeenCalled();
196
+ expect(process.exitCode).toBe(2);
197
+ });
198
+ it('reports every Codex selection and the full fallback as unverified without dispatch', async () => {
199
+ const cheap = { selector: { kind: 'model', id: 'gpt-6-sol' }, effort: { kind: 'explicit', value: 'low' } };
200
+ const full = { selector: { kind: 'model', id: 'gpt-6-astra' }, effort: { kind: 'explicit', value: 'high' } };
201
+ const queryCodexModelCatalog = jest.fn(async () => ({ provenance: 'native-catalog', selections: [cheap, full], nativeDispatchVerified: false, actualModelVerified: false }));
202
+ const queryCodexMachineFacts = jest.fn(async () => ({ provenance: 'codex-app-server-config-account', configDigest: 'c'.repeat(64), accountState: 'identified', accountScopeDigest: 'a'.repeat(64), inferenceDispatched: false }));
203
+ const queryRuntimeExecutable = jest.fn(async () => ({ version: '0.156.0', binaryDigest: 'b'.repeat(64), inferenceDispatched: false }));
204
+ const ensureMachineKey = jest.fn(() => Buffer.alloc(32, 7));
205
+ const readEffectivePolicy = jest.fn(() => ({ state: 'approved', policy: { content: { mappings: [{ target: 'codex', runtimeKind: 'native', profiles: { mechanical: cheap, integration: cheap, judgment: full }, fullCapability: full, degradation: { allowMissingObservedIdentity: false } }] } } }));
206
+ const program = new commander_1.Command();
207
+ program.exitOverride();
208
+ program.configureOutput({ writeErr: () => undefined });
209
+ (0, model_policy_1.registerModelPolicyCommand)(program, { queryCodexModelCatalog, queryCodexMachineFacts, queryRuntimeExecutable, ensureMachineKey, readEffectivePolicy: readEffectivePolicy });
210
+ await program.parseAsync(['node', 'awm', 'model-policy', 'setup', '--provider', 'codex', '--json']);
211
+ const report = JSON.parse(String(out.mock.calls[0][0]));
212
+ expect(report).toMatchObject({ state: 'setup-pending', provider: 'codex', inferenceDispatched: false, tokenUsage: 'unknown', nativeDispatchVerified: false, actualModelVerified: false,
213
+ machine: { runtimeVersion: '0.156.0', binaryDigest: 'b'.repeat(64), configDigest: 'c'.repeat(64), accountState: 'identified', accountScopeDigest: 'a'.repeat(64) } });
214
+ expect(report.selections).toEqual(expect.arrayContaining([
215
+ expect.objectContaining({ role: 'mechanical', catalogAvailable: true, dispatch: 'untested' }),
216
+ expect.objectContaining({ role: 'fullCapability', catalogAvailable: true, dispatch: 'untested' }),
217
+ ]));
218
+ expect(report.policyAction).toMatch(/allowMissingObservedIdentity/);
219
+ expect(queryCodexModelCatalog).toHaveBeenCalledTimes(1);
220
+ expect(queryCodexMachineFacts).toHaveBeenCalledTimes(1);
221
+ expect(queryRuntimeExecutable).toHaveBeenCalledTimes(1);
222
+ expect(ensureMachineKey).toHaveBeenCalledTimes(1);
223
+ expect(process.exitCode).toBe(2);
224
+ });
225
+ it('never runs inference merely because setup was requested', async () => {
226
+ const queryCodexModelCatalog = jest.fn();
227
+ const program = new commander_1.Command();
228
+ program.exitOverride();
229
+ program.configureOutput({ writeErr: () => undefined });
230
+ (0, model_policy_1.registerModelPolicyCommand)(program, { queryCodexModelCatalog });
231
+ await expect(program.parseAsync(['node', 'awm', 'model-policy', 'setup', '--provider', 'codex', '--allow-inference'])).rejects.toThrow(/unknown option/i);
232
+ expect(queryCodexModelCatalog).not.toHaveBeenCalled();
233
+ });
234
+ it('captures only an approved Codex selection from an existing native child, with local scope', async () => {
235
+ const selected = { selector: { kind: 'model', id: 'gpt-6-luna' }, effort: { kind: 'explicit', value: 'high' } };
236
+ const mapping = { target: 'codex', runtimeKind: 'native', profiles: { mechanical: selected, integration: selected, judgment: selected }, fullCapability: selected,
237
+ degradation: { allowMissingModelOverride: false, allowMissingEffortOverride: false, allowMissingObservedIdentity: true } };
238
+ const queryCodexChildThreadObservation = jest.fn(async () => ({ configuredSelection: selected, childRuntimeVersion: '0.156.1', observedAt: '2026-09-23T01:00:00.000Z' }));
239
+ const publishCodexObservation = jest.fn(() => ({ schema: 'routing-capabilities/v2', claims: [{ selection: selected }] }));
240
+ const program = new commander_1.Command();
241
+ program.exitOverride();
242
+ program.configureOutput({ writeErr: () => undefined });
243
+ (0, model_policy_1.registerModelPolicyCommand)(program, { readEffectivePolicy: (() => ({ state: 'approved', policy: { content: { mappings: [mapping] } } })),
244
+ queryCodexChildThreadObservation: queryCodexChildThreadObservation, publishCodexObservation: publishCodexObservation,
245
+ queryCodexMachineFacts: (async () => ({ configDigest: 'c'.repeat(64), accountScopeDigest: 'a'.repeat(64), accountState: 'identified' })),
246
+ queryRuntimeExecutable: (async () => ({ version: '0.156.1', binaryDigest: 'b'.repeat(64) })),
247
+ ensureMachineKey: (() => Buffer.alloc(32, 7)) });
248
+ await program.parseAsync(['node', 'awm', 'model-policy', 'capture', '--provider', 'codex', '--runtime-kind', 'native', '--parent-thread-id', 'parent-1', '--child-thread-id', 'child-1', '--json']);
249
+ expect(queryCodexChildThreadObservation).toHaveBeenCalledWith(expect.objectContaining({ parentThreadId: 'parent-1', childThreadId: 'child-1' }));
250
+ expect(publishCodexObservation).toHaveBeenCalledWith(expect.objectContaining({ expectedSelection: selected,
251
+ scope: { runtime: { target: 'codex', kind: 'native', version: '0.156.1', accountScopeDigest: 'a'.repeat(64) }, binaryDigest: 'b'.repeat(64), configDigest: 'c'.repeat(64) } }));
252
+ expect(JSON.parse(String(out.mock.calls[0][0]))).toMatchObject({ state: 'captured', actualModelVerified: false, tokenUsage: 'unknown' });
253
+ });
254
+ it('reports a matching event-scoped enrollment as ready after 25 hours without refreshing it', async () => {
255
+ const selected = { selector: { kind: 'model', id: 'gpt-6-luna' }, effort: { kind: 'explicit', value: 'high' } };
256
+ const mapping = { target: 'codex', runtimeKind: 'native', profiles: { mechanical: selected, integration: selected, judgment: selected }, fullCapability: selected,
257
+ degradation: { allowMissingModelOverride: false, allowMissingEffortOverride: false, allowMissingObservedIdentity: true } };
258
+ const { createHash } = await Promise.resolve().then(() => __importStar(require('crypto')));
259
+ const mappingDigest = createHash('sha256').update(JSON.stringify({ target: mapping.target, runtimeKind: mapping.runtimeKind, selection: selected })).digest('hex');
260
+ const receipt = { schema: 'routing-capabilities/v2', runtime: { target: 'codex', kind: 'native', version: '0.156.1', accountScopeDigest: 'a'.repeat(64) },
261
+ binaryDigest: 'b'.repeat(64), configDigest: 'c'.repeat(64), recordedAt: '2026-09-22T01:00:00.000Z', claims: [{ selection: selected, mappingDigest,
262
+ eventDigest: 'e'.repeat(64), source: 'codex-turn-context', observedAt: '2026-09-22T00:59:00.000Z', actualModel: 'unverified', tokenUsage: 'unknown' }] };
263
+ const readStoredEventReceipt = jest.fn(() => ({ state: 'present', receipt }));
264
+ const program = new commander_1.Command();
265
+ program.exitOverride();
266
+ program.configureOutput({ writeErr: () => undefined });
267
+ (0, model_policy_1.registerModelPolicyCommand)(program, { readEffectivePolicy: (() => ({ state: 'approved', policy: { content: { mappings: [mapping] } } })),
268
+ readStoredEventReceipt: readStoredEventReceipt,
269
+ queryCodexModelCatalog: (async () => ({ selections: [selected] })),
270
+ queryCodexMachineFacts: (async () => ({ configDigest: 'c'.repeat(64), accountScopeDigest: 'a'.repeat(64), accountState: 'identified' })),
271
+ queryRuntimeExecutable: (async () => ({ version: '0.156.1', binaryDigest: 'b'.repeat(64) })),
272
+ ensureMachineKey: (() => Buffer.alloc(32, 7)) });
273
+ await program.parseAsync(['node', 'awm', 'model-policy', 'setup', '--provider', 'codex', '--json']);
274
+ expect(JSON.parse(String(out.mock.calls[0][0]))).toMatchObject({ state: 'ready-operational', selections: expect.arrayContaining([expect.objectContaining({ dispatch: 'verified', acceptedSelection: 'verified', actualModel: 'untested' })]) });
275
+ expect(readStoredEventReceipt).toHaveBeenCalledTimes(1);
276
+ expect(process.exitCode).toBeUndefined();
277
+ });
278
+ it('discovers Claude version and account without claiming a model or dispatch', async () => {
279
+ const selected = { selector: { kind: 'model', id: 'claude-sonnet-4-6' }, effort: { kind: 'runtime-default' } };
280
+ const mapping = { target: 'claude-code', runtimeKind: 'native', profiles: { mechanical: selected, integration: selected, judgment: selected }, fullCapability: selected,
281
+ degradation: { allowMissingModelOverride: false, allowMissingEffortOverride: false, allowMissingObservedIdentity: false } };
282
+ const queryClaudeAuthStatus = jest.fn(async () => ({ accountState: 'identified', accountScopeDigest: 'a'.repeat(64), inferenceDispatched: false }));
283
+ const queryRuntimeExecutable = jest.fn(async () => ({ version: '2.1.263', binaryDigest: 'b'.repeat(64), inferenceDispatched: false }));
284
+ const program = new commander_1.Command();
285
+ program.exitOverride();
286
+ program.configureOutput({ writeErr: () => undefined });
287
+ (0, model_policy_1.registerModelPolicyCommand)(program, { readEffectivePolicy: (() => ({ state: 'approved', policy: { content: { mappings: [mapping] } } })),
288
+ queryClaudeAuthStatus: queryClaudeAuthStatus, queryRuntimeExecutable: queryRuntimeExecutable,
289
+ readClaudeModelConfigDigest: (() => 'c'.repeat(64)),
290
+ ensureMachineKey: (() => Buffer.alloc(32, 7)) });
291
+ await program.parseAsync(['node', 'awm', 'model-policy', 'setup', '--provider', 'claude-code', '--json']);
292
+ expect(JSON.parse(String(out.mock.calls[0][0]))).toMatchObject({ state: 'setup-pending', provider: 'claude-code', machine: { runtimeVersion: '2.1.263', accountState: 'identified', configState: 'local-fingerprint' },
293
+ nativeDispatchVerified: false, actualModelVerified: false, inferenceDispatched: false });
294
+ expect(queryClaudeAuthStatus).toHaveBeenCalledTimes(1);
295
+ });
117
296
  });
@@ -84,7 +84,7 @@ describe('plan validate Commander wiring', () => {
84
84
  // not come out of validatePlanFile, so a spread-and-relabel fixture
85
85
  // cannot reach this path at all.
86
86
  const sliceId = 'S1';
87
- const sel = { selector: { kind: 'model', id: 'gpt-5.6-luna' }, effort: { kind: 'explicit', value: 'medium' } };
87
+ const sel = { selector: { kind: 'model', id: 'gpt-5.6-luna' }, effort: { kind: 'explicit', value: 'high' } };
88
88
  const full = { selector: { kind: 'model', id: 'gpt-5.6-sol' }, effort: { kind: 'explicit', value: 'high' } };
89
89
  const sha = 'a'.repeat(64);
90
90
  const content = { schema: 'model-policy/v1', mappings: [{ target: 'codex', runtimeKind: 'native', profiles: { mechanical: sel, integration: sel, judgment: sel }, fullCapability: full, degradation: { allowMissingModelOverride: false, allowMissingEffortOverride: false, allowMissingObservedIdentity: false } }], implementationBudget: { maxAttempts: 3, escalation: ['mechanical', 'integration', 'judgment'], judgmentEfforts: ['medium', 'high'] } };
@@ -115,7 +115,7 @@ describe('plan validate Commander wiring', () => {
115
115
  expect(emitted.envelope.executionDigest).toBe(v2Valid.executionDigest);
116
116
  // The point of the whole thing: that envelope reserves a first attempt,
117
117
  // which is what creates the lineage the escalation path later needs.
118
- const reserved = (0, journal_1.reserveRoutingAttempt)((0, types_1.emptyState)('main'), { obligationId: 'o1', lineageId: 'l1', envelope: emitted.envelope, fingerprint: 'e'.repeat(64) }, '2026-09-19T00:00:00.000Z');
118
+ const reserved = (0, journal_1.reserveRoutingAttempt)((0, types_1.emptyState)('main'), { obligationId: 'o1', lineageId: 'l1', envelope: emitted.envelope, fingerprint: 'e'.repeat(64), approval: () => ({ policy: readEffectivePolicy().policy, capabilities: receipt, checkedAt: new Date() }) }, '2026-09-19T00:00:00.000Z');
119
119
  expect(reserved.attemptId).toEqual(expect.any(String));
120
120
  expect(reserved.state.implementationLineages).toEqual([expect.objectContaining({ id: 'l1', sliceId, initialProfile: 'mechanical' })]);
121
121
  });
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -11,6 +44,8 @@ const checks_1 = require("../../../src/commands/preflight/checks");
11
44
  const preflight_1 = require("../../../src/commands/preflight");
12
45
  const run_1 = require("../../../src/commands/sensors/run");
13
46
  const check_1 = require("../../../src/core/currentness/check");
47
+ const store_1 = require("../../../src/core/model-policy/store");
48
+ const setupReadiness = __importStar(require("../../../src/core/model-policy/setup-readiness"));
14
49
  // Only `execSync` (used by `resolveOnPath` to check for `gh`/`glab`) is mocked — `git
15
50
  // remote get-url origin` runs for real via `execFileSync` against real tmpdir git repos,
16
51
  // same as every other check in this file exercises the real filesystem.
@@ -25,8 +60,13 @@ jest.mock('../../../src/commands/sensors/run', () => ({
25
60
  jest.mock('../../../src/core/currentness/check', () => ({
26
61
  checkCurrentness: jest.fn(),
27
62
  }));
63
+ jest.mock('../../../src/core/model-policy/store', () => ({
64
+ ...jest.requireActual('../../../src/core/model-policy/store'),
65
+ readEffectivePolicy: jest.fn(),
66
+ }));
28
67
  const mockRunSensors = run_1.runSensors;
29
68
  const mockCheckCurrentness = check_1.checkCurrentness;
69
+ const mockReadEffectivePolicy = store_1.readEffectivePolicy;
30
70
  /** Turn a tmpdir into a real git repo with (optionally) an `origin` remote. */
31
71
  function gitRepo(dir, remoteUrl) {
32
72
  (0, child_process_1.execFileSync)('git', ['init'], { cwd: dir, stdio: 'pipe' });
@@ -104,6 +144,7 @@ function writePartialKernel(dir) {
104
144
  const check = (r, id) => r.checks.find(c => c.id === id);
105
145
  describe('preflight', () => {
106
146
  beforeEach(() => {
147
+ mockReadEffectivePolicy.mockReturnValue({ state: 'absent' });
107
148
  mockCheckCurrentness.mockResolvedValue({
108
149
  checkedAt: '2026-08-26T00:00:00.000Z',
109
150
  compatibility: { status: 'not-checked' },
@@ -115,6 +156,30 @@ describe('preflight', () => {
115
156
  }],
116
157
  });
117
158
  });
159
+ it('advises machine model setup for an approved mapping without degrading ordinary harness readiness', async () => {
160
+ mockReadEffectivePolicy.mockReturnValue({
161
+ state: 'approved', provenance: 'user',
162
+ policy: { content: { mappings: [{ target: 'codex', runtimeKind: 'native' }] } },
163
+ });
164
+ const report = await (0, checks_1.preflight)(make({ manifest: { pack: 'generic', sensors: { security: { enabled: false } } } }));
165
+ expect(check(report, 'routing-setup')).toMatchObject({ advisory: true, ok: false, remedy: 'awm model-policy setup --provider codex --json' });
166
+ expect(report.status).toBe('ready');
167
+ });
168
+ it('labels sealed local coverage without claiming current machine verification or demanding setup', async () => {
169
+ const guidance = jest.spyOn(setupReadiness, 'routingSetupGuidance').mockReturnValueOnce([
170
+ { target: 'codex', runtimeKind: 'native', state: 'coverage-only' },
171
+ ]);
172
+ try {
173
+ const report = await (0, checks_1.preflight)(make({ manifest: { pack: 'generic', sensors: { security: { enabled: false } } } }));
174
+ expect(check(report, 'routing-setup')).toMatchObject({ advisory: true, ok: true,
175
+ detail: expect.stringContaining('do not verify current runtime/account/config scope') });
176
+ expect(check(report, 'routing-setup').remedy).toBeUndefined();
177
+ expect(report.status).toBe('ready');
178
+ }
179
+ finally {
180
+ guidance.mockRestore();
181
+ }
182
+ });
118
183
  afterEach(() => {
119
184
  mockRunSensors.mockReset();
120
185
  mockCheckCurrentness.mockReset();