deadbyte-mcp 0.15.1 → 0.15.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 (96) hide show
  1. package/MANIFEST.SHA256 +95 -64
  2. package/PROVENANCE.json +6 -5
  3. package/README.txt +36 -20
  4. package/RELEASE.json +24 -8
  5. package/SBOM.cdx.json +3 -3
  6. package/controller/README.TXT +2 -2
  7. package/controller/deadbyte-controller.ps1 +50 -2
  8. package/controller/deadbyte-process-policy.json +63 -1
  9. package/docs/ARCHITECTURE.md +3 -4
  10. package/package.json +88 -86
  11. package/scripts/autonomous-build.ps1 +1 -0
  12. package/scripts/autonomous-tests.ps1 +1 -0
  13. package/scripts/check-agent-backend-r46.mjs +77 -0
  14. package/scripts/check-atomic-resource-r46.mjs +84 -0
  15. package/scripts/check-autonomous-race-r46.mjs +160 -0
  16. package/scripts/check-coding-task-deadline-r46.mjs +59 -0
  17. package/scripts/check-deadline-cancellation-r46.mjs +49 -0
  18. package/scripts/check-process-deadline-r46.mjs +52 -0
  19. package/scripts/check-r46-background.mjs +5 -0
  20. package/scripts/deferred-slot-operation-r46.mjs +126 -0
  21. package/scripts/extract-r46-failures.mjs +5 -0
  22. package/scripts/final-closure-r46.mjs +98 -0
  23. package/scripts/final-closure-verify-r46.mjs +119 -0
  24. package/scripts/full-regression-r46.mjs +28 -0
  25. package/scripts/gate-windows-r46.ps1 +58 -0
  26. package/scripts/inspect-r46-active.mjs +2 -0
  27. package/scripts/r47-core-failures.mjs +1 -0
  28. package/scripts/refresh-process-policy.mjs +64 -7
  29. package/scripts/release-manifest.mjs +1 -1
  30. package/scripts/release-parity-r46.mjs +187 -0
  31. package/scripts/run-r46-full-regression-background.mjs +7 -0
  32. package/scripts/run-r46-windows-gate-background.mjs +6 -0
  33. package/scripts/run-r46-windows-gate-background.ps1 +10 -0
  34. package/scripts/windows-gate-evidence-r46.mjs +111 -0
  35. package/scripts/workload-contract-regression-r47.mjs +14 -0
  36. package/scripts/workload-stream-regression.mjs +16 -0
  37. package/scripts/workload-substrate-r47-regression.mjs +12 -0
  38. package/src/agent-backend-r44.mjs +75 -10
  39. package/src/atomic-mutation.mjs +55 -0
  40. package/src/autonomous-mcp-tools.mjs +4 -3
  41. package/src/autonomous-output-contracts.mjs +16 -3
  42. package/src/autonomous-runtime.mjs +83 -30
  43. package/src/capability-ledger.mjs +1 -0
  44. package/src/coding-mcp-tools.mjs +2 -2
  45. package/src/coding-output-contracts.mjs +18 -4
  46. package/src/coding-plane.mjs +3 -24
  47. package/src/coding-search.mjs +11 -2
  48. package/src/coding-task-runtime.mjs +41 -6
  49. package/src/compact-gateway-mcp-tools.mjs +7 -5
  50. package/src/deadbyte-cli.mjs +7 -3
  51. package/src/deadline-cancellation.mjs +83 -0
  52. package/src/machine-fs-mcp-tools.mjs +3 -3
  53. package/src/machine-fs-output-contracts.mjs +1 -1
  54. package/src/machine-fs-read-worker.mjs +46 -0
  55. package/src/machine-fs-smoke-client.mjs +1 -1
  56. package/src/machine-fs.mjs +66 -33
  57. package/src/mcp-server.mjs +10 -0
  58. package/src/mcp-smoke-client.mjs +4 -1
  59. package/src/observation-runtime.mjs +25 -4
  60. package/src/observation-smoke-client.mjs +1 -1
  61. package/src/process-mcp-tools.mjs +29 -8
  62. package/src/process-output-contracts.mjs +43 -3
  63. package/src/process-policy.mjs +3 -1
  64. package/src/process-runtime.mjs +152 -23
  65. package/src/process-smoke-client.mjs +67 -22
  66. package/src/release-generation.mjs +22 -3
  67. package/src/remote-device-r44.mjs +53 -15
  68. package/src/remote-mcp-smoke-client.mjs +1 -1
  69. package/src/resource-identity.mjs +59 -0
  70. package/src/runtime-update.mjs +526 -162
  71. package/src/stdio-console-guard.mjs +24 -0
  72. package/src/version.mjs +1 -1
  73. package/src/workload-substrate.mjs +87 -0
  74. package/test/cli-entrypoint.test.mjs +3 -3
  75. package/test/coding-runtime.test.mjs +12 -0
  76. package/test/coding-search-r36.test.mjs +7 -0
  77. package/test/compact-gateway-r36.test.mjs +28 -0
  78. package/test/core.test.mjs +1 -1
  79. package/test/full-max-catalog-r46.test.mjs +92 -0
  80. package/test/helpers/autonomous-r34-fixture.mjs +10 -1
  81. package/test/machine-fs-mcp-tools.test.mjs +4 -1
  82. package/test/machine-fs-runtime.test.mjs +18 -2
  83. package/test/observation-runtime.test.mjs +29 -2
  84. package/test/process-mcp-tools.test.mjs +27 -6
  85. package/test/process-policy-refresh.test.mjs +87 -10
  86. package/test/process-runtime.test.mjs +129 -2
  87. package/test/process-supervision.test.mjs +4 -2
  88. package/test/production-docs.test.mjs +3 -3
  89. package/test/r33-finalization.test.mjs +3 -3
  90. package/test/r45-finalization.test.mjs +1 -1
  91. package/test/release-generation.test.mjs +25 -11
  92. package/test/release-version.test.mjs +99 -44
  93. package/test/remote-device-r44.test.mjs +75 -0
  94. package/test/remote-r24-catalog.test.mjs +2 -2
  95. package/test/runtime-self-update.test.mjs +118 -1
  96. package/test/workload-substrate.test.mjs +22 -0
