deadbyte-mcp 0.15.48 → 0.15.49
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.
- package/MANIFEST.SHA256 +48 -22
- package/PROVENANCE.json +11 -22
- package/README.txt +18 -18
- package/RELEASE.json +368 -378
- package/SBOM.cdx.json +2 -2
- package/TEST-MATRIX.json +2 -2
- package/bench/r121-epoch-readhead.mjs +54 -0
- package/bench/r124-epoch-predecessor.mjs +53 -0
- package/controller/deadbyte-process-policy.json +4 -4
- package/docs/HARNESS2-ADAPTATION-20261020.md +24 -0
- package/docs/R128-RELEASE-CANDIDATE.md +26 -0
- package/package.json +1 -1
- package/scripts/npm-release-r48.mjs +0 -4
- package/scripts/verify-authority-epoch-history.mjs +38 -0
- package/src/activation-continuity-engine-r65.mjs +9 -15
- package/src/agent-eval-r42.mjs +30 -0
- package/src/authority-continuity-r65.mjs +182 -13
- package/src/autonomous-local-supervisor.mjs +77 -47
- package/src/deadbyte-cli.mjs +18 -28
- package/src/remote-live-log.mjs +15 -8
- package/src/remote-log-decode-r60.mjs +65 -0
- package/src/remote-session-guardian.mjs +4 -5
- package/src/version.mjs +1 -1
- package/test/autonomous-local-supervisor.test.mjs +1 -1
- package/test/harness2-eval-context-isolation.test.mjs +90 -0
- package/test/r108-remote-powershell-path.test.mjs +59 -0
- package/test/r110-supervisor-powershell-path.test.mjs +28 -0
- package/test/r111-supervisor-marker-cas.test.mjs +116 -0
- package/test/r112-supervisor-claim-cas.test.mjs +63 -0
- package/test/r113-supervisor-cleanup-terminality.test.mjs +100 -0
- package/test/r114-supervisor-absence-proof.test.mjs +45 -0
- package/test/r115-posix-continuity-entrypoint.test.mjs +17 -0
- package/test/r116-authority-crash-matrix.test.mjs +83 -0
- package/test/r117-concurrent-orphan-recovery.test.mjs +54 -0
- package/test/r118-cross-process-orphan-recovery.test.mjs +99 -0
- package/test/r119-recovery-crash-after-commit.test.mjs +91 -0
- package/test/r120-authority-history-audit.test.mjs +103 -0
- package/test/r121-signed-transition-invariant.test.mjs +132 -0
- package/test/r122-epoch-bounded-read.test.mjs +58 -0
- package/test/r123-recovery-bounded-read.test.mjs +64 -0
- package/test/r124-live-log-integrity.test.mjs +66 -0
- package/test/r124-live-log-tail-boundaries.test.mjs +57 -0
- package/test/r124-signed-predecessor-shape.test.mjs +66 -0
- package/test/r125-restore-binding-types.test.mjs +63 -0
- package/test/r126-restore-policy-envelope.test.mjs +89 -0
- package/test/r127-restore-append-policy-boundary.test.mjs +25 -0
- package/test/r59-tool-surface-compat.test.mjs +1 -1
- package/test/r65-authority-epoch-store.test.mjs +9 -6
- package/test/r74-prepublish-contract.test.mjs +3 -1
- package/scripts/npm-release-readiness-r108.mjs +0 -134
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
|
|
6
|
-
const defaultRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
7
|
-
const sha256 = value => createHash('sha256').update(value).digest('hex');
|
|
8
|
-
const evidenceName = 'r108-protected-publication-evidence.json';
|
|
9
|
-
const norm = p => path.resolve(p).replace(/\\/g, '/').toLowerCase();
|
|
10
|
-
const assert = (ok, message) => { if (!ok) throw new Error('R108_PUBLICATION_GATE: ' + message); };
|
|
11
|
-
const json = async file => JSON.parse(await readFile(file, 'utf8'));
|
|
12
|
-
|
|
13
|
-
function manifestEntries(input) {
|
|
14
|
-
const entries = new Map();
|
|
15
|
-
for (const line of input.split(/\r?\n/)) {
|
|
16
|
-
if (!line.trim()) continue;
|
|
17
|
-
const match = /^([a-f0-9]{64})\s+\*?(.+)$/i.exec(line);
|
|
18
|
-
assert(match !== null, 'unrecognized manifest line format');
|
|
19
|
-
const rel = match[2].replace(/\\/g, '/');
|
|
20
|
-
assert(!entries.has(rel), 'duplicate manifest entry ' + rel);
|
|
21
|
-
entries.set(rel, match[1].toLowerCase());
|
|
22
|
-
}
|
|
23
|
-
return entries;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function testCounts(output) {
|
|
27
|
-
const values = {};
|
|
28
|
-
for (const line of output.split(/\r?\n/)) {
|
|
29
|
-
const match = /^\s*(?:ℹ|#)\s*(tests|pass|fail|skipped)\s+(\d+)\s*$/.exec(line);
|
|
30
|
-
if (match) values[match[1]] = Number(match[2]);
|
|
31
|
-
}
|
|
32
|
-
assert(['tests','pass','fail','skipped'].every(k => Number.isSafeInteger(values[k])), 'missing complete Node test-runner footer');
|
|
33
|
-
assert(values.tests === values.pass + values.fail + values.skipped, 'inconsistent test totals');
|
|
34
|
-
assert(values.fail === 0, 'fresh full regression reported failures');
|
|
35
|
-
assert(values.pass >= 1621, 'full regression below R107 established pass baseline');
|
|
36
|
-
assert(values.skipped <= 48, 'new unexplained skips relative to R107');
|
|
37
|
-
return values;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function slotParity(root, protectedRoot, expectedRootSha, expectedSlotSha) {
|
|
41
|
-
assert(path.isAbsolute(protectedRoot), 'protected slot must be absolute');
|
|
42
|
-
assert(norm(root) !== norm(protectedRoot), 'protected test slot must differ from source');
|
|
43
|
-
if (process.platform === 'win32') {
|
|
44
|
-
assert(norm(protectedRoot).startsWith('c:/program files/'), 'protected slot must be under Program Files');
|
|
45
|
-
}
|
|
46
|
-
const sourceBytes = await readFile(path.join(root,'MANIFEST.SHA256'));
|
|
47
|
-
const slotBytes = await readFile(path.join(protectedRoot,'MANIFEST.SHA256'));
|
|
48
|
-
assert(sha256(sourceBytes) === expectedRootSha, 'R108 source manifest hash changed after test');
|
|
49
|
-
assert(sha256(slotBytes) === expectedSlotSha, 'protected test manifest hash changed after test');
|
|
50
|
-
const source = manifestEntries(sourceBytes.toString('utf8'));
|
|
51
|
-
const slot = manifestEntries(slotBytes.toString('utf8'));
|
|
52
|
-
assert(source.size === slot.size, 'source/protected manifest surface differs');
|
|
53
|
-
const allowed = 'controller/deadbyte-process-policy.json';
|
|
54
|
-
for (const [p,h] of source) {
|
|
55
|
-
assert(slot.has(p), 'protected fixture missing source entry ' + p);
|
|
56
|
-
if (p !== allowed) assert(slot.get(p) === h, 'protected fixture changes tested source bytes at ' + p);
|
|
57
|
-
}
|
|
58
|
-
assert(source.has(allowed) && slot.has(allowed), 'required policy fixture missing from manifest');
|
|
59
|
-
for (const [label,dir] of [['source',root],['protected',protectedRoot]]) {
|
|
60
|
-
const policy = await json(path.join(dir, 'controller', 'deadbyte-process-policy.json'));
|
|
61
|
-
assert(norm(policy?.roots?.core?.path ?? '.') === norm(dir), label + ' process policy core root not bound to its own checkout');
|
|
62
|
-
assert(norm(policy?.native_host?.path ?? '.') === norm(path.join(dir,'bin','deadbyte-process-host.exe')), label + ' native host not self-bound');
|
|
63
|
-
assert(norm(policy?.grant_file ?? '.') === norm(path.join(dir,'controller','runtime','process-grant.json')), label + ' grant path not self-bound');
|
|
64
|
-
assert(norm(policy?.state_dir ?? '.') === norm(path.join(dir,'controller','runtime','process-state')), label + ' state path not self-bound');
|
|
65
|
-
}
|
|
66
|
-
return { sourceFiles: source.size, protectedFiles: slot.size };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export async function assertR108NpmPublishReady(release, {root = defaultRoot,provenance = null} = {}) {
|
|
70
|
-
const rootPath = path.resolve(root);
|
|
71
|
-
const pkg = await json(path.join(rootPath,'package.json'));
|
|
72
|
-
const prov = provenance ?? await json(path.join(rootPath,'PROVENANCE.json'));
|
|
73
|
-
const lock = await json(path.join(rootPath,'package-lock.json'));
|
|
74
|
-
assert(pkg.name === 'deadbyte-mcp', 'package name mismatch');
|
|
75
|
-
assert([pkg.version,lock.version,lock.packages?.['']?.version,release.version,prov.version].every(v => v === '0.15.48'), 'package/release/provenance identity mismatch');
|
|
76
|
-
assert(release.train === 'R108', 'release train is not R108');
|
|
77
|
-
assert(release.r108_candidate?.status === 'CANDIDATE_UNSEALED', 'R108 pending-state metadata missing');
|
|
78
|
-
assert(release.source_predecessor?.version === '0.15.47' && prov.source_predecessor_version === '0.15.47', 'published source predecessor mismatch');
|
|
79
|
-
assert(release.parent?.version === '0.15.45' && release.runtime_predecessor?.version === '0.15.45', 'runtime predecessor mismatch');
|
|
80
|
-
for (const key of ['release_id','manifest_sha256','generation_manifest_sha256']) {
|
|
81
|
-
assert(release.parent?.[key] === prov['parent_'+key], 'sealed parent lineage mismatch at ' + key);
|
|
82
|
-
assert(release.runtime_predecessor?.[key] === release.parent?.[key], 'runtime predecessor drift at ' + key);
|
|
83
|
-
assert(prov.runtime_predecessor?.[key] === release.parent?.[key], 'provenance runtime predecessor drift at ' + key);
|
|
84
|
-
}
|
|
85
|
-
const proof = await json(path.join(rootPath,'testing',evidenceName));
|
|
86
|
-
assert(proof.schema === 'deadbyte.r108-protected-publication-evidence.v1', 'missing/fake R108 proof schema');
|
|
87
|
-
assert(proof.version === '0.15.48', 'proof version mismatch');
|
|
88
|
-
assert(norm(proof.candidate_root ?? '.') === norm(rootPath), 'proof candidate root changed');
|
|
89
|
-
assert(proof.test_exit_code === 0, 'test process did not finish with exit 0');
|
|
90
|
-
const testLog = await readFile(path.join(rootPath,'testing','r108-protected-full.tap'));
|
|
91
|
-
assert(sha256(testLog) === proof.test_log_sha256, 'test log bytes drifted');
|
|
92
|
-
const actualCounts = testCounts(testLog.toString('utf8'));
|
|
93
|
-
for (const key of ['tests','pass','fail','skipped']) assert(actualCounts[key] === proof.counts?.[key], 'proof disagrees with test log at '+key);
|
|
94
|
-
const parity = await slotParity(rootPath, proof.protected_root, proof.source_manifest_sha256, proof.protected_manifest_sha256);
|
|
95
|
-
assert(parity.sourceFiles >= 2339, 'manifest file count smaller than R107 baseline');
|
|
96
|
-
console.log('R108_PREPUBLISH_GATE_PASS '+JSON.stringify({version:'0.15.48',manifest_sha256:proof.source_manifest_sha256,test_log_sha256:proof.test_log_sha256,counts:actualCounts,source_files:parity.sourceFiles,protected_files:parity.protectedFiles}));
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const invoked = process.argv[1] && norm(process.argv[1]) === norm(fileURLToPath(import.meta.url));
|
|
101
|
-
if (invoked) {
|
|
102
|
-
try {
|
|
103
|
-
const command = process.argv[2] ?? 'verify';
|
|
104
|
-
if (command === 'record') {
|
|
105
|
-
const [rootArg,protectedArg,exitCodeArg] = process.argv.slice(3);
|
|
106
|
-
assert(rootArg && protectedArg && exitCodeArg !== undefined, 'usage: node scripts/npm-release-readiness-r108.mjs record ROOT PROTECTED_ROOT TEST_EXIT');
|
|
107
|
-
const root = path.resolve(rootArg), protectedRoot = path.resolve(protectedArg);
|
|
108
|
-
assert(Number(exitCodeArg) === 0, 'test exit code not zero');
|
|
109
|
-
const testLog = await readFile(path.join(root,'testing','r108-protected-full.tap'));
|
|
110
|
-
const counts = testCounts(testLog.toString('utf8'));
|
|
111
|
-
const sourceManifest = sha256(await readFile(path.join(root,'MANIFEST.SHA256')));
|
|
112
|
-
const protectedManifest = sha256(await readFile(path.join(protectedRoot,'MANIFEST.SHA256')));
|
|
113
|
-
await slotParity(root,protectedRoot,sourceManifest,protectedManifest);
|
|
114
|
-
const receipt = {
|
|
115
|
-
schema:'deadbyte.r108-protected-publication-evidence.v1',
|
|
116
|
-
version:'0.15.48',candidate_root:root,protected_root:protectedRoot,
|
|
117
|
-
source_manifest_sha256:sourceManifest,protected_manifest_sha256:protectedManifest,
|
|
118
|
-
test_log_sha256:sha256(testLog),test_exit_code:0,counts,
|
|
119
|
-
limitations:'Locally hashed regression and source/protected manifest parity; not a hardware attestation or independent signature.'
|
|
120
|
-
};
|
|
121
|
-
const proofPath=path.join(root,'testing',evidenceName);
|
|
122
|
-
await mkdir(path.dirname(proofPath),{recursive:true});
|
|
123
|
-
await writeFile(proofPath,JSON.stringify(receipt,null,2)+'\n',{flag:'wx'});
|
|
124
|
-
console.log('R108_PROOF_WRITTEN '+JSON.stringify({path:proofPath,...receipt}));
|
|
125
|
-
} else if (command === 'verify') {
|
|
126
|
-
const root = path.resolve(process.argv[3] ?? defaultRoot);
|
|
127
|
-
const release = await json(path.join(root,'RELEASE.json'));
|
|
128
|
-
await assertR108NpmPublishReady(release,{root});
|
|
129
|
-
} else throw new Error('unknown command '+command);
|
|
130
|
-
} catch(error) {
|
|
131
|
-
console.error(error?.stack || String(error));
|
|
132
|
-
process.exitCode=1;
|
|
133
|
-
}
|
|
134
|
-
}
|