diff --git a/docs/TEST_INTEGRITY.md b/docs/TEST_INTEGRITY.md index aa6ba3e..b80534b 100644 --- a/docs/TEST_INTEGRITY.md +++ b/docs/TEST_INTEGRITY.md @@ -1,5 +1,50 @@ # Test Integrity Notes +## 2026-10-01 — Candidate attempt-store B0 fixture schema + +```yaml +test_integrity_note: + change_type: new_tests + scenarios: + - id: SCN-candidate-store-canonical-schema + given: The B0 internal ordered CREATE and INDEX schema statements and version framing + when: Their UTF-8/LF DDL and schema preimages are produced + then: Independently assembled bytes and SHA-256 digests match, without self-referential stored metadata + - id: SCN-candidate-store-fixture-provisioning + given: A harness-created empty synthetic fixture target and opaque capability + when: B0 provisions and read-only verifies candidate-store metadata + then: Foreign keys are enabled on the verifier connection, user_version is 1, and no root, manifest, database, or raw handle is exposed + - id: SCN-candidate-store-fixture-nonpromotion + given: A provisioned B0 fixture attestation + when: Its public module surfaces are inspected + then: It remains permanently nonpromotable and exposes no lifecycle, receipt, or native PASS authority + - id: SCN-candidate-store-fixture-authority + given: Foreign, closed, reused, nonempty, or registered-relationship fixture inputs + when: Provisioning is attempted + then: It refuses before usable metadata, and no caller-supplied root, database, manifest, or DDL is accepted + - id: SCN-candidate-store-metadata-drift + given: A provisioned fixture with one enumerated bounded test corruption + when: Read-only metadata verification runs + then: DDL or metadata drift is rejected with a stable code and no lifecycle, receipt, or native PASS behavior exists + observable_outcomes: + - Canonical version-framed DDL/schema bytes and independently computed digests + - Read-only metadata, per-connection foreign-key status, schema version, and nonpromotable fixture attestation + - Stable refusals for authority expiry/reuse, preexisting bytes, registered relationships, malformed metadata, and schema drift + determinism_controls: + - Harness-owned mkdtemp target, generated synthetic identity, private WeakMap capability, fixed created_at, and enumerated internal corruption only + - No registered project root, live control-plane database, network, provider, retry, sleep, dashboard, or mutable golden data + anti_cheat_rationale: + prevents: + - Replacing canonical DDL or its framing while updating expectations from the implementation under test + - Accepting a caller-selected root, database, manifest, DDL, or raw SQLite handle + - Reusing, forging, or extending a fixture authority after close or first provisioning attempt + - Treating fixture evidence as a receipt, lifecycle result, native PASS, or consumer eligibility + - Ignoring per-connection foreign-key setup, schema-version drift, or malformed metadata + relaxation: + did_relax_any_assertion: false + if_true_explain_spec_basis: "" +``` + ## 2026-10-01 — Atomic runtime identity reservations ```yaml diff --git a/src/control-plane/candidate-attempt-store-provisioner.mjs b/src/control-plane/candidate-attempt-store-provisioner.mjs new file mode 100644 index 0000000..f2a7f2a --- /dev/null +++ b/src/control-plane/candidate-attempt-store-provisioner.mjs @@ -0,0 +1,163 @@ +import { randomUUID } from 'node:crypto'; +import { existsSync, mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { DatabaseSync } from 'node:sqlite'; +import { TorchError } from '../kernel/errors.mjs'; +import { + candidateAttemptStoreDigestsV1, + initializeCandidateAttemptStoreV1, + inspectCandidateAttemptStoreMetadataV1, +} from './candidate-attempt-store.mjs'; + +const harnesses = new WeakMap(); +const fixtures = new WeakMap(); +const TEST_CORRUPTIONS = new Set(['nonempty', 'registered-relationship', 'ddl-drift', 'malformed-meta']); + +function fail(message, code, details) { + throw new TorchError(message, { code, details }); +} + +function exactObject(value, allowed, label) { + if (!value || typeof value !== 'object' || Array.isArray(value)) { + fail(`${label} must be an object`, 'CANDIDATE_STORE_FIXTURE_INPUT_INVALID'); + } + for (const key of Object.keys(value)) { + if (!allowed.has(key)) fail(`${label} contains an unsupported field`, 'CANDIDATE_STORE_FIXTURE_INPUT_INVALID', { field: key }); + } +} + +function assertHarness(harness) { + const state = harnesses.get(harness); + if (!state) fail('Fixture authority is not issued by this harness', 'CANDIDATE_STORE_FIXTURE_AUTH_REQUIRED'); + if (state.closed) fail('Fixture authority has expired', 'CANDIDATE_STORE_FIXTURE_AUTH_EXPIRED'); + return state; +} + +function assertFixture(fixture) { + const state = fixtures.get(fixture); + if (!state) fail('Fixture attestation is not issued by this harness', 'CANDIDATE_STORE_FIXTURE_AUTH_REQUIRED'); + if (state.closed) fail('Fixture attestation has expired', 'CANDIDATE_STORE_FIXTURE_AUTH_EXPIRED'); + return state; +} + +function databasePath(state) { + return join(state.root, 'candidate-attempt-store.sqlite'); +} + +function assertFreshTarget(state) { + const marker = join(state.root, '.torch', 'install-manifest.json'); + if (existsSync(marker)) fail('Fixture target has a registered-install relationship', 'CANDIDATE_STORE_REGISTERED_TARGET_FORBIDDEN'); + const entries = readdirSync(state.root); + if (entries.length !== 0) fail('Fixture target is not empty', 'CANDIDATE_STORE_FIXTURE_NONEMPTY'); +} + +function closeState(state) { + if (state.closed) return; + state.closed = true; + rmSync(state.root, { recursive: true, force: true }); +} + +/** Creates its own synthetic target and opaque capability; callers cannot supply roots or SQLite handles. */ +export function createCandidateAttemptStoreFixtureHarnessV1(input = {}) { + exactObject(input, new Set(), 'Fixture harness input'); + const root = mkdtempSync(join(tmpdir(), 'torch-candidate-attempt-store-')); + const fixtureIdentity = `fixture-${randomUUID()}`; + const harness = Object.freeze({ schema: 'torch.dev/candidate-attempt-fixture-authority/v1alpha1', fixtureIdentity }); + harnesses.set(harness, { root, fixtureIdentity, used: false, closed: false }); + return harness; +} + +/** Enumerated hermetic corruption hook for strict tests; it never reveals a filesystem or database handle. */ +export function applyCandidateAttemptStoreFixtureTestCorruptionV1(input = {}) { + exactObject(input, new Set(['harness', 'kind']), 'Fixture corruption input'); + const { harness, kind } = input; + const state = assertHarness(harness); + if (!TEST_CORRUPTIONS.has(kind)) { + fail('Fixture corruption kind is unsupported', 'CANDIDATE_STORE_FIXTURE_INPUT_INVALID', { kind }); + } + if (kind === 'nonempty') writeFileSync(join(state.root, 'preexisting-fixture-byte'), 'fixture only\n', { flag: 'wx' }); + if (kind === 'registered-relationship') { + const markerRoot = join(state.root, '.torch'); + mkdirSync(markerRoot); + writeFileSync(join(markerRoot, 'install-manifest.json'), '{"fixture":"registered-relationship"}\n', { flag: 'wx' }); + } + if (kind === 'ddl-drift' || kind === 'malformed-meta') { + if (!state.fixture) fail('Fixture corruption requires a provisioned fixture', 'CANDIDATE_STORE_FIXTURE_INPUT_INVALID', { kind }); + const database = new DatabaseSync(databasePath(state)); + try { + if (kind === 'ddl-drift') database.exec('CREATE TABLE fixture_schema_drift (id TEXT PRIMARY KEY)'); + else database.prepare('UPDATE candidate_attempt_store_meta SET ddl_digest = ? WHERE singleton = 1').run('0'.repeat(64)); + } finally { + database.close(); + } + } + return Object.freeze({ applied: kind }); +} + +export function provisionCandidateAttemptStoreFixtureV1(input = {}) { + exactObject(input, new Set(['harness']), 'Fixture provision input'); + const state = assertHarness(input.harness); + if (state.used) fail('Fixture authority is single-use', 'CANDIDATE_STORE_FIXTURE_AUTH_REUSED'); + state.used = true; + assertFreshTarget(state); + const database = new DatabaseSync(databasePath(state)); + let metadata; + try { + metadata = initializeCandidateAttemptStoreV1(database, { + fixtureIdentity: state.fixtureIdentity, + storeIdentity: `store-${randomUUID()}`, + createdAt: '2026-10-01T00:00:00.000Z', + }); + } finally { + database.close(); + } + const fixture = Object.freeze({ + schema: 'torch.dev/candidate-attempt-fixture-attestation/v1alpha1', + fixtureIdentity: metadata.fixtureIdentity, + storeIdentity: metadata.storeIdentity, + protocolVersion: metadata.protocolVersion, + schemaVersion: metadata.schemaVersion, + ddlDigest: metadata.ddlDigest, + schemaDigest: metadata.schemaDigest, + promotion: 'nonpromotable', + }); + state.fixture = fixture; + fixtures.set(fixture, state); + return fixture; +} + +/** Opens only a closure-owned fixture DB for read-only metadata inspection. */ +export function inspectCandidateAttemptStoreFixtureV1(input = {}) { + exactObject(input, new Set(['fixture']), 'Fixture inspection input'); + const fixture = input.fixture; + const state = assertFixture(fixture); + const database = new DatabaseSync(databasePath(state), { readOnly: true }); + try { + const metadata = inspectCandidateAttemptStoreMetadataV1(database); + const digests = candidateAttemptStoreDigestsV1(); + if (metadata.fixtureIdentity !== fixture.fixtureIdentity || metadata.storeIdentity !== fixture.storeIdentity + || metadata.ddlDigest !== digests.ddlDigest || metadata.schemaDigest !== digests.schemaDigest + || fixture.promotion !== 'nonpromotable') { + fail('Fixture attestation does not match its metadata', 'CANDIDATE_STORE_FIXTURE_DRIFT'); + } + return Object.freeze({ ...metadata, nonpromotable: true }); + } finally { + database.close(); + } +} + +export function closeCandidateAttemptStoreFixtureV1(input = {}) { + exactObject(input, new Set(['fixture']), 'Fixture close input'); + const fixture = input.fixture; + const state = assertFixture(fixture); + closeState(state); + return Object.freeze({ closed: true, fixtureIdentity: fixture.fixtureIdentity }); +} + +export function closeCandidateAttemptStoreFixtureHarnessV1(input = {}) { + exactObject(input, new Set(['harness']), 'Fixture harness close input'); + const state = assertHarness(input.harness); + closeState(state); + return Object.freeze({ closed: true, fixtureIdentity: state.fixtureIdentity }); +} diff --git a/src/control-plane/candidate-attempt-store.mjs b/src/control-plane/candidate-attempt-store.mjs new file mode 100644 index 0000000..97e5691 --- /dev/null +++ b/src/control-plane/candidate-attempt-store.mjs @@ -0,0 +1,192 @@ +import { createHash } from 'node:crypto'; +import { TorchError } from '../kernel/errors.mjs'; + +export const CANDIDATE_ATTEMPT_STORE_PROTOCOL_VERSION = 1; +export const CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION = 1; + +const DIGEST_PATTERN = /^[0-9a-f]{64}$/; +const MAX_IDENTIFIER_BYTES = 128; + +const DDL_STATEMENTS = Object.freeze([ + `CREATE TABLE candidate_attempt_store_meta ( + singleton INTEGER PRIMARY KEY CHECK (singleton = 1), + protocol_version INTEGER NOT NULL CHECK (protocol_version = 1), + schema_version INTEGER NOT NULL CHECK (schema_version = 1), + ddl_digest TEXT NOT NULL CHECK (length(ddl_digest) = 64 AND ddl_digest NOT GLOB '*[^0-9a-f]*'), + schema_digest TEXT NOT NULL CHECK (length(schema_digest) = 64 AND schema_digest NOT GLOB '*[^0-9a-f]*'), + fixture_identity TEXT NOT NULL UNIQUE CHECK (length(fixture_identity) BETWEEN 1 AND 128), + store_identity TEXT NOT NULL UNIQUE CHECK (length(store_identity) BETWEEN 1 AND 128), + promotion TEXT NOT NULL CHECK (promotion = 'nonpromotable'), + created_at TEXT NOT NULL CHECK (length(created_at) BETWEEN 1 AND 40) +)`, + 'CREATE INDEX candidate_attempt_store_meta_fixture_identity_idx ON candidate_attempt_store_meta (fixture_identity)', +]); + +function fail(message, code, details) { + throw new TorchError(message, { code, details }); +} + +function digest(bytes) { + return createHash('sha256').update(bytes).digest('hex'); +} + +function frame(label, value) { + const bytes = Buffer.from(value, 'utf8'); + return `${label}:${bytes.length}\n${value}\n`; +} + +function exactObject(value, allowed, label) { + if (!value || typeof value !== 'object' || Array.isArray(value)) { + fail(`${label} must be an object`, 'CANDIDATE_STORE_METADATA_INVALID'); + } + for (const key of Object.keys(value)) { + if (!allowed.has(key)) fail(`${label} contains an unsupported field`, 'CANDIDATE_STORE_METADATA_INVALID', { field: key }); + } +} + +function boundedIdentifier(value, field) { + if (typeof value !== 'string' || !value || Buffer.byteLength(value, 'utf8') > MAX_IDENTIFIER_BYTES) { + fail(`${field} must be a bounded identifier`, 'CANDIDATE_STORE_METADATA_INVALID', { field }); + } + return value; +} + +function expectedMetaRow() { + const digests = candidateAttemptStoreDigestsV1(); + return { + protocolVersion: CANDIDATE_ATTEMPT_STORE_PROTOCOL_VERSION, + schemaVersion: CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION, + ddlDigest: digests.ddlDigest, + schemaDigest: digests.schemaDigest, + }; +} + +function assertConnection(database) { + if (!database || typeof database.exec !== 'function' || typeof database.prepare !== 'function') { + fail('Candidate-store metadata verifier requires an internal SQLite connection', 'CANDIDATE_STORE_METADATA_INVALID'); + } + database.exec('PRAGMA foreign_keys = ON'); + const foreignKeys = database.prepare('PRAGMA foreign_keys').get()?.foreign_keys; + if (foreignKeys !== 1) fail('Candidate-store connection did not enable foreign keys', 'CANDIDATE_STORE_FOREIGN_KEYS_REQUIRED'); + return foreignKeys; +} + +function assertSchemaStatements(database) { + const actual = database.prepare(` + SELECT type, name, sql + FROM sqlite_master + WHERE type IN ('table', 'index') AND name NOT LIKE 'sqlite_%' + ORDER BY CASE name + WHEN 'candidate_attempt_store_meta' THEN 0 + WHEN 'candidate_attempt_store_meta_fixture_identity_idx' THEN 1 + ELSE 2 + END ASC + `).all(); + const expected = [ + { type: 'table', name: 'candidate_attempt_store_meta', sql: DDL_STATEMENTS[0] }, + { type: 'index', name: 'candidate_attempt_store_meta_fixture_identity_idx', sql: DDL_STATEMENTS[1] }, + ]; + if (JSON.stringify(actual) !== JSON.stringify(expected)) { + fail('Candidate-store DDL does not match the canonical v1 schema', 'CANDIDATE_STORE_SCHEMA_DRIFT'); + } +} + +/** Internal, version-framed UTF-8/LF preimage; it contains no stored metadata values. */ +export function candidateAttemptStoreDdlBytesV1() { + const payload = [ + frame('schema', 'torch.dev/candidate-attempt-store-ddl/v1alpha1'), + frame('protocol-version', String(CANDIDATE_ATTEMPT_STORE_PROTOCOL_VERSION)), + frame('schema-version', String(CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION)), + ...DDL_STATEMENTS.map((statement, index) => frame(`statement-${index + 1}`, statement)), + ].join(''); + return Buffer.from(payload, 'utf8'); +} + +/** Internal schema preimage intentionally excludes schema_digest itself. */ +export function candidateAttemptStoreSchemaBytesV1() { + const ddlDigest = digest(candidateAttemptStoreDdlBytesV1()); + const payload = [ + frame('schema', 'torch.dev/candidate-attempt-store-schema/v1alpha1'), + frame('protocol-version', String(CANDIDATE_ATTEMPT_STORE_PROTOCOL_VERSION)), + frame('schema-version', String(CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION)), + frame('ddl-digest', ddlDigest), + ].join(''); + return Buffer.from(payload, 'utf8'); +} + +export function candidateAttemptStoreDigestsV1() { + const ddlBytes = candidateAttemptStoreDdlBytesV1(); + const schemaBytes = candidateAttemptStoreSchemaBytesV1(); + return Object.freeze({ ddlDigest: digest(ddlBytes), schemaDigest: digest(schemaBytes) }); +} + +/** Internal provisioner seam; never accepts a caller path, root, manifest, or DDL. */ +export function initializeCandidateAttemptStoreV1(database, metadata) { + exactObject(metadata, new Set(['fixtureIdentity', 'storeIdentity', 'createdAt']), 'Candidate-store metadata'); + const fixtureIdentity = boundedIdentifier(metadata.fixtureIdentity, 'fixtureIdentity'); + const storeIdentity = boundedIdentifier(metadata.storeIdentity, 'storeIdentity'); + if (typeof metadata.createdAt !== 'string' || !metadata.createdAt || Buffer.byteLength(metadata.createdAt, 'utf8') > 40) { + fail('createdAt must be bounded ISO text', 'CANDIDATE_STORE_METADATA_INVALID', { field: 'createdAt' }); + } + assertConnection(database); + database.exec(`PRAGMA user_version = ${CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION}`); + for (const statement of DDL_STATEMENTS) database.exec(statement); + const digests = candidateAttemptStoreDigestsV1(); + database.prepare(` + INSERT INTO candidate_attempt_store_meta ( + singleton, protocol_version, schema_version, ddl_digest, schema_digest, + fixture_identity, store_identity, promotion, created_at + ) VALUES (1, ?, ?, ?, ?, ?, ?, 'nonpromotable', ?) + `).run( + CANDIDATE_ATTEMPT_STORE_PROTOCOL_VERSION, + CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION, + digests.ddlDigest, + digests.schemaDigest, + fixtureIdentity, + storeIdentity, + metadata.createdAt, + ); + return inspectCandidateAttemptStoreMetadataV1(database); +} + +/** Internal read-only metadata verifier. Its connection is owned by the fixture provisioner. */ +export function inspectCandidateAttemptStoreMetadataV1(database) { + const foreignKeys = assertConnection(database); + const userVersion = database.prepare('PRAGMA user_version').get()?.user_version; + if (userVersion !== CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION) { + fail('Candidate-store user_version is incompatible', 'CANDIDATE_STORE_SCHEMA_MISMATCH', { + expected: CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION, observed: userVersion, + }); + } + assertSchemaStatements(database); + const rows = database.prepare(` + SELECT protocol_version, schema_version, ddl_digest, schema_digest, + fixture_identity, store_identity, promotion, created_at + FROM candidate_attempt_store_meta + ORDER BY singleton ASC + `).all(); + if (rows.length !== 1) fail('Candidate-store metadata must contain exactly one row', 'CANDIDATE_STORE_METADATA_INVALID'); + const row = rows[0]; + const expected = expectedMetaRow(); + if (row.protocol_version !== expected.protocolVersion || row.schema_version !== expected.schemaVersion + || row.ddl_digest !== expected.ddlDigest || row.schema_digest !== expected.schemaDigest + || row.promotion !== 'nonpromotable' || !DIGEST_PATTERN.test(row.ddl_digest) || !DIGEST_PATTERN.test(row.schema_digest)) { + fail('Candidate-store metadata is malformed or drifted', 'CANDIDATE_STORE_METADATA_INVALID'); + } + boundedIdentifier(row.fixture_identity, 'fixtureIdentity'); + boundedIdentifier(row.store_identity, 'storeIdentity'); + if (typeof row.created_at !== 'string' || !row.created_at || Buffer.byteLength(row.created_at, 'utf8') > 40) { + fail('Candidate-store created_at is malformed', 'CANDIDATE_STORE_METADATA_INVALID'); + } + return Object.freeze({ + protocolVersion: row.protocol_version, + schemaVersion: row.schema_version, + ddlDigest: row.ddl_digest, + schemaDigest: row.schema_digest, + fixtureIdentity: row.fixture_identity, + storeIdentity: row.store_identity, + promotion: row.promotion, + createdAt: row.created_at, + connection: Object.freeze({ foreignKeys, userVersion }), + }); +} diff --git a/test/fleet/candidate-attempt-store.test.mjs b/test/fleet/candidate-attempt-store.test.mjs new file mode 100644 index 0000000..bf86c67 --- /dev/null +++ b/test/fleet/candidate-attempt-store.test.mjs @@ -0,0 +1,162 @@ +import assert from 'node:assert/strict'; +import { createHash } from 'node:crypto'; +import test from 'node:test'; +import { + CANDIDATE_ATTEMPT_STORE_PROTOCOL_VERSION, + CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION, + candidateAttemptStoreDdlBytesV1, + candidateAttemptStoreDigestsV1, + candidateAttemptStoreSchemaBytesV1, +} from '../../src/control-plane/candidate-attempt-store.mjs'; +import { + applyCandidateAttemptStoreFixtureTestCorruptionV1, + closeCandidateAttemptStoreFixtureHarnessV1, + closeCandidateAttemptStoreFixtureV1, + createCandidateAttemptStoreFixtureHarnessV1, + inspectCandidateAttemptStoreFixtureV1, + provisionCandidateAttemptStoreFixtureV1, +} from '../../src/control-plane/candidate-attempt-store-provisioner.mjs'; + +const expectedStatements = [ + `CREATE TABLE candidate_attempt_store_meta ( + singleton INTEGER PRIMARY KEY CHECK (singleton = 1), + protocol_version INTEGER NOT NULL CHECK (protocol_version = 1), + schema_version INTEGER NOT NULL CHECK (schema_version = 1), + ddl_digest TEXT NOT NULL CHECK (length(ddl_digest) = 64 AND ddl_digest NOT GLOB '*[^0-9a-f]*'), + schema_digest TEXT NOT NULL CHECK (length(schema_digest) = 64 AND schema_digest NOT GLOB '*[^0-9a-f]*'), + fixture_identity TEXT NOT NULL UNIQUE CHECK (length(fixture_identity) BETWEEN 1 AND 128), + store_identity TEXT NOT NULL UNIQUE CHECK (length(store_identity) BETWEEN 1 AND 128), + promotion TEXT NOT NULL CHECK (promotion = 'nonpromotable'), + created_at TEXT NOT NULL CHECK (length(created_at) BETWEEN 1 AND 40) +)`, + 'CREATE INDEX candidate_attempt_store_meta_fixture_identity_idx ON candidate_attempt_store_meta (fixture_identity)', +]; + +function frame(label, value) { + const bytes = Buffer.from(value, 'utf8'); + return `${label}:${bytes.length}\n${value}\n`; +} + +function sha256(value) { + return createHash('sha256').update(value).digest('hex'); +} + +function independentlyExpectedDigests() { + const ddl = Buffer.from([ + frame('schema', 'torch.dev/candidate-attempt-store-ddl/v1alpha1'), + frame('protocol-version', '1'), + frame('schema-version', '1'), + ...expectedStatements.map((statement, index) => frame(`statement-${index + 1}`, statement)), + ].join(''), 'utf8'); + const ddlDigest = sha256(ddl); + const schema = Buffer.from([ + frame('schema', 'torch.dev/candidate-attempt-store-schema/v1alpha1'), + frame('protocol-version', '1'), + frame('schema-version', '1'), + frame('ddl-digest', ddlDigest), + ].join(''), 'utf8'); + return { ddl, schema, ddlDigest, schemaDigest: sha256(schema) }; +} + +function expectCode(callback, code) { + assert.throws(callback, (error) => error.code === code); +} + +test('SCN-candidate-store-canonical-schema: ordered version-framed UTF-8/LF bytes have independently computed digests', () => { + const expected = independentlyExpectedDigests(); + assert.equal(CANDIDATE_ATTEMPT_STORE_PROTOCOL_VERSION, 1); + assert.equal(CANDIDATE_ATTEMPT_STORE_SCHEMA_VERSION, 1); + assert.deepEqual(candidateAttemptStoreDdlBytesV1(), expected.ddl); + assert.deepEqual(candidateAttemptStoreSchemaBytesV1(), expected.schema); + assert.deepEqual(candidateAttemptStoreDigestsV1(), { + ddlDigest: expected.ddlDigest, + schemaDigest: expected.schemaDigest, + }); + assert.equal(candidateAttemptStoreSchemaBytesV1().includes(Buffer.from(expected.schemaDigest, 'utf8')), false, + 'the schema preimage must not include its own digest'); +}); + +test('SCN-candidate-store-fixture-provisioning: a private fresh fixture verifies v1 metadata with per-connection foreign keys and user_version', () => { + const harness = createCandidateAttemptStoreFixtureHarnessV1(); + const fixture = provisionCandidateAttemptStoreFixtureV1({ harness }); + const inspected = inspectCandidateAttemptStoreFixtureV1({ fixture }); + const expected = independentlyExpectedDigests(); + assert.deepEqual({ + protocolVersion: fixture.protocolVersion, + schemaVersion: fixture.schemaVersion, + ddlDigest: fixture.ddlDigest, + schemaDigest: fixture.schemaDigest, + promotion: fixture.promotion, + }, { + protocolVersion: 1, + schemaVersion: 1, + ddlDigest: expected.ddlDigest, + schemaDigest: expected.schemaDigest, + promotion: 'nonpromotable', + }); + assert.deepEqual(inspected.connection, { foreignKeys: 1, userVersion: 1 }); + for (const forbidden of ['root', 'path', 'database', 'manifest', 'handle']) { + assert.equal(Object.hasOwn(fixture, forbidden), false, `fixture must not expose ${forbidden}`); + assert.equal(Object.hasOwn(inspected, forbidden), false, `inspection must not expose ${forbidden}`); + } + closeCandidateAttemptStoreFixtureV1({ fixture }); + expectCode(() => inspectCandidateAttemptStoreFixtureV1({ fixture }), 'CANDIDATE_STORE_FIXTURE_AUTH_EXPIRED'); +}); + +test('SCN-candidate-store-fixture-nonpromotion: fixture attestation cannot expose lifecycle, receipt, or native-PASS authority', async () => { + const harness = createCandidateAttemptStoreFixtureHarnessV1(); + const fixture = provisionCandidateAttemptStoreFixtureV1({ harness }); + const provisioner = await import('../../src/control-plane/candidate-attempt-store-provisioner.mjs'); + const store = await import('../../src/control-plane/candidate-attempt-store.mjs'); + assert.equal(fixture.promotion, 'nonpromotable'); + assert.equal(inspectCandidateAttemptStoreFixtureV1({ fixture }).nonpromotable, true); + for (const forbiddenExport of [ + 'issueAttemptV1', 'startAttemptV1', 'sealAttemptV1', 'finalizeAttemptV1', 'createCandidateSourceReceiptV1', + ]) { + assert.equal(Object.hasOwn(store, forbiddenExport), false, `${forbiddenExport} is outside B0`); + assert.equal(Object.hasOwn(provisioner, forbiddenExport), false, `${forbiddenExport} is outside B0`); + } + closeCandidateAttemptStoreFixtureV1({ fixture }); +}); + +test('SCN-candidate-store-fixture-authority: foreign, closed, reused, nonempty, and registered fixture targets refuse before usable metadata', () => { + expectCode(() => createCandidateAttemptStoreFixtureHarnessV1({ root: '/tmp/not-allowed' }), 'CANDIDATE_STORE_FIXTURE_INPUT_INVALID'); + const foreign = { schema: 'torch.dev/candidate-attempt-fixture-authority/v1alpha1', fixtureIdentity: 'foreign' }; + expectCode(() => provisionCandidateAttemptStoreFixtureV1({ harness: foreign }), 'CANDIDATE_STORE_FIXTURE_AUTH_REQUIRED'); + + const closed = createCandidateAttemptStoreFixtureHarnessV1(); + closeCandidateAttemptStoreFixtureHarnessV1({ harness: closed }); + expectCode(() => provisionCandidateAttemptStoreFixtureV1({ harness: closed }), 'CANDIDATE_STORE_FIXTURE_AUTH_EXPIRED'); + + const reused = createCandidateAttemptStoreFixtureHarnessV1(); + const fixture = provisionCandidateAttemptStoreFixtureV1({ harness: reused }); + expectCode(() => provisionCandidateAttemptStoreFixtureV1({ harness: reused }), 'CANDIDATE_STORE_FIXTURE_AUTH_REUSED'); + expectCode(() => provisionCandidateAttemptStoreFixtureV1({ harness: reused, root: '/tmp/not-allowed' }), 'CANDIDATE_STORE_FIXTURE_INPUT_INVALID'); + closeCandidateAttemptStoreFixtureV1({ fixture }); + + for (const [kind, code] of [ + ['nonempty', 'CANDIDATE_STORE_FIXTURE_NONEMPTY'], + ['registered-relationship', 'CANDIDATE_STORE_REGISTERED_TARGET_FORBIDDEN'], + ]) { + const harness = createCandidateAttemptStoreFixtureHarnessV1(); + applyCandidateAttemptStoreFixtureTestCorruptionV1({ harness, kind }); + expectCode(() => provisionCandidateAttemptStoreFixtureV1({ harness }), code); + closeCandidateAttemptStoreFixtureHarnessV1({ harness }); + } +}); + +test('SCN-candidate-store-metadata-drift: only enumerated hermetic corruption can invalidate a provisioned fixture', () => { + for (const [kind, code] of [ + ['ddl-drift', 'CANDIDATE_STORE_SCHEMA_DRIFT'], + ['malformed-meta', 'CANDIDATE_STORE_METADATA_INVALID'], + ]) { + const harness = createCandidateAttemptStoreFixtureHarnessV1(); + const fixture = provisionCandidateAttemptStoreFixtureV1({ harness }); + applyCandidateAttemptStoreFixtureTestCorruptionV1({ harness, kind }); + expectCode(() => inspectCandidateAttemptStoreFixtureV1({ fixture }), code); + closeCandidateAttemptStoreFixtureV1({ fixture }); + } + const harness = createCandidateAttemptStoreFixtureHarnessV1(); + expectCode(() => applyCandidateAttemptStoreFixtureTestCorruptionV1({ harness, kind: 'arbitrary-sql' }), 'CANDIDATE_STORE_FIXTURE_INPUT_INVALID'); + closeCandidateAttemptStoreFixtureHarnessV1({ harness }); +});