@@ -13,18 +13,58 @@ async function fixture() {
13
13
  const root = await mkdtemp(path.join(os.tmpdir(), 'deadbyte-process-refresh-'));
14
14
  const bin = path.join(root, 'bin');
15
15
  const controller = path.join(root, 'controller');
16
+ const systemRoot = path.join(root, 'Windows');
17
+ const system32 = path.join(systemRoot, 'System32');
18
+ const powershellDir = path.join(system32, 'WindowsPowerShell', 'v1.0');
16
19
  await mkdir(bin, { recursive: true });
17
20
  await mkdir(controller, { recursive: true });
21
+ await mkdir(powershellDir, { recursive: true });
22
+
18
23
  const hostPath = path.join(bin, 'deadbyte-process-host.exe');
19
24
  const hostBytes = Buffer.from('fresh-native-host\n');
25
+ const cmdPath = path.join(system32, 'cmd.exe');
26
+ const cmdBytes = Buffer.from('target-cmd\n');
27
+ const powershellPath = path.join(powershellDir, 'powershell.exe');
28
+ const powershellBytes = Buffer.from('target-powershell\n');
20
29
  await writeFile(hostPath, hostBytes);
30
+ await writeFile(cmdPath, cmdBytes);
31
+ await writeFile(powershellPath, powershellBytes);
32
+
21
33
  const policyPath = path.join(controller, 'deadbyte-process-policy.json');
22
- const policy = { schema:'deadbyte.process-policy.v1', enabled:true, grant_file:path.join(root,'runtime','grant.json'),
23
- state_dir:path.join(root,'state'), native_host:{ path:hostPath, sha256:'0'.repeat(64) },
24
- roots:{core:{path:root,deny_paths:[]}}, profiles:{probe:{executable:process.execPath,executable_sha256:'1'.repeat(64),root_ids:['core'],prefix_args:[],max_args:0,max_arg_bytes:256,max_sessions:1,max_input_bytes:4096,max_retained_output_bytes:4096,env_allow:[],input_actions:{}}}};
34
+ const profile = executable => ({
35
+ executable,
36
+ executable_sha256:'1'.repeat(64),
37
+ root_ids:['core'],
38
+ prefix_args:[],
39
+ transport:'pipe',
40
+ max_args:1,
41
+ max_arg_bytes:8192,
42
+ max_sessions:1,
43
+ max_input_bytes:4096,
44
+ max_retained_output_bytes:4096,
45
+ env_allow:[],
46
+ input_actions:{}
47
+ });
48
+ const policy = {
49
+ schema:'deadbyte.process-policy.v1',
50
+ enabled:true,
51
+ grant_file:path.join(root,'runtime','grant.json'),
52
+ state_dir:path.join(root,'state'),
53
+ native_host:{ path:hostPath, sha256:'0'.repeat(64) },
54
+ roots:{core:{path:root,deny_paths:[]}},
55
+ profiles:{
56
+ ping_hold:profile(cmdPath),
57
+ powershell:profile(powershellPath),
58
+ powershell_repl:profile(powershellPath)
59
+ }
60
+ };
25
61
  await writeFile(policyPath, `${JSON.stringify(policy,null,2)}\n`);
26
- return { root, policyPath, hostPath, hostBytes, policy };
62
+ return {
63
+ root, policyPath, hostPath, hostBytes, systemRoot,
64
+ cmdPath, cmdBytes, powershellPath, powershellBytes, policy
65
+ };
27
66
  }
