deadbyte-mcp 0.15.61 → 0.15.63

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 (83) hide show
  1. package/MANIFEST.SHA256 +81 -32
  2. package/PROVENANCE.json +38 -11
  3. package/README.txt +18 -18
  4. package/RELEASE.json +59 -15
  5. package/SBOM.cdx.json +2 -2
  6. package/TEST-MATRIX.json +31 -2
  7. package/bridge/package.json +1 -1
  8. package/controller/deadbyte-controller.ps1 +78 -1
  9. package/controller/deadbyte-process-policy.json +4 -4
  10. package/docs/R156-LOOP-AND-EPOCH-ROUTING.md +86 -0
  11. package/docs/R157-ARCHITECTURE-DEPENDENCIES.md +58 -0
  12. package/docs/R157-ARCHITECTURE-GRAPH.json +2874 -0
  13. package/docs/R157-ENGINEERING-HANDOFF.md +71 -0
  14. package/docs/R157-FILE-DELTA.json +80 -0
  15. package/docs/R157-FOCUSED-VERIFICATION.log +0 -0
  16. package/docs/R157-REFERENCE-CAPABILITY-MATRIX.md +207 -0
  17. package/docs/R157-REFERENCE-DECISIONS.md +46 -0
  18. package/docs/R157-REFERENCE-INVENTORY.json +2849 -0
  19. package/docs/R158-COMBINED-REGRESSION.log +0 -0
  20. package/docs/R158-DELTA.json +80 -0
  21. package/docs/R158-EPOCH-BOOTSTRAP-GREEN.log +0 -0
  22. package/docs/R158-EPOCH-BOOTSTRAP-RED.log +0 -0
  23. package/docs/R158-EPOCH-IDENTITY-RED.log +0 -0
  24. package/docs/R158-FOCUSED-GREEN.log +0 -0
  25. package/docs/R158-PROTECTED-EPOCH-VERIFIED.md +43 -0
  26. package/docs/R158-PROTECTED-EXACT-SOURCE-LIVE.log +0 -0
  27. package/docs/R158-UPDATER-REGRESSION.log +0 -0
  28. package/docs/R159-COMPLETED-HISTORY-BACKUP/deadbyte-cli.mjs.before +965 -0
  29. package/docs/R159-COMPLETED-HISTORY-BACKUP/legacy-marker-evidence-r159.mjs.before +102 -0
  30. package/docs/R159-COMPLETED-HISTORY-BACKUP/r159-legacy-marker-evidence.test.mjs.before +79 -0
  31. package/docs/R159-COMPLETED-HISTORY-PATCH.json +26 -0
  32. package/docs/R159-MARKER-LOCATOR-CHECKPOINT.md +46 -0
  33. package/docs/R160-ENGINEERING-HANDOFF.md +32 -0
  34. package/docs/R160-REFERENCE-CAPABILITY-MATRIX.json +165 -0
  35. package/package.json +2 -2
  36. package/scripts/gate-windows-r160.ps1 +57 -0
  37. package/scripts/npm-release-r48.mjs +10 -0
  38. package/scripts/npm-release-readiness-r163.mjs +67 -0
  39. package/scripts/npm-release-readiness-r165.mjs +68 -0
  40. package/src/autonomous-supervisor.mjs +21 -4
  41. package/src/deadbyte-cli.mjs +90 -50
  42. package/src/legacy-marker-evidence-r159.mjs +128 -0
  43. package/src/package-identity-r160.mjs +61 -0
  44. package/src/release-generation.mjs +13 -0
  45. package/src/release-slot.mjs +2 -1
  46. package/src/remote-live-log.mjs +30 -2
  47. package/src/runtime-update.mjs +18 -6
  48. package/src/trusted-epoch-bootstrap-r158.mjs +42 -0
  49. package/src/version.mjs +1 -1
  50. package/src/windows-powershell-environment.mjs +5 -2
  51. package/test/r106-trusted-powershell-spawn.test.mjs +1 -0
  52. package/test/r130-release-security-contract.test.mjs +9 -9
  53. package/test/r132-release-identity.test.mjs +12 -10
  54. package/test/r153-prepublish-identity.test.mjs +25 -4
  55. package/test/r153-staging-leaf-acl.test.mjs +5 -2
  56. package/test/r155-commander-live-log.test.mjs +44 -0
  57. package/test/r155-default-live-log.test.mjs +89 -0
  58. package/test/r156-epoch-route-smoke.ps1 +48 -0
  59. package/test/r156-supervisor-pacing.test.mjs +59 -0
  60. package/test/r157-architecture-map.mjs +61 -0
  61. package/test/r157-reference-survey.mjs +91 -0
  62. package/test/r157-supervisor-singleflight.test.mjs +32 -0
  63. package/test/r158-epoch-bootstrap.test.mjs +34 -0
  64. package/test/r159-legacy-marker-evidence.test.mjs +103 -0
  65. package/test/r159-legacy-marker-evidence.test.mjs.before-assertion-fix-20261025-120246.bak +100 -0
  66. package/test/r160-marker-proof.test.mjs +87 -0
  67. package/test/r160-package-decision-manifest.test.mjs +67 -0
  68. package/test/r160-release-contract.test.mjs +30 -0
  69. package/test/r160-stable-launcher.test.mjs +10 -0
  70. package/test/r163-isolated-slot-rollback-restore.test.mjs +58 -0
  71. package/test/r163-publish-fence.test.mjs +13 -0
  72. package/test/r164-remote-history-skew.test.mjs +13 -0
  73. package/test/r165-live-cli-skew.test.mjs +90 -0
  74. package/test/r165-publish-fence.test.mjs +13 -0
  75. package/test/r48-release-contract.test.mjs +7 -1
  76. package/test/r58-launcher-shell.test.mjs +4 -1
  77. package/test/r59-tool-surface-compat.test.mjs +1 -1
  78. package/test/r65-cli-invocation.test.mjs +27 -7
  79. package/test/release-generation.test.mjs +16 -0
  80. package/test/remote-live-log-r37.test.mjs +5 -3
  81. package/test/remote-session-cli.test.mjs +11 -11
  82. package/test/stabilization-state-root.test.mjs +2 -1
  83. package/node_modules/which/CHANGELOG.md +0 -166
