mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-11-06 21:01:54 +00:00
TASK-6e4ff870-a386-4a11-a59c-444ebc23732e: add hermetic candidate checks
This commit is contained in:
1 parent
1a2b5b0fec
commit
9946a2a3e4
5 files changed
+502
No files matched your search
@@ -0,0 +1,71 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdirSync, mkdtempSync, readFileSync, symlinkSync, writeFileSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
ARTIFACT_MANIFEST_FILE, artifactNodeKind, assertArtifactRelativePath, sealArtifactManifest, verifyArtifactManifest,
|
||||
} from '../../src/checks/artifact-manifest.mjs';
|
||||
|
||||
function fixture() {
|
||||
return mkdtempSync(join(tmpdir(), 'torch-candidate-manifest-'));
|
||||
}
|
||||
|
||||
function write(root, path, content) {
|
||||
const target = join(root, path);
|
||||
mkdirSync(join(target, '..'), { recursive: true });
|
||||
writeFileSync(target, content);
|
||||
}
|
||||
|
||||
test('SCN-artifact-manifest-seal: regular fixture artifacts seal as canonical sorted hash and length evidence regardless of creation order', () => {
|
||||
const first = fixture();
|
||||
const second = fixture();
|
||||
write(first, 'z/proof.txt', 'zeta');
|
||||
write(first, 'a/proof.txt', 'alpha');
|
||||
write(second, 'a/proof.txt', 'alpha');
|
||||
write(second, 'z/proof.txt', 'zeta');
|
||||
const left = sealArtifactManifest({ directory: first });
|
||||
const right = sealArtifactManifest({ directory: second });
|
||||
assert.deepEqual(left.files, right.files);
|
||||
assert.equal(left.sealDigest, right.sealDigest);
|
||||
assert.deepEqual(left.files.map((file) => file.path), ['a/proof.txt', 'z/proof.txt']);
|
||||
assert.equal(left.totalBytes, 9);
|
||||
assert.equal(verifyArtifactManifest({ directory: first }).verified, true);
|
||||
assert.throws(() => sealArtifactManifest({ directory: first }), { code: 'CANDIDATE_ARTIFACT_ALREADY_SEALED' });
|
||||
});
|
||||
|
||||
test('SCN-artifact-manifest-negative-paths: traversal, links, special files, caps and duplicate manifest paths refuse', () => {
|
||||
assert.throws(() => assertArtifactRelativePath('../escape'), { code: 'CANDIDATE_ARTIFACT_PATH_INVALID' });
|
||||
assert.throws(() => assertArtifactRelativePath('/absolute'), { code: 'CANDIDATE_ARTIFACT_PATH_INVALID' });
|
||||
|
||||
const linked = fixture();
|
||||
write(linked, 'safe.txt', 'safe');
|
||||
symlinkSync('safe.txt', join(linked, 'linked.txt'));
|
||||
assert.throws(() => sealArtifactManifest({ directory: linked }), { code: 'CANDIDATE_ARTIFACT_LINK_REJECTED' });
|
||||
|
||||
const limited = fixture();
|
||||
write(limited, 'large.txt', '12345');
|
||||
assert.throws(() => sealArtifactManifest({ directory: limited, limits: { maxFileBytes: 4 } }),
|
||||
{ code: 'CANDIDATE_ARTIFACT_LIMIT_EXCEEDED' });
|
||||
|
||||
assert.throws(() => artifactNodeKind({
|
||||
isSymbolicLink: () => false, isDirectory: () => false, isFile: () => false,
|
||||
}, 'pipe'), { code: 'CANDIDATE_ARTIFACT_SPECIAL_REJECTED' });
|
||||
|
||||
const malformed = fixture();
|
||||
write(malformed, 'proof.txt', 'proof');
|
||||
sealArtifactManifest({ directory: malformed });
|
||||
const path = join(malformed, ARTIFACT_MANIFEST_FILE);
|
||||
const record = JSON.parse(readFileSync(path, 'utf8'));
|
||||
record.files.push({ ...record.files[0] });
|
||||
writeFileSync(path, JSON.stringify(record));
|
||||
assert.throws(() => verifyArtifactManifest({ directory: malformed }), { code: 'CANDIDATE_ARTIFACT_MANIFEST_INVALID' });
|
||||
});
|
||||
|
||||
test('SCN-artifact-manifest-drift: post-seal mutation or overwrite is detected and cannot become retained evidence', () => {
|
||||
const root = fixture();
|
||||
write(root, 'proof.txt', 'before');
|
||||
sealArtifactManifest({ directory: root });
|
||||
write(root, 'proof.txt', 'after');
|
||||
assert.throws(() => verifyArtifactManifest({ directory: root }), { code: 'CANDIDATE_ARTIFACT_SEAL_DRIFT' });
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdtempSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import test from 'node:test';
|
||||
import { runCandidateEngine } from '../../src/checks/candidate-engine.mjs';
|
||||
|
||||
function fixtureInput() {
|
||||
return { directory: mkdtempSync(join(tmpdir(), 'torch-candidate-engine-')), digest: 'a'.repeat(64), bytes: 12 };
|
||||
}
|
||||
|
||||
function fixtureOptions(overrides = {}) {
|
||||
return {
|
||||
input: fixtureInput(),
|
||||
definition: { command: 'fixture-command', args: ['--fixed'] },
|
||||
args: ['--bounded'],
|
||||
environment: { FIXTURE_MODE: '1', TZ: 'UTC' },
|
||||
artifactDirectory: mkdtempSync(join(tmpdir(), 'torch-candidate-artifacts-')),
|
||||
executor: () => ({ status: 0, stdout: 'fixture output', stderr: '' }),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test('SCN-candidate-engine-pure-fixture: immutable bounded fixture execution returns only parent-observed nonpromotable evidence', () => {
|
||||
let invocation;
|
||||
const options = fixtureOptions({
|
||||
executor: (command, args, execution) => {
|
||||
invocation = { command, args, execution };
|
||||
return { status: 0, stdout: 'fixture output', stderr: '' };
|
||||
},
|
||||
});
|
||||
const observed = runCandidateEngine(options);
|
||||
assert.equal(observed.fixtureOnly, true);
|
||||
assert.deepEqual(observed.sourceAttestation, {
|
||||
schema: 'torch.dev/source-attestation/v1alpha1', promotion: 'nonpromotable',
|
||||
});
|
||||
assert.equal(Object.hasOwn(observed.sourceAttestation, 'receiptId'), false);
|
||||
assert.equal(observed.terminal.success, true);
|
||||
assert.equal(observed.terminal.kind, 'exit');
|
||||
assert.deepEqual(invocation.args, ['--fixed', '--bounded']);
|
||||
assert.equal(invocation.execution.cwd, options.input.directory);
|
||||
assert.deepEqual(invocation.execution.env, { FIXTURE_MODE: '1', TZ: 'UTC' });
|
||||
assert.equal(Object.isFrozen(invocation.execution), true);
|
||||
assert.equal(Object.hasOwn(invocation.execution, 'token'), false);
|
||||
assert.equal(Object.hasOwn(invocation.execution, 'receiptWriter'), false);
|
||||
assert.equal(Object.hasOwn(invocation.execution, 'controlPlane'), false);
|
||||
});
|
||||
|
||||
test('SCN-candidate-engine-limits: invalid bounded inputs, arguments, environment and artifact descriptors refuse before execution', () => {
|
||||
let executions = 0;
|
||||
const executor = () => { executions += 1; return { status: 0 }; };
|
||||
assert.throws(() => runCandidateEngine(fixtureOptions({ executor, input: { directory: '/tmp', digest: 'bad', bytes: 1 } })),
|
||||
{ code: 'CANDIDATE_ENGINE_INPUT_INVALID' });
|
||||
assert.throws(() => runCandidateEngine(fixtureOptions({ executor, args: ['x'.repeat(8)], limits: { maxArgBytes: 4 } })),
|
||||
{ code: 'CANDIDATE_ENGINE_INPUT_INVALID' });
|
||||
assert.throws(() => runCandidateEngine(fixtureOptions({ executor, environment: { bad: '1' } })),
|
||||
{ code: 'CANDIDATE_ENGINE_INPUT_INVALID' });
|
||||
assert.throws(() => runCandidateEngine(fixtureOptions({ executor, artifactDirectory: 'x'.repeat(5), limits: { maxArtifactPathBytes: 4 } })),
|
||||
{ code: 'CANDIDATE_ENGINE_INPUT_INVALID' });
|
||||
assert.equal(executions, 0, 'refusal must occur before a candidate executor starts');
|
||||
});
|
||||
|
||||
test('SCN-candidate-engine-terminal-observation: overflow, including exit zero plus ENOBUFS, is raw parent evidence and never success', () => {
|
||||
const overflow = runCandidateEngine(fixtureOptions({
|
||||
limits: { maxOutputBytes: 4 },
|
||||
executor: () => ({ status: 0, error: Object.assign(new Error('overflow'), { code: 'ENOBUFS' }), stdout: 'too many bytes' }),
|
||||
}));
|
||||
assert.equal(overflow.terminal.exitStatus, 0);
|
||||
assert.equal(overflow.terminal.kind, 'overflow');
|
||||
assert.equal(overflow.terminal.success, false);
|
||||
assert.equal(overflow.terminal.overflow, true);
|
||||
|
||||
const timeout = runCandidateEngine(fixtureOptions({
|
||||
executor: () => ({ status: null, timedOut: true, error: Object.assign(new Error('timeout'), { code: 'ETIMEDOUT' }) }),
|
||||
}));
|
||||
assert.equal(timeout.terminal.kind, 'timeout');
|
||||
assert.equal(timeout.terminal.success, false);
|
||||
|
||||
const signal = runCandidateEngine(fixtureOptions({ executor: () => ({ status: null, signal: 'SIGTERM' }) }));
|
||||
assert.equal(signal.terminal.kind, 'signal');
|
||||
assert.equal(signal.terminal.success, false);
|
||||
});
|
||||
|
||||
test('SCN-candidate-engine-capability-boundary: registered-state and writer-shaped inputs are rejected before execution', () => {
|
||||
let executions = 0;
|
||||
const options = fixtureOptions({ executor: () => { executions += 1; return { status: 0 }; } });
|
||||
options.controlPlane = {};
|
||||
assert.throws(() => runCandidateEngine(options), { code: 'CANDIDATE_ENGINE_CAPABILITY_FORBIDDEN' });
|
||||
assert.equal(executions, 0);
|
||||
});
|
||||
Reference in new issue
Block a user