67
+
28
68
  test('R33 candidate process policy self-binds to the current repository root', async () => {
29
69
  const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
30
70
  const policyPath = path.join(repoRoot, 'controller', 'deadbyte-process-policy.json');
@@ -33,32 +73,69 @@ test('R33 candidate process policy self-binds to the current repository root', a
33
73
  assert.equal(policy.state_dir, path.join(repoRoot, 'controller', 'runtime', 'process-state'));
34
74
  assert.equal(policy.native_host.path, path.join(repoRoot, 'bin', 'deadbyte-process-host.exe'));
35
75
  assert.equal(policy.roots.core.path, repoRoot);
76
+ assert.ok(policy.profiles.ping_hold);
77
+ assert.ok(policy.profiles.powershell);
78
+ assert.ok(policy.profiles.powershell_repl);
79
+ assert.equal(policy.profiles.powershell_repl.allow_raw_input,true);
80
+ assert.deepEqual(policy.profiles.powershell.prefix_args, ['-NoLogo','-NoProfile','-NonInteractive','-Command']);
81
+ assert.equal(policy.profiles.powershell.max_args, 1);
82
+ assert.equal(policy.profiles.powershell.max_arg_bytes, 8192);
36
83
  });
37
84
 
38
- test('R31 refresh changes only the native-host digest after the Windows build', async () => {
85
+ test('process policy refresh repins native host and Windows system executables', async () => {
39
86
  const f = await fixture();
40
- const result = await refreshProcessPolicy({ repoRoot:f.root, policyPath:f.policyPath });
87
+ const result = await refreshProcessPolicy({ repoRoot:f.root, policyPath:f.policyPath, systemRoot:f.systemRoot });
41
88
  const after = JSON.parse(await readFile(f.policyPath,'utf8'));
42
89
  assert.equal(after.native_host.path, f.hostPath);
43
90
  assert.equal(after.native_host.sha256, sha256(f.hostBytes));
91
+ assert.equal(after.profiles.ping_hold.executable, f.cmdPath);
92
+ assert.equal(after.profiles.ping_hold.executable_sha256, sha256(f.cmdBytes));
93
+ assert.equal(after.profiles.powershell.executable, f.powershellPath);
94
+ assert.equal(after.profiles.powershell.executable_sha256, sha256(f.powershellBytes));
95
+ assert.equal(after.profiles.powershell_repl.executable, f.powershellPath);
96
+ assert.equal(after.profiles.powershell_repl.executable_sha256, sha256(f.powershellBytes));
44
97
  assert.equal(result.native_host_sha256, sha256(f.hostBytes));
98
+ assert.equal(result.cmd_executable_sha256, sha256(f.cmdBytes));
99
+ assert.equal(result.powershell_executable_sha256, sha256(f.powershellBytes));
100
+ assert.equal(result.powershell_repl_executable_sha256, sha256(f.powershellBytes));
101
+
45
102
  const expected = structuredClone(f.policy);
46
103
  expected.native_host.sha256 = sha256(f.hostBytes);
104
+ expected.profiles.ping_hold.executable_sha256 = sha256(f.cmdBytes);
105
+ expected.profiles.powershell.executable_sha256 = sha256(f.powershellBytes);
106
+ expected.profiles.powershell_repl.executable_sha256 = sha256(f.powershellBytes);
47
107
  assert.deepEqual(after, expected);
48
108
  });
49
109
 
50
- test('R31 refresh fails closed when native-host path is not the candidate bin path', async () => {
110
+ test('process policy refresh fails closed when native-host path is not the candidate bin path', async () => {
51
111
  const f = await fixture();
52
112
  const raw = JSON.parse(await readFile(f.policyPath,'utf8'));
53
113
  raw.native_host.path = process.execPath;
54
114
  await writeFile(f.policyPath, `${JSON.stringify(raw,null,2)}\n`);
55
- await assert.rejects(() => refreshProcessPolicy({ repoRoot:f.root, policyPath:f.policyPath }), /native_host path must equal candidate bin/);
115
+ await assert.rejects(
116
+ () => refreshProcessPolicy({ repoRoot:f.root, policyPath:f.policyPath, systemRoot:f.systemRoot }),
117
+ /native_host path must equal candidate bin/
118
+ );
119
+ });
120
+
121
+ test('process policy refresh fails closed when a system profile path is not target-bound', async () => {
122
+ const f = await fixture();
123
+ const raw = JSON.parse(await readFile(f.policyPath,'utf8'));
124
+ raw.profiles.powershell.executable = process.execPath;
125
+ await writeFile(f.policyPath, `${JSON.stringify(raw,null,2)}\n`);
126
+ await assert.rejects(
127
+ () => refreshProcessPolicy({ repoRoot:f.root, policyPath:f.policyPath, systemRoot:f.systemRoot }),
128
+ /profile 'powershell' executable path mismatch/
129
+ );
56
130
  });
57
131
 
58
- test('R31 refresh refuses a malformed or disabled process policy', async () => {
132
+ test('process policy refresh refuses a malformed or disabled process policy', async () => {
59
133
  const f = await fixture();
60
134
  const raw = JSON.parse(await readFile(f.policyPath,'utf8'));
61
135
  raw.enabled = false;
62
136
  await writeFile(f.policyPath, `${JSON.stringify(raw,null,2)}\n`);
63
- await assert.rejects(() => refreshProcessPolicy({ repoRoot:f.root, policyPath:f.policyPath }), /schema\/enabled mismatch/);
137
+ await assert.rejects(
138
+ () => refreshProcessPolicy({ repoRoot:f.root, policyPath:f.policyPath, systemRoot:f.systemRoot }),
139
+ /schema\/enabled mismatch/
140
+ );
64
141
  });
@@ -12,6 +12,7 @@ import { generateTrustKeypair } from '../src/trust.mjs';
12
12
  const repo = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
13
13
  const host = path.join(repo, 'bin', 'deadbyte-process-host.exe');
14
14
  const cmd = 'C:\\Windows\\System32\\cmd.exe';
15
+ const powershell = 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
15
16
  const sha = bytes => createHash('sha256').update(bytes).digest('hex');
16
17
  const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
17
18
 
@@ -25,6 +26,7 @@ async function fixture() {
25
26
  const policyPath = path.join(root, 'process-policy.json');
26
27
  const hostSha = sha(await readFile(host));
27
28
  const cmdSha = sha(await readFile(cmd));
29
+ const powershellSha = sha(await readFile(powershell));
28
30
  const raw = {
29
31
  schema: PROCESS_POLICY_SCHEMA, enabled: true, grant_file: grantFile, state_dir: stateDir,
30
32
  native_host: { path: host, sha256: hostSha },
@@ -47,6 +49,18 @@ async function fixture() {
47
49
  prefix_args: ['/d', '/q'], max_args: 0, max_arg_bytes: 256,
48
50
  max_sessions: 1, max_input_bytes: 4096, max_retained_output_bytes: 65536,
49
51
  env_allow: ['PATH', 'TEMP', 'TMP'], input_actions: { ping: 'echo mustnotrun\r\n' }
52
+ },
53
+ powershell: {
54
+ executable: powershell, executable_sha256: powershellSha, root_ids: ['core'], transport: 'pipe',
55
+ prefix_args: ['-NoLogo','-NoProfile','-NonInteractive','-Command'], max_args: 1, max_arg_bytes: 8192,
56
+ max_sessions: 2, max_input_bytes: 65536, max_retained_output_bytes: 1048576,
57
+ env_allow: ['PATH','TEMP','TMP','SystemRoot','WINDIR','USERPROFILE','PSModulePath','COMSPEC','PATHEXT'], input_actions: {}
58
+ },
59
+ powershell_repl: {
60
+ executable: powershell, executable_sha256: powershellSha, root_ids: ['core'], transport: 'pipe', allow_raw_input: true,
61
+ prefix_args: ['-NoLogo','-NoProfile','-NonInteractive'], max_args: 0, max_arg_bytes: 256,
62
+ max_sessions: 2, max_input_bytes: 65536, max_retained_output_bytes: 4 * 1024 * 1024,
63
+ env_allow: ['PATH','TEMP','TMP','SystemRoot','WINDIR','USERPROFILE','PSModulePath','COMSPEC','PATHEXT'], input_actions: {}
50
64
  }
51
65
  }
52
66
  };
@@ -54,14 +68,14 @@ async function fixture() {
54
68
  const policy = await loadProcessPolicy(policyPath);
55
69
  await writeFile(grantFile, JSON.stringify({
56
70
  schema: PROCESS_GRANT_SCHEMA, policy_sha256: policy.policy_sha256,
57
- instance_nonce: 'a'.repeat(64), profile_ids: ['echo', 'hold', 'conptyhold'], root_ids: ['core'],
71
+ instance_nonce: 'a'.repeat(64), profile_ids: ['echo', 'hold', 'conptyhold', 'powershell', 'powershell_repl'], root_ids: ['core'],
58
72
  granted_at_utc: '2026-09-14T00:00:00Z'
59
73
  }));
60
74
  const keys = await generateTrustKeypair({
61
75
  privateKeyPath: path.join(trust, 'private.pem'), publicKeyPath: path.join(trust, 'public.pem')
62
76
  });
63
77
  return {
64
- root, project, policy, grantFile, stateDir,
78
+ root, project, policy, grantFile, stateDir, keys,
65
79
  runtime: createProcessRuntime({ policy, signingKeyPath: keys.privateKeyPath, verifyKeyPath: keys.publicKeyPath })
66
80
  };
67
81
  }
@@ -83,6 +97,12 @@ test('R31 runtime starts one approved profile and exposes ordered bounded output
83
97
  assert.ok(started.child_pid > 0);
84
98
  assert.match(started.creation_filetime, /^[0-9]+$/);
85
99
  assert.equal(started.profile_id, 'echo');
100
+ assert.equal(started.stream_id, started.session_id);
101
+ assert.equal(started.stream_generation, 1);
102
+ assert.equal(started.stream_next_seq, 1);
103
+ assert.equal(started.stream_coverage.logical_item_count, 0);
104
+ assert.equal(started.stream_coverage.retained_item_count, 0);
105
+ assert.equal(started.stream_coverage.complete, true);
86
106
  const observed = await waitFor(f.runtime, started.session_id, text => text.includes('DBR31RUNTIME:42'));
87
107
  assert.match(observed.text, /DBR31RUNTIME:42/);
88
108
  assert.equal(observed.page.offset, 0);
@@ -90,6 +110,113 @@ test('R31 runtime starts one approved profile and exposes ordered bounded output
90
110
  assert.equal(observed.page.truncated, false);
91
111
  });
92
112
 
113
+ test('R46 runtime executes fileless PowerShell source without ps1 materialization', { skip: process.platform !== 'win32' }, async () => {
114
+ const f = await fixture();
115
+ const source = "$ErrorActionPreference='Stop';$before=@(Get-ChildItem -LiteralPath $env:TEMP -Filter '*.ps1' -File -ErrorAction SilentlyContinue|ForEach-Object{$_.FullName});[Console]::WriteLine('DB_FILELESS_PS_TEST');[Console]::WriteLine('PSCommandPath=' + [string]$PSCommandPath);[Console]::WriteLine('InvocationPath=' + [string]$MyInvocation.MyCommand.Path);$after=@(Get-ChildItem -LiteralPath $env:TEMP -Filter '*.ps1' -File -ErrorAction SilentlyContinue|ForEach-Object{$_.FullName});$new=@($after|Where-Object{$_ -notin $before});[Console]::WriteLine('NEW_TEMP_PS1_COUNT=' + $new.Count)";
116
+ const started = await f.runtime.start({ profileId: 'powershell', rootId: 'core', cwd: '.', args: [source] });
117
+ const observed = await waitFor(f.runtime, started.session_id, text => text.includes('NEW_TEMP_PS1_COUNT=0'));
118
+ assert.match(observed.text, /DB_FILELESS_PS_TEST/);
119
+ assert.match(observed.text, /PSCommandPath=\r?\n/);
120
+ assert.match(observed.text, /InvocationPath=\r?\n/);
121
+ assert.match(observed.text, /NEW_TEMP_PS1_COUNT=0/);
122
+ const deadline = Date.now() + 5000;
123
+ let status = await f.runtime.status({ sessionId: started.session_id });
124
+ while (status.state === 'running' && Date.now() < deadline) {
125
+ await sleep(25);
126
+ status = await f.runtime.status({ sessionId: started.session_id });
127
+ }
128
+ assert.equal(status.state, 'exited');
129
+ assert.equal(status.exit_code, 0);
130
+ const verified = await f.runtime.verifyEventJournal({ sessionId: started.session_id });
131
+ assert.equal(verified.ok, true);
132
+ });
133
+
134
+ test('R46 process output retention evicts oldest bytes without losing tail identity under multi-megabyte output', { skip: process.platform !== 'win32' }, async () => {
135
+ const f = await fixture();
136
+ const source = "[Console]::Write(('A'*2097152));[Console]::WriteLine('DB_RING_TAIL_MARK')";
137
+ const started = await f.runtime.start({ profileId: 'powershell', rootId: 'core', cwd: '.', args: [source] });
138
+ const deadline = Date.now() + 10000;
139
+ let status = await f.runtime.status({ sessionId: started.session_id });
140
+ while (status.state === 'running' && Date.now() < deadline) {
141
+ await sleep(25);
142
+ status = await f.runtime.status({ sessionId: started.session_id });
143
+ }
144
+ assert.equal(status.state, 'exited');
145
+ assert.equal(status.exit_code, 0);
146
+ assert.ok(status.stream_head > 2 * 1024 * 1024);
147
+ assert.ok(status.earliest_offset > 0);
148
+ assert.ok(status.stream_head - status.earliest_offset <= 1024 * 1024);
149
+ const fromStart = await f.runtime.read({ sessionId: started.session_id, offset: 0, maxBytes: 4096 });
150
+ assert.equal(fromStart.truncated, true);
151
+ assert.equal(fromStart.offset, status.earliest_offset);
152
+ const tail = await f.runtime.read({ sessionId: started.session_id, offset: -4096, maxBytes: 4096 });
153
+ const tailText = Buffer.from(tail.data_base64, 'base64').toString('utf8');
154
+ assert.match(tailText, /DB_RING_TAIL_MARK/);
155
+ const verified = await f.runtime.verifyEventJournal({ sessionId: started.session_id });
156
+ assert.equal(verified.ok, true);
157
+ const recoveredRuntime = createProcessRuntime({
158
+ policy: f.policy,
159
+ signingKeyPath: f.keys.privateKeyPath,
160
+ verifyKeyPath: f.keys.publicKeyPath
161
+ });
162
+ const recovered = await recoveredRuntime.status({ sessionId: started.session_id });
163
+ assert.equal(recovered.stream_id, null);
164
+ assert.equal(recovered.stream_generation, null);
165
+ assert.equal(recovered.stream_next_seq, null);
166
+ assert.equal(recovered.stream_coverage, null);
167
+ assert.ok(recovered.stream_head > 2 * 1024 * 1024);
168
+ });
169
+
170
+ test('R46 process raw input keeps persistent PowerShell state with bounded wait and tail reads', { skip: process.platform !== 'win32' }, async () => {
171
+ const f = await fixture();
172
+ const started = await f.runtime.start({ profileId: 'powershell_repl', rootId: 'core', cwd: '.', args: [] });
173
+ try {
174
+ const first = await f.runtime.write({ sessionId: started.session_id, input: "$x=41;[Console]::WriteLine('DB_REPL_SET')", appendNewline: true });
175
+ assert.equal(first.session.state, 'running');
176
+ assert.match(first.logical_sha256, /^[0-9a-f]{64}$/);
177
+ const page1 = await f.runtime.read({ sessionId: started.session_id, offset: 0, maxBytes: 65536, waitMs: 3000, waitFor: 'DB_REPL_SET' });
178
+ const text1 = Buffer.from(page1.data_base64, 'base64').toString('utf8');
179
+ assert.match(text1, /DB_REPL_SET/);
180
+
181
+ const beforeSecond = (await f.runtime.status({ sessionId: started.session_id })).stream_head;
182
+ await f.runtime.write({ sessionId: started.session_id, input: "[Console]::WriteLine('DB_REPL_VALUE=' + ($x+1))", appendNewline: true });
183
+ const waited = await f.runtime.read({ sessionId: started.session_id, offset: beforeSecond, maxBytes: 65536, waitMs: 3000, waitFor: 'DB_REPL_VALUE=42' });
184
+ const waitedText = Buffer.from(waited.data_base64, 'base64').toString('utf8');
185
+ assert.equal(waited.wait_satisfied, true);
186
+ assert.match(waitedText, /DB_REPL_VALUE=42/);
187
+ const tail = await f.runtime.read({ sessionId: started.session_id, offset: -4096, maxBytes: 4096, waitMs: 0 });
188
+ const tailText = Buffer.from(tail.data_base64, 'base64').toString('utf8');
189
+ assert.match(tailText, /DB_REPL_VALUE=42/);
190
+
191
+ const journal = await readFile(path.join(f.stateDir, `${started.session_id}.jsonl`), 'utf8');
192
+ assert.doesNotMatch(journal, /DB_REPL_SET|DB_REPL_VALUE|\$x=41/);
193
+ const verified = await f.runtime.verifyEventJournal({ sessionId: started.session_id });
194
+ assert.equal(verified.ok, true);
195
+ assert.ok(verified.event_count >= 3);
196
+ } finally {
197
+ await f.runtime.terminate({ sessionId: started.session_id }).catch(() => {});
198
+ }
199
+ });
200
+
201
+ test('R46 raw process input is profile-opt-in, bounded, and rechecks standing authority', { skip: process.platform !== 'win32' }, async () => {
202
+ const f = await fixture();
203
+ const hold = await f.runtime.start({ profileId: 'hold', rootId: 'core', cwd: '.', args: [] });
204
+ try {
205
+ await assert.rejects(() => f.runtime.write({ sessionId: hold.session_id, input: 'echo forbidden', appendNewline: true }), /does not allow raw input/);
206
+ } finally {
207
+ await f.runtime.terminate({ sessionId: hold.session_id }).catch(() => {});
208
+ }
209
+
210
+ const repl = await f.runtime.start({ profileId: 'powershell_repl', rootId: 'core', cwd: '.', args: [] });
211
+ try {
212
+ await assert.rejects(() => f.runtime.write({ sessionId: repl.session_id, input: 'x'.repeat(65536), appendNewline: true }), /exceeds profile input bound/);
213
+ await rm(f.grantFile);
214
+ await assert.rejects(() => f.runtime.write({ sessionId: repl.session_id, input: 'Write-Output denied', appendNewline: true }), /process plane is disarmed/);
215
+ } finally {
216
+ await f.runtime.terminate({ sessionId: repl.session_id }).catch(() => {});
217
+ }
218
+ });
219
+
93
220
  test('R31 runtime lists, reports and terminates only its owned session', { skip: process.platform !== 'win32' }, async () => {
94
221
  const f = await fixture();
95
222
  const started = await f.runtime.start({ profileId: 'hold', rootId: 'core', cwd: '.', args: [] });
@@ -7,7 +7,7 @@ const runtimePath = fileURLToPath(new URL('../src/process-runtime.mjs', import.m
7
7
  const serverPath = fileURLToPath(new URL('../src/mcp-server.mjs', import.meta.url));
8
8
  const toolsPath = fileURLToPath(new URL('../src/process-mcp-tools.mjs', import.meta.url));
9
9
 
10
- test('R32 process supervision is policy-gated and registers the bounded named-action tool', async () => {
10
+ test('R46 process supervision is policy-gated and exposes bounded action plus opt-in raw input', async () => {
11
11
  const runtimeSource = await readFile(runtimePath, 'utf8');
12
12
  const serverSource = await readFile(serverPath, 'utf8');
13
13
  const toolsSource = await readFile(toolsPath, 'utf8');
@@ -20,5 +20,7 @@ test('R32 process supervision is policy-gated and registers the bounded named-ac
20
20
  assert.match(serverSource, /processRuntime/);
21
21
  assert.match(toolsSource, /process_session_action/);
22
22
  assert.match(toolsSource, /action_id/);
23
- assert.doesNotMatch(toolsSource, /raw_stdin|raw_input/);
23
+ assert.match(toolsSource, /process_session_write/);
24
+ assert.match(toolsSource, /append_newline/);
25
+ assert.doesNotMatch(toolsSource, /caller-selected executable|raw_stdin/);
24
26
  });
@@ -9,9 +9,9 @@ const readme=()=>readFile(path.join(root,'README.txt'),'utf8');
9
9
 
10
10
  test('production README documents one-command stdio configs for major MCP clients',async()=>{
11
11
  const text=await readme();
12
- assert.match(text,/npx -y deadbyte-mcp@0\.15\.1 mcp/);
12
+ assert.match(text,/npx -y deadbyte-mcp@0\.15\.2 mcp/);
13
13
  assert.match(text,/CLAUDE DESKTOP/);
14
- assert.match(text,/"mcpServers"[\s\S]*?"command"\s*:\s*"npx"[\s\S]*?"-y"[\s\S]*?"deadbyte-mcp@0\.15\.1"[\s\S]*?"mcp"/);
14
+ assert.match(text,/"mcpServers"[\s\S]*?"command"\s*:\s*"npx"[\s\S]*?"-y"[\s\S]*?"deadbyte-mcp@0\.15\.2"[\s\S]*?"mcp"/);
15
15
  assert.match(text,/CURSOR/);
16
16
  assert.match(text,/\.cursor\/mcp\.json/);
17
17
  assert.match(text,/VS CODE/);
@@ -20,7 +20,7 @@ test('production README documents one-command stdio configs for major MCP client
20
20
  assert.match(text,/CODEX/);
21
21
  assert.match(text,/\[mcp_servers\.deadbyte\]/);
22
22
  assert.match(text,/command\s*=\s*"npx"/);
23
- assert.match(text,/args\s*=\s*\["-y",\s*"deadbyte-mcp@0\.15\.1",\s*"mcp"\]/);
23
+ assert.match(text,/args\s*=\s*\["-y",\s*"deadbyte-mcp@0\.15\.2",\s*"mcp"\]/);
24
24
  });
25
25
 
26
26
  test('production README records tracer bullet, semantic scope, remote UX, safety and document extension',async()=>{
@@ -19,9 +19,9 @@ test('R34 public parity catalog is exact, unique, and includes production coding
19
19
 
20
20
  test('release parity and final verifier are package entry points', async () => {
21
21
  const pkg = JSON.parse(await text('package.json'));
22
- assert.equal(pkg.scripts['release:parity'], 'node scripts/release-parity-r45.mjs');
23
- assert.equal(pkg.scripts['release:final:write'], 'node scripts/final-closure-r45.mjs');
24
- assert.equal(pkg.scripts['release:final:verify'], 'node scripts/final-closure-verify-r45.mjs');
22
+ assert.equal(pkg.scripts['release:parity'], 'node scripts/release-parity-r46.mjs');
23
+ assert.equal(pkg.scripts['release:final:write'], 'node scripts/final-closure-r46.mjs');
24
+ assert.equal(pkg.scripts['release:final:verify'], 'node scripts/final-closure-verify-r46.mjs');
25
25
  assert.equal(typeof validateParityEvidence, 'function');
26
26
  assert.equal(typeof verifyFinalClosureObject, 'function');
27
27
  });
@@ -79,6 +79,6 @@ test('R45 release machinery binds 0.15.1, 82/43 surfaces, Host v2 bootstrap and
79
79
  assert.match(finalizer,/host_inline_native/);assert.match(finalizer,/native_hardware_observation/);assert.match(finalizer,/doctor_release_truth/);
80
80
  assert.match(evidence,/host_inline_native:true/);assert.match(evidence,/native_hardware_observation:true/);assert.match(evidence,/doctor_release_truth:true/);
81
81
  assert.match(manifestSource,/excludedPackagePrefixes = \[[^\]]*'tmp\/'[^\]]*'\.deadbyte-machine-fs-recovery\/'[^\]]*\]/);
82
- assert.match(manifestSource,/excludedPackagePaths = new Set\(\['controller\/deadbyte-host-policy\.json'\]\)/);
82
+ assert.match(manifestSource,/excludedPackagePaths = new Set\(\['controller\/deadbyte-host-policy\.json','controller\/deadbyte-coding-policy\.json'\]\)/);
83
83
  assert.match(manifestSource,/excludedPackagePrefixes\.some\(prefix => rel\.startsWith\(prefix\)\)/);
84
84
  });
@@ -16,7 +16,12 @@ function command(executable='C:/Windows/System32/cmd.exe'){
16
16
  test('R27 generation bundle rebinds authority and mutable state outside the release slot', async () => {
17
17
  const base=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r27-generation-'));
18
18
  const state=path.join(base,'state'),release=path.join(base,'release'),workspace=path.join(base,'workspace');
19
- await mkdir(path.join(release,'scripts'),{recursive:true}); await mkdir(path.join(release,'bin'),{recursive:true}); await mkdir(workspace,{recursive:true});
19
+ const systemRoot=path.join(base,'Windows'),system32=path.join(systemRoot,'System32');
20
+ const powershellDir=path.join(system32,'WindowsPowerShell','v1.0');
21
+ await mkdir(path.join(release,'scripts'),{recursive:true}); await mkdir(path.join(release,'bin'),{recursive:true}); await mkdir(workspace,{recursive:true}); await mkdir(powershellDir,{recursive:true});
22
+ const cmdPath=path.join(system32,'cmd.exe'),cmdBytes=Buffer.from('target-cmd-bytes\\n');
23
+ const powershellPath=path.join(powershellDir,'powershell.exe'),powershellBytes=Buffer.from('target-powershell-bytes\\n');
24
+ await writeFile(cmdPath,cmdBytes); await writeFile(powershellPath,powershellBytes);
20
25
  await writeFile(path.join(release,'scripts','gate.ps1'),'Write-Output gate\n');
21
26
  await writeFile(path.join(release,'bin','deadbyte-process-host.exe'),'process-host-bytes\n');
22
27
  const desktopObserver=Buffer.from('desktop-observer-bytes\n');
@@ -47,7 +52,10 @@ test('R27 generation bundle rebinds authority and mutable state outside the rele
47
52
  const processPolicy={schema:'deadbyte.process-policy.v1',enabled:true,grant_file:'C:/old/process-grant.json',state_dir:'C:/old/process-state',
48
53
  native_host:{path:'C:/old/deadbyte-process-host.exe',sha256:'0'.repeat(64)},
49
54
  roots:{core:{path:'C:/old/core',deny_paths:['node_modules']}},
50
- profiles:{probe:{executable:'C:/Windows/System32/ping.exe',executable_sha256:EXE,root_ids:['core'],prefix_args:['127.0.0.1','-n','2'],max_args:0,max_arg_bytes:256,max_sessions:1,max_input_bytes:4096,max_retained_output_bytes:65536,env_allow:['PATH','TEMP','TMP'],input_actions:{}}}};
55
+ profiles:{
56
+ ping_hold:{executable:'C:/stale/cmd.exe',executable_sha256:EXE,root_ids:['core'],prefix_args:['/d','/q'],transport:'pipe',max_args:0,max_arg_bytes:256,max_sessions:1,max_input_bytes:4096,max_retained_output_bytes:65536,env_allow:['PATH','TEMP','TMP'],input_actions:{ping:'echo DEADBYTE_ACTION_PING\\r\\n'}},
57
+ powershell:{executable:'C:/stale/powershell.exe',executable_sha256:EXE,root_ids:['core'],prefix_args:['-NoLogo','-NoProfile','-NonInteractive','-Command'],transport:'pipe',max_args:1,max_arg_bytes:8192,max_sessions:4,max_input_bytes:65536,max_retained_output_bytes:1048576,env_allow:['PATH','TEMP','TMP','SystemRoot','WINDIR','USERPROFILE','PSModulePath','COMSPEC','PATHEXT'],input_actions:{}}
58
+ }};
51
59
  const desktopPolicy={schema:'deadbyte.desktop-policy.v1',enabled:true,grant_file:'C:/old/desktop-grant.json',evidence_dir:'C:/old/desktop-evidence',
52
60
  allowed_input_desktops:['Default'],allowed_actions:['click_primary','key_chord'],
53
61
  limits:{max_frame_age_ms:2000,max_frame_bytes:8388608,capture_timeout_ms:5000,input_timeout_ms:2000,ground_timeout_ms:5000,post_observe_timeout_ms:5000,max_preview_bytes:1048576,max_text_bytes:4096},
@@ -59,7 +67,8 @@ test('R27 generation bundle rebinds authority and mutable state outside the rele
59
67
  await writeFile(path.join(development,'scripts','gate-windows-old.ps1'),'Write-Output old-gate\n');
60
68
  await writeFile(path.join(development,'scripts','gate-windows-current.ps1'),'Write-Output current-gate\n');
61
69
  await writeFile(path.join(development,'package.json'),JSON.stringify({scripts:{'gate:windows':'powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-current.ps1'}}));
62
- const result=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
70
+ const build=args=>createGenerationBundle({...args,systemRoot});
71
+ const result=await build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
63
72
  const verified=await verifyGenerationBundle(result.generation_root,result.generation_manifest_sha256);
64
73
  assert.equal(verified.files,7);
65
74
  const generatedProcess=JSON.parse(await readFile(result.process_policy_path,'utf8'));
@@ -68,6 +77,11 @@ test('R27 generation bundle rebinds authority and mutable state outside the rele
68
77
  assert.equal(generatedProcess.roots.core.path,path.resolve(development));
69
78
  assert.equal(generatedProcess.native_host.path,path.join(path.resolve(release),'bin','deadbyte-process-host.exe'));
70
79
  assert.equal(generatedProcess.native_host.sha256,sha(Buffer.from('process-host-bytes\n')));
80
+ assert.equal(generatedProcess.profiles.ping_hold.executable,cmdPath);
81
+ assert.equal(generatedProcess.profiles.ping_hold.executable_sha256,sha(cmdBytes));
82
+ assert.equal(generatedProcess.profiles.powershell.executable,powershellPath);
83
+ assert.equal(generatedProcess.profiles.powershell.executable_sha256,sha(powershellBytes));
84
+ assert.deepEqual(generatedProcess.profiles.powershell.prefix_args,['-NoLogo','-NoProfile','-NonInteractive','-Command']);
71
85
  const generatedDesktop=JSON.parse(await readFile(result.desktop_policy_path,'utf8'));
72
86
  assert.equal(generatedDesktop.grant_file,path.join(path.resolve(state),'runtime','desktop-grant.json'));
73
87
  assert.equal(generatedDesktop.evidence_dir,path.join(path.resolve(state),'runtime','desktop-evidence'));
@@ -129,44 +143,44 @@ test('R27 generation bundle rebinds authority and mutable state outside the rele
129
143
  assert.match(path.basename(result.generation_root),/^v0\.8\.3-aaaaaaaaaaaaaaaa-g[0-9a-f]{16}$/);
130
144
  const changedConfig=structuredClone(currentConfig);
131
145
  changedConfig.Bridge.Arguments='bridge-v2.mjs';
132
- const second=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:changedConfig,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
146
+ const second=await build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:changedConfig,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
133
147
  assert.notEqual(second.generation_root,result.generation_root);
134
148
  assert.notEqual(second.generation_seed_sha256,result.generation_seed_sha256);
135
149
  const endpointChanged=structuredClone(currentConfig);
136
150
  endpointChanged.McpUrlFileSha256='2'.repeat(64);
137
- const third=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:endpointChanged,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
151
+ const third=await build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:endpointChanged,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
138
152
  assert.notEqual(third.generation_root,result.generation_root);
139
153
  assert.notEqual(third.generation_seed_sha256,result.generation_seed_sha256);
140
154
  const machineDisabled=structuredClone(currentConfig);
141
155
  machineDisabled.MachineRuntimeEnabled=false;
142
- const fourth=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:machineDisabled,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
156
+ const fourth=await build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:machineDisabled,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
143
157
  assert.notEqual(fourth.generation_root,result.generation_root);
144
158
  assert.notEqual(fourth.generation_seed_sha256,result.generation_seed_sha256);
145
159
  const machineFsDisabled=structuredClone(currentConfig);
146
160
  machineFsDisabled.MachineFsRuntimeEnabled=false;
147
- const fifth=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:machineFsDisabled,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
161
+ const fifth=await build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:machineFsDisabled,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
148
162
  assert.notEqual(fifth.generation_root,result.generation_root);
149
163
  assert.notEqual(fifth.generation_seed_sha256,result.generation_seed_sha256);
150
164
  const observationDisabled=structuredClone(currentConfig);
151
165
  observationDisabled.ObservationRuntimeEnabled=false;
152
- const sixth=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:observationDisabled,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
166
+ const sixth=await build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:observationDisabled,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
153
167
  assert.notEqual(sixth.generation_root,result.generation_root);
154
168
  assert.notEqual(sixth.generation_seed_sha256,result.generation_seed_sha256);
155
169
  const desktopDisabled=structuredClone(currentConfig);
156
170
  desktopDisabled.DesktopRuntimeEnabled=false;
157
- const desktopVariant=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:desktopDisabled,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
171
+ const desktopVariant=await build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:desktopDisabled,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
158
172
  assert.notEqual(desktopVariant.generation_root,result.generation_root);
159
173
  assert.notEqual(desktopVariant.generation_seed_sha256,result.generation_seed_sha256);
160
174
  const desktopTampered=structuredClone(desktopPolicy);
161
175
  desktopTampered.input.sha256='f'.repeat(64);
162
- await assert.rejects(createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy:desktopTampered}),/desktop input helper SHA-256 mismatch/);
176
+ await assert.rejects(build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy:desktopTampered}),/desktop input helper SHA-256 mismatch/);
163
177
  const semanticConfig2Path=path.join(base,'semantic-lsp-v2.json');
164
178
  const semanticConfig2Bytes=Buffer.from(JSON.stringify({schema:'deadbyte.semantic-lsp-config.v1',servers:[{id:'changed'}]})+'\n','utf8');
165
179
  await writeFile(semanticConfig2Path,semanticConfig2Bytes);
166
180
  const semanticChanged=structuredClone(currentConfig);
167
181
  semanticChanged.SemanticLspConfigFile=semanticConfig2Path;
168
182
  semanticChanged.SemanticLspConfigSha256=sha(semanticConfig2Bytes);
169
- const seventh=await createGenerationBundle({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:semanticChanged,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
183
+ const seventh=await build({stateRoot:state,releaseRoot:release,developmentRoot:development,workspaceRoot:workspace,releaseId:'v0.8.3-aaaaaaaaaaaaaaaa',currentConfig:semanticChanged,codingPolicy:coding,autonomousPolicy:autonomous,hostPolicy:host,processPolicy,desktopPolicy});
170
184
  assert.notEqual(seventh.generation_root,result.generation_root);
171
185
  assert.notEqual(seventh.generation_seed_sha256,result.generation_seed_sha256);
172
186
  await verifyGenerationBundle(result.generation_root,result.generation_manifest_sha256);