Files
jobtrackingapp/docs/automation/handoffs/pre-phase10/package.test.mjs
T

95 lines
4.7 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
import zlib from 'node:zlib';
import { fileURLToPath } from 'node:url';
import { validatePackage } from './verify.mjs';
const directory = path.dirname(fileURLToPath(import.meta.url));
const repository = fs.realpathSync(path.resolve(directory, '../../../..'));
const artifactRoot = path.join(repository, '.artifacts');
fs.mkdirSync(artifactRoot, { recursive: true });
assert.ok(fs.realpathSync(artifactRoot).startsWith(repository + path.sep));
const hash = bytes => crypto.createHash('sha256').update(bytes).digest('hex');
function shadow(change) {
const temporary = fs.mkdtempSync(path.join(artifactRoot, 'handoff-verify-'));
try {
fs.cpSync(directory, temporary, { recursive: true });
change(temporary);
assert.throws(() => validatePackage(temporary));
} finally {
const resolved = fs.realpathSync(temporary);
assert.ok(resolved.startsWith(artifactRoot + path.sep) && path.basename(resolved).startsWith('handoff-verify-'));
fs.rmSync(resolved, { recursive: true });
}
}
function json(directory, name, change) {
const file = path.join(directory, name + '.json');
const value = JSON.parse(fs.readFileSync(file, 'utf8'));
change(value);
fs.writeFileSync(file, JSON.stringify(value));
}
test('complete evidence validates while Phase10 remains blocked', () => {
const result = validatePackage();
assert.equal(result.integrity, 'PASS');
assert.equal(result.phase10, 'BLOCKED');
assert.equal(result.eligible, false);
});
test('worker-written GO and approval-shaped data cannot advance', () => shadow(base => {
json(base, 'ACCEPTANCE', value => { value.phase10DevelopmentReadiness = 'GO'; value.eligibleForAutomaticExecution = true; value.ownerSignature = 'invented'; });
}));
test('report from a different commit is rejected', () => shadow(base => {
json(base, 'TEST_EVIDENCE', value => { value.reports[0].sourceCommit = '0'.repeat(40); });
}));
test('missing native artifact is rejected', () => shadow(base => {
const index = JSON.parse(fs.readFileSync(path.join(base, 'TEST_EVIDENCE.json'), 'utf8'));
const report = index.reports.find(item => item.nativeFormat);
fs.unlinkSync(path.join(base, index.artifacts.find(item => item.id === report.artifactId).path));
}));
test('changed native bytes are rejected', () => shadow(base => {
const index = JSON.parse(fs.readFileSync(path.join(base, 'TEST_EVIDENCE.json'), 'utf8'));
const report = index.reports.find(item => item.nativeFormat);
fs.appendFileSync(path.join(base, index.artifacts.find(item => item.id === report.artifactId).path), 'changed');
}));
test('rewriting a process hash cannot conceal its nonzero native exit', () => shadow(base => {
json(base, 'TEST_EVIDENCE', index => {
const report = index.reports.find(item => item.nativeFormat);
const artifact = index.artifacts.find(item => item.id === report.processArtifactId);
const file = path.join(base, artifact.path);
const data = JSON.parse(zlib.gunzipSync(fs.readFileSync(file)).toString('utf8'));
const keys = report.processPointer.slice(1).split('/');
let parent = data;
for (const key of keys.slice(0, -1)) parent = parent[key];
parent[keys.at(-1)] = 17;
const bytes = zlib.gzipSync(JSON.stringify(data));
fs.writeFileSync(file, bytes); artifact.sha256 = hash(bytes);
});
}));
test('omitting a source file from both manifests cannot claim a complete freeze', () => shadow(base => {
json(base, 'TEST_EVIDENCE', index => {
for (const id of [index.sourceManifestArtifactId, index.sourceAfterArtifactId]) {
const artifact = index.artifacts.find(item => item.id === id);
const file = path.join(base, artifact.path);
const data = JSON.parse(zlib.gunzipSync(fs.readFileSync(file)).toString('utf8'));
delete data[Object.keys(data)[0]];
const bytes = zlib.gzipSync(JSON.stringify(data));
fs.writeFileSync(file, bytes); artifact.sha256 = hash(bytes);
}
});
}));
test('artifact paths cannot escape the imported package', () => shadow(base => {
json(base, 'TEST_EVIDENCE', index => { index.artifacts[0].path = '../../outside'; });
}));
test('an imported schema cannot weaken the trusted schema', () => shadow(base => {
fs.writeFileSync(path.join(base, 'HANDOFF_SCHEMA.json'), '{}');
}));
test('model quality cannot become PASS from the rejected development probes', () => shadow(base => {
json(base, 'ACCEPTANCE', value => { value.verdicts.find(item => item.criterion === 'CV AI Accuracy').status = 'PASS'; });
}));
test('a mandatory entry blocker cannot be self-deferred', () => shadow(base => {
json(base, 'ACCEPTANCE', value => { value.permissibleDeferrals.push('P10-ENTRY-01'); });
}));