@@ -0,0 +1,102 @@
1
+ import {readdir,lstat,readFile} from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import {createHash} from 'node:crypto';
4
+
5
+ const H=/^[0-9a-f]{64}$/;
6
+ const digest=b=>createHash('sha256').update(b).digest('hex');
7
+ function samePredecessor(a,b){
8
+ return !!a&&!!b&&['release_id','version','manifest_sha256','generation_manifest_sha256']
9
+ .every(k=>typeof a[k]==='string'&&a[k]===b[k]);
10
+ }
11
+ async function regular(file){
12
+ const st=await lstat(file);
13
+ if(!st.isFile()||st.isSymbolicLink())throw new Error('R159 evidence file must be regular and not a link');
14
+ }
15
+ function strictJson(bytes,label){
16
+ let result;
17
+ try{result=JSON.parse(bytes.toString('utf8').replace(/^\uFEFF/,''));}
18
+ catch{throw new Error('R159 '+label+' invalid JSON');}
19
+ if(!result||typeof result!=='object'||Array.isArray(result))
20
+ throw new Error('R159 '+label+' invalid object');
21
+ return result;
22
+ }
23
+ // Examine ONLY local immutable receipt candidates. It must never infer a live
24
+ // process state, delete a marker, grant an authority plane, or mutate evidence.
25
+ export async function selectLegacyMarkerEvidence({evidenceDir,activePointer}){
26
+ if(typeof evidenceDir!=='string'||!path.isAbsolute(evidenceDir))
27
+ throw new Error('R159 evidence root must be absolute');
28
+ let entries;
29
+ try{entries=await readdir(evidenceDir,{withFileTypes:true});}
30
+ catch(e){if(e?.code==='ENOENT')return {kind:'none'};throw e;}
31
+ if(entries.length>4096)throw new Error('R159 evidence inventory exceeds bounded scan');
32
+ const fileSet=new Map(entries.map(e=>[e.name,e]));
33
+ const locatorPath=path.join(evidenceDir,'r153-pending-migration.json');
34
+ let located=null;
35
+ const locatorEntry=fileSet.get('r153-pending-migration.json');
36
+ if(locatorEntry){
37
+ if(!locatorEntry.isFile()||locatorEntry.isSymbolicLink())
38
+ throw new Error('R159 locator is not regular');
39
+ await regular(locatorPath);
40
+ const locator=strictJson(await readFile(locatorPath),'legacy locator');
41
+ if(locator.schema!=='deadbyte.r153-pending-migration.v1'||
42
+ !H.test(String(locator.marker_sha256??''))||
43
+ !H.test(String(locator.receipt_sha256??''))||
44
+ typeof locator.receipt_path!=='string')
45
+ throw new Error('R159 legacy locator schema invalid');
46
+ const expected=path.join(evidenceDir,'marker-'+locator.marker_sha256+'.terminal.json');
47
+ if(path.resolve(locator.receipt_path).toLowerCase()!==path.resolve(expected).toLowerCase())
48
+ throw new Error('R159 legacy locator receipt path mismatch');
49
+ await regular(expected);
50
+ const raw=await readFile(expected);
51
+ if(digest(raw)!==locator.receipt_sha256)
52
+ throw new Error('R159 legacy locator receipt hash mismatch');
53
+ const terminal=strictJson(raw,'located terminal');
54
+ if(terminal.schema!=='deadbyte.r153-marker-reconciliation.v1'||
55
+ terminal.state!=='MARKER_RECONCILED'||terminal.marker_sha256!==locator.marker_sha256)
56
+ throw new Error('R159 located terminal identity mismatch');
57
+ if(samePredecessor(terminal.predecessor,activePointer))
58
+ located={kind:'located',receiptPath:expected,receiptSha256:locator.receipt_sha256,
59
+ markerSha256:locator.marker_sha256};
60
+ }
61
+ const candidates=[];
62
+ for(const entry of entries){
63
+ const match=/^marker-([a-f0-9]{64})\.intent\.json$/.exec(entry.name);
64
+ if(!match)continue;
65
+ if(!entry.isFile()||entry.isSymbolicLink())throw new Error('R159 intent is not regular');
66
+ const intent=path.join(evidenceDir,entry.name);
67
+ await regular(intent);
68
+ const intentBytes=await readFile(intent),value=strictJson(intentBytes,'recovery intent');
69
+ if(value.schema!=='deadbyte.r153-marker-reconciliation-intent.v1'||
70
+ value.state!=='RECONCILIATION_CLAIMED'||value.marker_sha256!==match[1])
71
+ throw new Error('R159 intent filename/identity mismatch');
72
+ if(!samePredecessor(value.predecessor,activePointer))continue;
73
+ const terminal=path.join(evidenceDir,'marker-'+match[1]+'.terminal.json');
74
+ const terminalEntry=fileSet.get(path.basename(terminal));
75
+ let terminalExists=false;
76
+ if(terminalEntry){
77
+ if(!terminalEntry.isFile()||terminalEntry.isSymbolicLink())
78
+ throw new Error('R159 terminal is not regular');
79
+ await regular(terminal);
80
+ const parsed=strictJson(await readFile(terminal),'current terminal');
81
+ if(parsed.schema!=='deadbyte.r153-marker-reconciliation.v1'||
82
+ parsed.state!=='MARKER_RECONCILED'||parsed.marker_sha256!==match[1]||
83
+ parsed.intent_sha256!==digest(intentBytes)||
84
+ !samePredecessor(parsed.predecessor,activePointer))
85
+ throw new Error('R159 current terminal intent/subject mismatch');
86
+ terminalExists=true;
87
+ }
88
+ candidates.push({markerSha256:match[1],intent,terminal,terminalExists});
89
+ }
90
+ const pending=candidates.filter(c=>!c.terminalExists);
91
+ if(pending.length>1)throw new Error('R159 multiple matching pending reconciliation claims; manual reconciliation required');
92
+ if(pending.length===1)return {kind:'pending',pending:pending[0]};
93
+ if(located){
94
+ const other=candidates.filter(c=>c.markerSha256!==located.markerSha256);
95
+ if(other.length)throw new Error('R159 ambiguous multiple current reconciliation receipts');
96
+ return located;
97
+ }
98
+ const completed=candidates.filter(c=>c.terminalExists);
99
+ if(completed.length>1)throw new Error('R159 ambiguous multiple completed reconciliation receipts');
100
+ if(completed.length===1)return {kind:'completed',pending:completed[0]};
101
+ return {kind:'none'};
102
+ }
@@ -0,0 +1,79 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import {mkdtemp,mkdir,writeFile,readFile,rm} from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
6
+ import {createHash} from 'node:crypto';
7
+ import {selectLegacyMarkerEvidence} from '../src/legacy-marker-evidence-r159.mjs';
8
+ const sha=x=>createHash('sha256').update(x).digest('hex');
9
+ const id=c=>c.repeat(64);
10
+ const old={release_id:'v0.15.45-OLD',version:'0.15.45',manifest_sha256:id('1'),generation_manifest_sha256:id('2')};
11
+ const current={release_id:'v0.15.61-CURRENT',version:'0.15.61',manifest_sha256:id('3'),generation_manifest_sha256:id('4')};
12
+ async function fixture(t){
13
+ const root=await mkdtemp(path.join(os.tmpdir(),'deadbyte-r159-locator-'));
14
+ const evidenceDir=path.join(root,'legacy-migration');await mkdir(evidenceDir);
15
+ t.after(()=>rm(root,{recursive:true,force:true}));
16
+ async function record(marker,predecessor,opts={}){
17
+ const body={schema:'deadbyte.r153-marker-reconciliation-intent.v1',state:'RECONCILIATION_CLAIMED',marker_sha256:marker,predecessor,subject_sha256:id('5')};
18
+ const intent=path.join(evidenceDir,'marker-'+marker+'.intent.json');
19
+ const intentBytes=Buffer.from(JSON.stringify(body)+'\n');
20
+ await writeFile(intent,intentBytes);
21
+ let terminalFile=null;
22
+ if(opts.terminal!==false){
23
+ terminalFile=path.join(evidenceDir,'marker-'+marker+'.terminal.json');
24
+ await writeFile(terminalFile,JSON.stringify({schema:'deadbyte.r153-marker-reconciliation.v1',state:'MARKER_RECONCILED',marker_sha256:marker,predecessor,intent_sha256:sha(intentBytes),subject_sha256:id('6')})+'\n');
25
+ }
26
+ return {intent,terminal:terminalFile};
27
+ }
28
+ async function locator(marker,receipt){
29
+ await writeFile(path.join(evidenceDir,'r153-pending-migration.json'),
30
+ JSON.stringify({schema:'deadbyte.r153-pending-migration.v1',marker_sha256:marker,receipt_path:receipt,receipt_sha256:sha(await readFile(receipt))})+'\n');
31
+ }
32
+ return {root,evidenceDir,record,locator};
33
+ }
34
+ test('R159 stale singleton locator does not hide current release terminal',async t=>{
35
+ const f=await fixture(t),o=await f.record(id('a'),old),n=await f.record(id('b'),current);
36
+ await f.locator(id('a'),o.terminal);
37
+ const v=await selectLegacyMarkerEvidence({evidenceDir:f.evidenceDir,activePointer:current});
38
+ assert.equal(v.kind,'completed');assert.equal(v.pending.markerSha256,id('b'));assert.equal(v.pending.terminal,n.terminal);
39
+ });
40
+ test('R159 current pending intent not masked by historic locator',async t=>{
41
+ const f=await fixture(t),o=await f.record(id('a'),old),n=await f.record(id('b'),current,{terminal:false});
42
+ await f.locator(id('a'),o.terminal);
43
+ const v=await selectLegacyMarkerEvidence({evidenceDir:f.evidenceDir,activePointer:current});
44
+ assert.equal(v.kind,'pending');assert.equal(v.pending.intent,n.intent);
45
+ });
46
+ test('R159 two matching pending intents fail closed',async t=>{
47
+ const f=await fixture(t);await f.record(id('a'),current,{terminal:false});await f.record(id('b'),current,{terminal:false});
48
+ await assert.rejects(selectLegacyMarkerEvidence({evidenceDir:f.evidenceDir,activePointer:current}),/multiple.*pending|ambiguous/i);
49
+ });
50
+ test('R159 current locator accepted after hash and subject',async t=>{
51
+ const f=await fixture(t),c=await f.record(id('b'),current);await f.locator(id('b'),c.terminal);
52
+ const v=await selectLegacyMarkerEvidence({evidenceDir:f.evidenceDir,activePointer:current});
53
+ assert.equal(v.kind,'located');assert.equal(v.receiptPath,c.terminal);assert.match(v.receiptSha256,/^[a-f0-9]{64}$/);
54
+ });
55
+ test('R159 tampered locator fails closed',async t=>{
56
+ const f=await fixture(t),c=await f.record(id('b'),current);await f.locator(id('b'),c.terminal);await writeFile(c.terminal,'{}\n');
57
+ await assert.rejects(selectLegacyMarkerEvidence({evidenceDir:f.evidenceDir,activePointer:current}),/hash|invalid|mismatch/i);
58
+ });
59
+ test('R159 no evidence on clean start',async t=>{
60
+ const f=await fixture(t);const v=await selectLegacyMarkerEvidence({evidenceDir:f.evidenceDir,activePointer:current});assert.equal(v.kind,'none');
61
+ });
62
+ test('R159 forged terminal with wrong intent hash fails closed',async t=>{
63
+ const f=await fixture(t),c=await f.record(id('b'),current);
64
+ const forged=JSON.parse(await readFile(c.terminal,'utf8'));
65
+ forged.intent_sha256=id('0');
66
+ await writeFile(c.terminal,JSON.stringify(forged)+'\n');
67
+ await assert.rejects(selectLegacyMarkerEvidence({evidenceDir:f.evidenceDir,activePointer:current}),/intent|mismatch/i);
68
+ });
69
+ test('R159 two unlocated completed current receipts remain ambiguous',async t=>{
70
+ const f=await fixture(t);await f.record(id('a'),current);await f.record(id('b'),current);
71
+ await assert.rejects(selectLegacyMarkerEvidence({evidenceDir:f.evidenceDir,activePointer:current}),/multiple|ambiguous/i);
72
+ });
73
+ test('R159 remote foreground code routes historical locators through subject selection',async()=>{
74
+ const cli=await readFile(new URL('../src/deadbyte-cli.mjs',import.meta.url),'utf8');
75
+ assert.match(cli,/selectLegacyMarkerEvidence\(\{evidenceDir,activePointer\}\)/);
76
+ assert.match(cli,/R159 active release changed during marker recovery/);
77
+ assert.match(cli,/marker-'\+reconciled\.marker_sha256\+'\.locator\.json'/);
78
+ assert.doesNotMatch(cli,/publishExclusiveJson\(locatorPath,locator\)/);
79
+ });
@@ -0,0 +1,26 @@
1
+ {
2
+ "schema": "deadbyte.r159-completed-history-patch.v1",
3
+ "time": "2026-10-25T04:57:11.495Z",
4
+ "candidate": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.62-r159-marker-reconcile",
5
+ "changes": [
6
+ {
7
+ "path": "src/legacy-marker-evidence-r159.mjs",
8
+ "before_sha256": "f4f333350db85b58ae00fccb78ebee70b4ad38f3682ddcb5c9c2601d0f67b140",
9
+ "after_sha256": "c8af54e4c5e52b812aebfc3da2525e3e6f8646785e598d4ad67878556c7c6eb8",
10
+ "backup": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.62-r159-marker-reconcile\\docs\\R159-COMPLETED-HISTORY-BACKUP\\legacy-marker-evidence-r159.mjs.before"
11
+ },
12
+ {
13
+ "path": "src/deadbyte-cli.mjs",
14
+ "before_sha256": "4830eff142e91a99672fd3d4da848a52b4594a07918390ed8a165cf6295c8cb4",
15
+ "after_sha256": "942e38a2acef5ee7114d7d36f86515f7c0d3a468d4006c9dbb771de194b8c592",
16
+ "backup": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.62-r159-marker-reconcile\\docs\\R159-COMPLETED-HISTORY-BACKUP\\deadbyte-cli.mjs.before"
17
+ },
18
+ {
19
+ "path": "test/r159-legacy-marker-evidence.test.mjs",
20
+ "before_sha256": "aeeefc14e8e007df4182a14e6936bfdf14a764578588fe82c5679b051826d7b0",
21
+ "after_sha256": "ff0fc541ef9b9b1565be647d2861c29afc8827504122c1df88a94d67fd2c20bd",
22
+ "backup": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.62-r159-marker-reconcile\\docs\\R159-COMPLETED-HISTORY-BACKUP\\r159-legacy-marker-evidence.test.mjs.before"
23
+ }
24
+ ],
25
+ "scope": "isolated source and test only; no production state touched"
26
+ }
@@ -0,0 +1,46 @@
1
+ # R159 — historical marker locator binding (candidate only)
2
+
3
+ Production: 0.15.61, verified ONLINE before changes, Coding DISARMED.
4
+ Parent: R158 isolated candidate.
5
+ Candidate: D:\Projects\deadbyte-mcp\development\deadbyte-mcp-0.15.62-r159-marker-reconcile
6
+ Safety: NO production mutation, UAC, grants, ACL changes, npm publish or activation.
7
+
8
+ ## Root cause verified from installed production evidence
9
+
10
+ The original src/deadbyte-cli.mjs recoverRemoteSession() read evidence/legacy-migration/r153-pending-migration.json whenever the foreground marker was absent. It validated receipt bytes/hash but returned the receipt without comparing terminal.predecessor against the ACTIVE release.
11
+
12
+ Observed on Windows:
13
+ - historical marker 4e9706... intent and terminal bind predecessor v0.15.45-34aa8d1241cfb8bf
14
+ - singleton r153-pending-migration.json still points to that historical terminal
15
+ - newer marker 9cbee7... intent and terminal bind predecessor v0.15.61-055d1ff0aa99e60b
16
+ - current active release is v0.15.61-055d1ff0aa99e60b
17
+ - two historical intents and two terminals exist; no evidence was deleted or rewritten
18
+
19
+ Blindly trusting the singleton could hand an OLD marker receipt into the upgrade migration path even though the installed active release has changed. Counting all intent files as unresolved also creates a false ambiguity.
20
+
21
+ ## Changes in R159 source only
22
+
23
+ - src/legacy-marker-evidence-r159.mjs: new bounded read-only selector. Validates exact locator filename, SHA-256 and terminal marker; requires predecessor release_id/version/manifest/generation-manifest binding. Scans historical and current intents; prioritizes a truly pending CURRENT predecessor; denies multiple current pending or multiple unlocated current completed claims. Rejects symlinks, invalid JSON, mismatched terminal intent hashes and malformed identities. Does not execute commands or mutate authority.
24
+ - src/deadbyte-cli.mjs: consume the selector before startup synchronization, ignore completed current terminal as historical when runtime already ONLINE, disallow pending reconciliation while runtime is not OFFLINE, reread active release before reuse/recovery to catch pointer drift, and publish marker-specific locators rather than writing over the legacy singleton. The historical r153-pending-migration.json and all terminal/intent receipts are preserved.
25
+ - test/r159-legacy-marker-evidence.test.mjs: 9 tests for historical locator vs current release, pending precedence, conflicting claims, exact located receipts, tamper rejection, clean empty start, forged terminal, duplicate completed and actual CLI wiring.
26
+
27
+ ## Evidence level and gating
28
+
29
+ IMPORTANT: The remote Windows test-runner action was blocked by the tool security check. The tool did not execute Node. Therefore R159 is **SOURCE_EDITED / TESTS_WRITTEN / NOT YET VERIFIED**. No RED/GREEN or integrated runtime PASS claim.
30
+
31
+ The focused test that must run once the approved local executor is available:
32
+
33
+ cd D:\Projects\deadbyte-mcp\development\deadbyte-mcp-0.15.62-r159-marker-reconcile
34
+ node --check src\legacy-marker-evidence-r159.mjs
35
+ node --check src\deadbyte-cli.mjs
36
+ node --test test\r159-legacy-marker-evidence.test.mjs test\r153-clean-activation-recovery.test.mjs
37
+
38
+ Then broader affected tests, restart/reconcile in disposable stateRoot, and exact production evidence read-only verification. Stop on unexpected behavior. Never test by destroying production markers.
39
+
40
+ ## Remaining dependency gates
41
+
42
+ R89 production arm still fails UNTRUSTED_WRITE_ACE because production generation lacks AuthorityEpochRoot. R158 implements verified protected root bootstrap in candidate, not active generation. Owner-approved exact protected installation + signed activation/rollback remain required.
43
+
44
+ R155 default LiveLogs focused tests previously passed, but full protected Windows release regression and clean tarball evidence are still outstanding. R70 owner autonomous enrollment remains unverified.
45
+
46
+ Do not label 0.15.62 ready or publish from this checkpoint. Candidate package.json still identifies the old version.
@@ -0,0 +1,32 @@
1
+ # R160 engineering handoff
2
+
3
+ ## Identity
4
+
5
+ - Source predecessor: `D:\Projects\deadbyte-mcp\development\deadbyte-mcp-0.15.62-r159-marker-reconcile` (unsealed; its inherited manifest was stale and rejected).
6
+ - Development successor: `D:\Projects\deadbyte-mcp\development\deadbyte-mcp-0.15.62-r160-marker-proof`.
7
+ - Observed runtime predecessor: `v0.15.61-055d1ff0aa99e60b`, manifest `055d1ff0aa99e60bbf9e9f136b02ebd4fffb8391712560f7607cff30af94dcdf`, generation `f940e794daac2dda097a66301c4b85c4b29a2df7c669e549503c05a2a55ff6c4`.
8
+ - Production was observed ONLINE and all five planes DISARMED. R160 has not been published or activated.
9
+
10
+ ## Completed behavior work
11
+
12
+ - Located legacy receipts now pass the existing R153 proof-binding verifier after locator/terminal hash checks; policy drift and a changed active pointer fail closed.
13
+ - Remote startup verifies exact manifest entries for every recovery/startup decision module before evidence recovery or foreground claim.
14
+ - Stable CMD launcher pins native Windows PowerShell rather than resolving an ambient `powershell.exe`.
15
+ - Restored the release-source package lock from the exact protected 0.15.61 source after a genuine `ENOENT` release-identity RED.
16
+ - Reference capability decisions for all twelve observed roots are in `docs/R160-REFERENCE-CAPABILITY-MATRIX.json`; no donor source bytes were copied.
17
+
18
+ ## Observed verification
19
+
20
+ - R160 receipt/package/launcher focused tests: GREEN.
21
+ - R155 LIVELOG and R156/R157 supervisor focused tests: GREEN.
22
+ - Protected fixture: `C:\Program Files\DEADBYTE-R160-Protected-0.15.62-Test`; owner Administrators, inherited Program Files ACL, Users read/execute only.
23
+ - Installed manifest verification: 2,464 files; protected tailored manifest SHA-256 `df050f750818cc95c4210137314a395df63ba66864bb51a2aef242c6de2ebaf0`.
24
+ - R158 protected exact-source preflight with a distinct writable release view: 4/4 PASS.
25
+ - Isolated engineering-loop proof: planning, mutation, repair, regression, restart reconciliation and no duplicate apply passed; no public tool or authority-scope change.
26
+
27
+ ## Pending release gates
28
+
29
+ - Regenerate the final manifest after the last source/metadata change.
30
+ - Install the exact final bytes into a fresh protected path and rerun full regression, Windows gate, doctor, package boundary, isolated install, receipt verification and performance checks.
31
+ - Exercise isolated authority arm/revoke and rollback/restore without touching production.
32
+ - Publication and production activation remain separate approval boundaries.
@@ -0,0 +1,165 @@
1
+ {
2
+ "schema": "deadbyte.r160-reference-capability-matrix.v1",
3
+ "observed_at_utc": "2026-10-25T06:02:31.1966596Z",
4
+ "method": "read-only source, test, package metadata, and license inspection; no donor executable was run and no donor source bytes were copied",
5
+ "public_tool_delta": 0,
6
+ "authority_scope_delta": 0,
7
+ "repositories": [
8
+ {
9
+ "reference": "better-remote-commander",
10
+ "evidence_paths": ["packages/agent/src/core/terminal-manager.ts", "packages/relay/src/device-hub.ts", "packages/agent/package.json"],
11
+ "behavior": "line-bounded process output with eviction counters and pagination; stale-socket replacement, call correlation, pong watchdog, bounded call timeout",
12
+ "deadbyte_state": "parity_or_stronger",
13
+ "deadbyte_equivalent": ["src/process-runtime.mjs", "src/process-output-contracts.mjs", "bridge/src/remote-call-claims-r60.mjs", "bridge/src/reconnect-delay-r60.mjs"],
14
+ "security": "relay must never widen local policy; PID alone remains non-authoritative",
15
+ "performance": "bounded output and watchdogs prevent memory growth and half-open stalls",
16
+ "license": "package metadata declares MIT; desktop-commander-derived files carry a separate notice",
17
+ "decision": "ADAPT",
18
+ "integration": "retain DEADBYTE signed claims and native ownership; reuse only adversarial eviction/watchdog/correlation test ideas",
19
+ "acceptance": "bounded retained bytes, monotonic cursor behavior, stale channel replacement, and no mutation replay"
20
+ },
21
+ {
22
+ "reference": "cua",
23
+ "evidence_paths": ["rfcs/3007-cua-driver-lifecycle-sessions.md", "rfcs/3682-typed-native-window-sdk.md", "libs/python/agent/tests/test_uitars_coordinate_security.py"],
24
+ "behavior": "lifecycle identity separated from authorization; host-held resume identity; typed exact-window snapshot/token action followed by fresh verification",
25
+ "deadbyte_state": "parity",
26
+ "deadbyte_equivalent": ["src/desktop-runtime-r40.mjs", "src/desktop-observer-r40.mjs", "src/foreground-process-identity.mjs"],
27
+ "security": "public session names are not bearer credentials; background action cannot silently escalate to foreground",
28
+ "performance": "fresh observation is paid only around desktop effects",
29
+ "license": "mixed monorepo licenses; pattern-only use",
30
+ "decision": "ADAPT",
31
+ "integration": "add conformance and stale-frame tests only; keep DEADBYTE desktop authority and receipt model",
32
+ "acceptance": "stale frame/token refusal, exact window identity, dispatched-not-verified distinction, cleanup exactly once"
33
+ },
34
+ {
35
+ "reference": "desktop-commander v0.2.52",
36
+ "evidence_paths": ["dist/terminal-manager.js", "dist/remote-device/remote-channel.js", "package.json"],
37
+ "behavior": "interactive process buffering, pagination, timeout, remote reconnect and command lifecycle",
38
+ "deadbyte_state": "parity_or_stronger",
39
+ "deadbyte_equivalent": ["src/process-runtime.mjs", "src/remote-live-log.mjs", "bridge/src/remote-dispatch-r60.mjs"],
40
+ "security": "donor process identity is weaker than DEADBYTE PID plus creation identity and signed receipts",
41
+ "performance": "use as a same-workload latency and retained-output baseline",
42
+ "license": "package metadata declares MIT",
43
+ "decision": "KEEP_OURS",
44
+ "integration": "no donor runtime import",
45
+ "acceptance": "DEADBYTE output remains bounded and control calls do not wait behind process output"
46
+ },
47
+ {
48
+ "reference": "desktop-commander v0.3.0",
49
+ "evidence_paths": ["dist/utils/atomic-write.js", "dist/utils/process-tree.js", "dist/remote-device/diagnostics/redact.js", "dist/remote-device/transport-telemetry.js", "vendor/telemetry-contract/transport.test.js"],
50
+ "behavior": "atomic configuration writes, process-tree cleanup, bounded diagnostic redaction and transport health telemetry",
51
+ "deadbyte_state": "parity_or_stronger",
52
+ "deadbyte_equivalent": ["src/atomic-mutation-r74.mjs", "src/process-runtime.mjs", "src/remote-log-decode-r60.mjs", "src/remote-result-journal.mjs"],
53
+ "security": "presentation telemetry cannot replace durable signed audit evidence",
54
+ "performance": "batch only non-authoritative presentation state",
55
+ "license": "package metadata declares MIT; vendor package inspected separately",
56
+ "decision": "ADAPT",
57
+ "integration": "retain DEADBYTE atomic receipts; add redaction and parent-child cleanup differential tests",
58
+ "acceptance": "no secret leakage, orphan, unbounded diagnostic growth, or audit weakening"
59
+ },
60
+ {
61
+ "reference": "desktop-commander v0.3.1",
62
+ "evidence_paths": ["dist/utils/atomic-write.js", "dist/utils/process-tree.js", "dist/remote-device/remote-channel.js", "dist/remote-device/realtime-health-telemetry.js"],
63
+ "behavior": "later transport/text-read revisions with health reporting and the same bounded process primitives",
64
+ "deadbyte_state": "different",
65
+ "deadbyte_equivalent": ["src/machine-fs-runtime.mjs", "src/remote-live-log.mjs", "bridge/src/bridge-health-r59.mjs"],
66
+ "security": "keep local authority final and diagnostics opt-in/local-first",
67
+ "performance": "compare event ordering, reconnect latency and read throughput on identical inputs",
68
+ "license": "package metadata declares MIT",
69
+ "decision": "DEFER",
70
+ "integration": "no R160 feature import; retain as benchmark/reference evidence",
71
+ "acceptance": "a future adoption requires a focused DEADBYTE RED and same-machine benchmark"
72
+ },
73
+ {
74
+ "reference": "desktop-commander-0.3.1-alpha.2",
75
+ "evidence_paths": ["static/dist/terminal-manager.js", "static/dist/remote-device/remote-channel.js", "static/dist/remote-device/diagnostics/redact.js", "static/package.json"],
76
+ "behavior": "alpha transport diagnostics, event grouping and bounded process presentation",
77
+ "deadbyte_state": "parity_or_stronger",
78
+ "deadbyte_equivalent": ["src/remote-live-log.mjs", "src/operation-history.mjs", "src/process-runtime.mjs"],
79
+ "security": "signed audit remains authority; alpha diagnostics are presentation only",
80
+ "performance": "grouping is acceptable only when failures and state changes remain visible",
81
+ "license": "static package metadata declares MIT",
82
+ "decision": "KEEP_OURS",
83
+ "integration": "R155 already preserves START and terminal lines with bounded presentation",
84
+ "acceptance": "no duplicate terminal result, hidden failure, raw payload, or secret"
85
+ },
86
+ {
87
+ "reference": "harness2-main",
88
+ "evidence_paths": ["harness2/core/ledger.py", "harness2/core/recursion.py", "LICENSE", "third_party/licenses/job-bench-eval.LICENSE"],
89
+ "behavior": "run ledger, recursion budgets, benchmark task/result accounting and resumable evaluation",
90
+ "deadbyte_state": "different",
91
+ "deadbyte_equivalent": ["src/autonomous-loop-state.mjs", "src/autonomous-progress.mjs", "src/autonomous-supervisor-host.mjs"],
92
+ "security": "evaluation metadata cannot grant authority or select new executable/root",
93
+ "performance": "use ledger metrics for wasted retry and time-to-repair measurement",
94
+ "license": "repository and third-party licenses present; pattern-only use",
95
+ "decision": "ADAPT",
96
+ "integration": "map bounded run ledger concepts onto existing signed autonomous journal",
97
+ "acceptance": "restart-safe goal state, bounded retries, repair fingerprint and evidence-backed terminal decision"
98
+ },
99
+ {
100
+ "reference": "open-remote-mcp",
101
+ "evidence_paths": ["apps/server/src/lib/security.ts", "apps/server/src/lib/security.test.ts", "apps/agent/src/index.ts"],
102
+ "behavior": "server policy and pairing may narrow a device but the device remains final enforcement authority",
103
+ "deadbyte_state": "stronger",
104
+ "deadbyte_equivalent": ["src/capability-resolver.mjs", "src/remote-authority.mjs", "src/authority-continuity-r65.mjs"],
105
+ "security": "remote policy may never mint local grants",
106
+ "performance": "no second relay stack is justified",
107
+ "license": "no root license identified in the inspected snapshot; no source reuse",
108
+ "decision": "KEEP_OURS",
109
+ "integration": "retain as negative authority-narrowing test inspiration",
110
+ "acceptance": "relay-selected route cannot widen local capability or authority"
111
+ },
112
+ {
113
+ "reference": "rea-main",
114
+ "evidence_paths": ["docs/reconstruction-obligation-ledgers.md", "scripts/generate-completion-ledger.mjs", "scripts/verify/recorded-crash/trace-policy.mjs", "LICENSE"],
115
+ "behavior": "completion-obligation ledgers and recorded-crash verification for reverse-engineering workflows",
116
+ "deadbyte_state": "out_of_scope",
117
+ "deadbyte_equivalent": ["src/autonomous-loop-state.mjs", "src/operation-history.mjs"],
118
+ "security": "debugger/tracer authority would expand the current scope",
119
+ "performance": "no comparable production workload in R160",
120
+ "license": "root license present with additional third-party licenses",
121
+ "decision": "DEFER",
122
+ "integration": "reuse only the concept of explicit unresolved obligations in a future bounded evaluation",
123
+ "acceptance": "requires separate owner-approved RE capability scope"
124
+ },
125
+ {
126
+ "reference": "remcp",
127
+ "evidence_paths": ["packages/client/src/agent.mjs", "packages/runtime/src/policy.mjs", "packages/runtime/test/extended-security.test.mjs", "packages/client/LICENSE", "packages/runtime/LICENSE"],
128
+ "behavior": "client/runtime split, reconnect cancellation, runtime coherence, low-dependency policy and catalog tests",
129
+ "deadbyte_state": "parity_or_stronger",
130
+ "deadbyte_equivalent": ["src/runtime-coherence.mjs", "src/remote-device-r44.mjs", "src/capability-ledger-r36.mjs"],
131
+ "security": "unrestricted mode and implicit upload are rejected",
132
+ "performance": "retain compact catalog and bounded reconnect timers",
133
+ "license": "client/runtime licenses and MIT package metadata present",
134
+ "decision": "ADAPT",
135
+ "integration": "reuse catalog/coherence golden-test methodology without a runtime dependency",
136
+ "acceptance": "43 compact tools, version coherence, cancellation and reconnect cleanup remain stable"
137
+ },
138
+ {
139
+ "reference": "secure-host-mcp",
140
+ "evidence_paths": ["src/workspace.ts", "src/executor.ts", "src/auth.ts", "src/audit.ts", "test/workspace.test.ts"],
141
+ "behavior": "realpath workspace confinement, bounded job output/TTL, authentication and bounded redacted audit files",
142
+ "deadbyte_state": "stronger_on_authority",
143
+ "deadbyte_equivalent": ["src/coding-runtime.mjs", "src/process-runtime.mjs", "src/audit-verify.mjs", "src/privileged-install-trust-r89.mjs"],
144
+ "security": "generic shell and taskkill-by-PID are weaker and rejected",
145
+ "performance": "bounded audit/output patterns already exist",
146
+ "license": "package metadata declares MIT",
147
+ "decision": "ADAPT",
148
+ "integration": "add workspace escape and retention negatives only",
149
+ "acceptance": "junction/symlink escape, oversized output and unauthenticated privileged execution fail closed"
150
+ },
151
+ {
152
+ "reference": "winremote-mcp",
153
+ "evidence_paths": ["src/winremote/security.py", "src/winremote/desktop.py", "src/winremote/auth.py", "tests/test_security_hardening.py"],
154
+ "behavior": "SSRF/private-network denial, remote auth guards and Windows desktop/window abstractions",
155
+ "deadbyte_state": "mixed",
156
+ "deadbyte_equivalent": ["src/desktop-runtime-r40.mjs", "src/remote-authority.mjs", "src/http-reader-r48.mjs"],
157
+ "security": "generic shell, fuzzy window action and OCR dependence are rejected",
158
+ "performance": "native exact-window paths remain preferred",
159
+ "license": "no root license identified in the inspected snapshot; no source reuse",
160
+ "decision": "ADAPT",
161
+ "integration": "reuse SSRF/auth negative test ideas and keep typed exact-window desktop flow",
162
+ "acceptance": "private/loopback URL fetch denial and stale/fuzzy target refusal"
163
+ }
164
+ ]
165
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deadbyte-mcp",
3
- "version": "0.15.61",
3
+ "version": "0.15.63",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Authenticated MCP agentic runtime with signed skills, persistent model backends, identity-bound remote devices, durable job supervision, immutable release slots, and separately revocable machine authority.",
@@ -42,7 +42,7 @@
42
42
  "contained:run": "node src/contained-cli.mjs workspaces/demo input.txt",
43
43
  "contained:smoke": "node src/contained-smoke.mjs",
44
44
  "mcp:contained:smoke": "node src/mcp-contained-smoke-client.mjs",
45
- "gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r72.ps1",
45
+ "gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r160.ps1 -Stage all",
46
46
  "authority:smoke": "node src/authority-smoke.mjs",
47
47
  "mcp:remote:smoke": "node src/remote-mcp-smoke-client.mjs",
48
48
  "mcp:host:smoke": "node src/mcp-host-smoke-client.mjs",
@@ -0,0 +1,57 @@
1
+ #requires -Version 5.1
2
+ [CmdletBinding()]
3
+ param([ValidateSet('preflight','focused','full','manifest','doctor','all')][string]$Stage='preflight')
4
+ Set-StrictMode -Version Latest
5
+ $ErrorActionPreference='Stop'
6
+ $repo=Split-Path -Parent $PSScriptRoot
7
+ $state=Join-Path $env:USERPROFILE '.deadbyte-mcp'
8
+ $parentId='v0.15.61-055d1ff0aa99e60b'
9
+ $parentSha='055d1ff0aa99e60bbf9e9f136b02ebd4fffb8391712560f7607cff30af94dcdf'
10
+ $parentGen='f940e794daac2dda097a66301c4b85c4b29a2df7c669e549503c05a2a55ff6c4'
11
+ $nativeNode='C:\Program Files\nodejs\node.exe'
12
+ $node=if(Test-Path -LiteralPath $nativeNode -PathType Leaf){$nativeNode}else{(Get-Command node -ErrorAction Stop).Source}
13
+ function Sha([string]$file){
14
+ $sha=[Security.Cryptography.SHA256]::Create()
15
+ try{$stream=[IO.File]::OpenRead($file);try{return ([BitConverter]::ToString($sha.ComputeHash($stream))).Replace('-','').ToLowerInvariant()}finally{$stream.Dispose()}}finally{$sha.Dispose()}
16
+ }
17
+ function Run-Node([string]$label,[string[]]$nodeArgs){
18
+ if($null -eq $nodeArgs -or $nodeArgs.Count -lt 1){throw "R160_${label}_NO_NODE_ARGUMENTS"}
19
+ Write-Output "R160_STAGE_START=$label"
20
+ Write-Output "R160_STAGE_ARGS=$($nodeArgs.Count)"
21
+ $global:LASTEXITCODE=0
22
+ & $node @nodeArgs
23
+ $exit=$global:LASTEXITCODE
24
+ if($exit -ne 0){throw "R160_${label}_FAILED exit=$exit"}
25
+ Write-Output "R160_STAGE_PASS=$label"
26
+ }
27
+ Push-Location $repo
28
+ try{
29
+ $pkg=Get-Content -LiteralPath 'package.json' -Raw | ConvertFrom-Json
30
+ $release=Get-Content -LiteralPath 'RELEASE.json' -Raw | ConvertFrom-Json
31
+ if($pkg.version -ne '0.15.62' -or $release.version -ne '0.15.62' -or $release.train -ne 'R160'){throw 'R160_CANDIDATE_VERSION_DRIFT'}
32
+ if($release.runtime_predecessor.release_id -ne $parentId -or $release.runtime_predecessor.manifest_sha256 -ne $parentSha -or $release.runtime_predecessor.generation_manifest_sha256 -ne $parentGen){throw 'R160_RUNTIME_PREDECESSOR_IDENTITY_DRIFT'}
33
+ $active=Get-Content -LiteralPath (Join-Path $state 'active-release.json') -Raw | ConvertFrom-Json
34
+ if($active.version -ne '0.15.61' -or $active.release_id -ne $parentId -or $active.manifest_sha256 -ne $parentSha -or $active.generation_manifest_sha256 -ne $parentGen){throw 'R160_ACTIVE_RUNTIME_DRIFT'}
35
+ if((Sha (Join-Path $active.release_root 'MANIFEST.SHA256')) -ne $parentSha){throw 'R160_ACTIVE_MANIFEST_MISMATCH'}
36
+ Write-Output 'R160_PREDECESSOR_PREFLIGHT=PASS'
37
+ if($Stage -eq 'preflight'){return}
38
+ if($Stage -in @('focused','all')){
39
+ Run-Node -label 'focused' -nodeArgs @('--test','--test-concurrency=1','test/r89-privileged-install-boundary.test.mjs','test/r92-acl-ace-applicability.test.mjs','test/r153-clean-activation-recovery.test.mjs','test/r155-commander-live-log.test.mjs','test/r155-default-live-log.test.mjs','test/r156-supervisor-pacing.test.mjs','test/r157-supervisor-singleflight.test.mjs','test/r158-epoch-bootstrap.test.mjs','test/r159-legacy-marker-evidence.test.mjs','test/r160-marker-proof.test.mjs','test/r160-package-decision-manifest.test.mjs','test/r160-stable-launcher.test.mjs','test/r160-release-contract.test.mjs','test/r59-tool-surface-compat.test.mjs')
40
+ if($Stage -eq 'focused'){return}
41
+ }
42
+ if($Stage -in @('full','all')){
43
+ Run-Node -label 'full' -nodeArgs @('--test','--test-concurrency=4','test/*.test.mjs')
44
+ if($Stage -eq 'full'){return}
45
+ }
46
+ if($Stage -in @('manifest','all')){
47
+ Run-Node -label 'manifest' -nodeArgs @('scripts/release-manifest.mjs','verify')
48
+ if($Stage -eq 'manifest'){return}
49
+ }
50
+ if($Stage -in @('doctor','all')){
51
+ $previous=$env:DEADBYTE_STATE_ROOT
52
+ $isolated=Join-Path $env:TEMP ('deadbyte-r160-doctor-'+[guid]::NewGuid().ToString('N'))
53
+ try{[IO.Directory]::CreateDirectory($isolated)|Out-Null;$env:DEADBYTE_STATE_ROOT=$isolated;Run-Node -label 'isolated_doctor' -nodeArgs @('src/deadbyte-cli.mjs','doctor')}
54
+ finally{$env:DEADBYTE_STATE_ROOT=$previous;Remove-Item -LiteralPath $isolated -Recurse -Force -ErrorAction SilentlyContinue}
55
+ }
56
+ Write-Output 'R160_WINDOWS_CANDIDATE_GATE=PASS_PREPUBLICATION'
57
+ }finally{Pop-Location}
@@ -7,6 +7,8 @@ import {assertR67NpmPublishReady} from './npm-release-readiness-r67.mjs';
7
7
  import {assertR71NpmPublishReady} from './npm-release-readiness-r71.mjs';
8
8
  import {assertR72NpmPublishReady} from './npm-release-readiness-r72.mjs';
9
9
  import {assertR74NpmPublishReady} from './npm-release-readiness-r74.mjs';
10
+ import {assertR163NpmPublishReady} from './npm-release-readiness-r163.mjs';
11
+ import {assertR165NpmPublishReady} from './npm-release-readiness-r165.mjs';
10
12
  import { existsSync } from 'node:fs';
11
13
  import { resolveStateRoot } from '../src/state-root.mjs';
12
14
  import path from 'node:path';
@@ -95,6 +97,14 @@ async function main() {
95
97
  if (!isVerifyOnly && version==='0.15.45') assertR71NpmPublishReady(release);
96
98
  if (!isVerifyOnly && version==='0.15.46') await assertR72NpmPublishReady(release,{root});
97
99
  if (!isVerifyOnly && version==='0.15.47') await assertR74NpmPublishReady(release,{root});
100
+ if (!isVerifyOnly && version==='0.15.62') {
101
+ if (!publishOnly) throw new Error('PUBLISH_BLOCKED R163 0.15.62 requires --publish-only; production activation is a separate authority boundary');
102
+ await assertR163NpmPublishReady(release,{root});
103
+ }
104
+ if (!isVerifyOnly && version==='0.15.63') {
105
+ if (!publishOnly) throw new Error('PUBLISH_BLOCKED R165 0.15.63 requires --publish-only; production activation is a separate authority boundary');
106
+ await assertR165NpmPublishReady(release,{root});
107
+ }
98
108
  if (release.parent?.release_id !== provenance.parent_release_id ||
99
109
  release.parent?.manifest_sha256 !== provenance.parent_manifest_sha256 ||
100
110
  release.parent?.generation_manifest_sha256 !== provenance.parent_generation_manifest_sha256) {