TASK-f40126ee: registered adoption candidate composition

Prepared without moving any ref. Tree is intentionally byte-for-byte identical to QA-accepted 77122fed while first-parent preserving registered Work/B2 history at 7533d864.
This commit is contained in:
thePR0M3TH3AN committed 2026-10-03 18:22:45 -04:00
commit 08838260ba
15 files changed
+73 -509

No files matched your search

+6 -4
View File
@@ -3206,11 +3206,11 @@ test_integrity_note:
scenarios:
- id: SCN-integration-adoption-lifecycle-revision-cas
given: "A prepared or finalized owner-bound adoption record with a known journal revision"
when: "A caller supplies a stale expectedRecordRevision to finalize or request native qualification"
then: "The operation refuses before private-ref or queue effects; the original refs, journal state, and queue remain unchanged"
when: "A caller supplies a stale or omitted expectedRecordRevision to finalize, reconcile, rollback, or request native qualification"
then: "The operation refuses before private-ref, journal, queue, or audit effects; the original record and refs remain unchanged"
observable_outcomes:
- "ADOPTION_RECORD_REVISION_STALE is returned for stale lifecycle callers"
- "Private candidate/archive refs remain absent before stale finalize and no integration request is created by stale native request"
- "ADOPTION_RECORD_REVISION_STALE is returned for stale or omitted lifecycle callers"
- "Private candidate/archive refs, durable journal record, audit count, and integration queue remain unchanged for every rejected lifecycle call"
determinism_controls:
- "Disposable local Git repository and temporary SQLite-backed control-plane fixture; no network, provider, or live adoption"
anti_cheat_rationale:
@@ -3233,6 +3233,8 @@ test_integrity_note:
observable_outcomes:
- "The replay loser reports the stale journal-revision boundary, not a generic post-state refusal"
- "Exactly one private-ref integration request and requested audit transition exist"
spec_correction_basis:
- "The former ADOPTION_REQUEST_STATE_INVALID replay expectation was wrong: after the serialized winner commits, the loser carries an obsolete journal revision, so revision CAS is the first observable refusal boundary under SCN-integration-adoption-request-replay."
determinism_controls:
- "Two independently opened local API processes over disposable Git and SQLite fixture state"
anti_cheat_rationale:
@@ -1,28 +0,0 @@
// Private init entrypoint. It is never a CLI surface: bootstrap is supplied only on inherited FD3 and acknowledgement only on FD4.
import { closeSync, readSync, writeFileSync } from 'node:fs';
const MAX_BOOTSTRAP_FRAME_BYTES = 65_536;
function readBoundedFrame(fd) {
const chunks = [];
let total = 0;
const buffer = Buffer.allocUnsafe(8_192);
while (true) {
const bytesRead = readSync(fd, buffer, 0, buffer.length, null);
if (bytesRead === 0) break;
total += bytesRead;
if (total > MAX_BOOTSTRAP_FRAME_BYTES) throw new Error('CANDIDATE_FENCE_FRAME_TOO_LARGE');
chunks.push(Buffer.from(buffer.subarray(0, bytesRead)));
}
return Buffer.concat(chunks, total).toString('utf8');
}
export function readPrivateFenceBootstrapV2() {
const frame = readBoundedFrame(3);
const value = JSON.parse(frame);
if (!value?.nonce || !value?.generation) throw new Error('CANDIDATE_FENCE_FRAME_INVALID');
writeFileSync(4, JSON.stringify({ nonce: value.nonce, generation: value.generation }));
closeSync(3);
closeSync(4);
return Object.freeze({ nonce: value.nonce, generation: value.generation, admissionFdsClosed: true });
}
-33
View File
@@ -1,33 +0,0 @@
import { TorchError } from '../kernel/errors.mjs';
function fail(message, code, details) {
throw new TorchError(message, { code, details });
}
/**
* Fence observations are owned by the backend, never submitted by the caller.
* Until the backend has recorded a PID1 namespace identity, FD closure, and
* namespace-wide reaping, every attempt is UNKNOWN. A process-group exit never
* creates TerminalProof.
*/
export function createCandidateExecutionFenceRuntimeV2({ stateForAttempt, backendObservation } = {}) {
if (typeof stateForAttempt !== 'function' || typeof backendObservation !== 'function') throw new TypeError('candidate fence runtime is incomplete');
const closed = new WeakSet();
function close(attempt) {
if (!stateForAttempt(attempt) || closed.has(attempt)) fail('Candidate fence is unavailable', 'CANDIDATE_FENCE_UNAVAILABLE');
closed.add(attempt);
}
function terminal(attempt) {
if (!stateForAttempt(attempt) || !closed.has(attempt)) fail('Candidate fence is unavailable', 'CANDIDATE_FENCE_UNAVAILABLE');
const observed = backendObservation(attempt);
const qualified = observed?.backend === 'private-pid1-namespace'
&& Number.isSafeInteger(observed.namespacePid) && observed.namespacePid > 0
&& typeof observed.namespaceIdentity === 'string' && observed.namespaceIdentity.length > 0
&& observed.admissionFdsClosed === true && observed.descendantsReaped === true && observed.escapedDescendants === false;
return Object.freeze({
schema: 'torch.dev/candidate-terminal-proof/v2alpha1', outcome: qualified ? 'terminal' : 'unknown', terminalProof: qualified,
reason: qualified ? null : 'descendant-closure-unobserved',
});
}
return Object.freeze({ close, terminal });
}
-96
View File
@@ -1,96 +0,0 @@
import { createHash, randomUUID } from 'node:crypto';
import { closeSync, constants, fstatSync, lstatSync, mkdirSync, openSync, readSync, readdirSync, writeSync } from 'node:fs';
import { isAbsolute, join, relative, resolve } from 'node:path';
import { TorchError } from '../kernel/errors.mjs';
export const CANDIDATE_PRODUCT_INPUT_LIMITS_V2 = Object.freeze({ maxRecords: 8192, maxPathUtf8Bytes: 4096, maxFileBytes: 67_108_864, maxTotalBytes: 536_870_912, maxFrameBytes: 1_048_576, chunkBytes: 65_536 });
const fail = (message, code, details) => { throw new TorchError(message, { code, details }); };
const order = (a, b) => Buffer.compare(Buffer.from(a, 'utf8'), Buffer.from(b, 'utf8'));
const bytes = (value) => Buffer.byteLength(value, 'utf8');
function pathOf(value, limits) {
if (typeof value !== 'string' || !value || isAbsolute(value) || value.includes('\\') || value.includes('\0') || bytes(value) > limits.maxPathUtf8Bytes || value.split('/').some((part) => !part || part === '.' || part === '..' || part === '.git')) fail('Candidate snapshot path is invalid', 'CANDIDATE_SNAPSHOT_PATH_INVALID', { path: value });
return value;
}
function normalizeLimits(value = {}) {
if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).some((key) => !Object.hasOwn(CANDIDATE_PRODUCT_INPUT_LIMITS_V2, key))) fail('Candidate snapshot limits are invalid', 'CANDIDATE_SNAPSHOT_LIMIT_INVALID');
const result = {};
for (const [key, maximum] of Object.entries(CANDIDATE_PRODUCT_INPUT_LIMITS_V2)) { const v = value[key] ?? maximum; if (!Number.isInteger(v) || v < 1 || v > maximum) fail('Candidate snapshot limit is invalid', 'CANDIDATE_SNAPSHOT_LIMIT_INVALID', { key, value: v }); result[key] = v; }
return Object.freeze(result);
}
function regular(path) { const stat = lstatSync(path); if (stat.isSymbolicLink()) fail('Candidate snapshot rejects links', 'CANDIDATE_SNAPSHOT_LINK_REJECTED', { path }); if (!stat.isFile() && !stat.isDirectory()) fail('Candidate snapshot rejects special files', 'CANDIDATE_SNAPSHOT_SPECIAL_REJECTED', { path }); return stat; }
function files(root, paths, limits) {
const result = [];
const visit = (rel) => { const absolute = join(root, rel); const stat = regular(absolute); if (stat.isDirectory()) for (const name of readdirSync(absolute).sort(order)) visit(`${rel}/${name}`); else { if (stat.size > limits.maxFileBytes) fail('Candidate snapshot file cap exceeded', 'CANDIDATE_SNAPSHOT_LIMIT_EXCEEDED', { path: rel }); result.push({ path: rel, size: stat.size, executable: Boolean(stat.mode & 0o111) }); } };
for (const path of [...new Set(paths.map((p) => pathOf(p, limits)))].sort(order)) visit(path);
if (!result.length || result.length > limits.maxRecords) fail('Candidate snapshot record cap exceeded', 'CANDIDATE_SNAPSHOT_LIMIT_EXCEEDED');
return result.sort((a, b) => order(a.path, b.path));
}
function copyAndHash(source, destination, expected, limits) {
let inFd; let outFd;
try {
inFd = openSync(source, constants.O_RDONLY | constants.O_NOFOLLOW); const before = fstatSync(inFd);
if (!before.isFile() || before.size !== expected.size || before.size > limits.maxFileBytes) fail('Candidate snapshot source drifted', 'CANDIDATE_SNAPSHOT_DRIFT', { path: expected.path });
outFd = openSync(destination, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, expected.executable ? 0o500 : 0o400);
const hash = createHash('sha256'); const buffer = Buffer.alloc(limits.chunkBytes); let total = 0;
for (;;) { const count = readSync(inFd, buffer, 0, buffer.length, null); if (!count) break; total += count; if (total > limits.maxFileBytes) fail('Candidate snapshot file cap exceeded', 'CANDIDATE_SNAPSHOT_LIMIT_EXCEEDED'); hash.update(buffer.subarray(0, count)); let offset = 0; while (offset < count) offset += writeSync(outFd, buffer, offset, count - offset); }
const after = fstatSync(inFd); if (total !== before.size || after.size !== before.size) fail('Candidate snapshot source changed while read', 'CANDIDATE_SNAPSHOT_DRIFT', { path: expected.path });
return { path: expected.path, bytes: total, sha256: hash.digest('hex'), executable: expected.executable };
} finally { if (inFd !== undefined) closeSync(inFd); if (outFd !== undefined) closeSync(outFd); }
}
function hashRegularFile(path, expected, limits) {
let fd;
try {
fd = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW); const before = fstatSync(fd);
if (!before.isFile() || before.size !== expected.bytes || before.size > limits.maxFileBytes) fail('Candidate snapshot drifted', 'CANDIDATE_SNAPSHOT_DRIFT', { path: expected.path });
const hash = createHash('sha256'); const buffer = Buffer.alloc(limits.chunkBytes); let total = 0;
for (;;) { const count = readSync(fd, buffer, 0, buffer.length, null); if (!count) break; total += count; if (total > limits.maxFileBytes) fail('Candidate snapshot cap exceeded', 'CANDIDATE_SNAPSHOT_LIMIT_EXCEEDED'); hash.update(buffer.subarray(0, count)); }
const after = fstatSync(fd); if (total !== before.size || after.size !== before.size) fail('Candidate snapshot drifted while read', 'CANDIDATE_SNAPSHOT_DRIFT', { path: expected.path });
return { path: expected.path, bytes: total, sha256: hash.digest('hex'), executable: expected.executable };
} finally { if (fd !== undefined) closeSync(fd); }
}
/** Private caller seam: callers obtain inputRoot from the returned opaque snapshot, never from a policy selector. */
function captureCandidateInputSnapshotV2({ sourceRoot, destinationRoot, paths, limits: requestedLimits = {}, id = randomUUID() } = {}) {
const limits = normalizeLimits(requestedLimits); if (typeof sourceRoot !== 'string' || typeof destinationRoot !== 'string' || !Array.isArray(paths)) fail('Candidate snapshot request is invalid', 'CANDIDATE_SNAPSHOT_INPUT_INVALID');
const source = resolve(sourceRoot); const destination = resolve(destinationRoot); if (source === destination || !relative(source, destination).startsWith('..')) fail('Candidate snapshot destination must be outside source', 'CANDIDATE_SNAPSHOT_INPUT_INVALID');
const listed = files(source, paths, limits); mkdirSync(destination, { recursive: false, mode: 0o700 }); let totalBytes = 0; const records = [];
for (const item of listed) { const target = join(destination, item.path); mkdirSync(resolve(target, '..'), { recursive: true, mode: 0o700 }); const record = copyAndHash(join(source, item.path), target, item, limits); totalBytes += record.bytes; if (totalBytes > limits.maxTotalBytes) fail('Candidate snapshot total cap exceeded', 'CANDIDATE_SNAPSHOT_LIMIT_EXCEEDED'); records.push(record); }
const manifest = Object.freeze({ schema: 'torch.dev/candidate-input-manifest/v2alpha1', id, files: Object.freeze(records), totalBytes, digest: createHash('sha256').update(JSON.stringify(records)).digest('hex') });
return Object.freeze({ schema: 'torch.dev/candidate-input-snapshot/v2alpha1', inputRoot: destination, manifest, limits });
}
function verifyCandidateInputSnapshotV2(snapshot = {}) {
if (snapshot?.schema !== 'torch.dev/candidate-input-snapshot/v2alpha1' || !snapshot.manifest?.files || typeof snapshot.inputRoot !== 'string') fail('Candidate snapshot is malformed', 'CANDIDATE_SNAPSHOT_INVALID');
const listed = files(snapshot.inputRoot, snapshot.manifest.files.map((file) => file.path), snapshot.limits);
const observed = listed.map((file) => hashRegularFile(join(snapshot.inputRoot, file.path), { ...file, bytes: file.size }, snapshot.limits));
if (JSON.stringify(observed) !== JSON.stringify(snapshot.manifest.files)
|| createHash('sha256').update(JSON.stringify(observed)).digest('hex') !== snapshot.manifest.digest) {
fail('Candidate snapshot content drifted', 'CANDIDATE_SNAPSHOT_DRIFT');
}
return Object.freeze({ verified: true, digest: snapshot.manifest.digest, files: observed.length, totalBytes: snapshot.manifest.totalBytes });
}
/**
* The public boundary accepts only a service-issued attempt. Source roots,
* paths, destinations, and S limits live in the service's private state.
*/
export function createCandidateInputSnapshotRuntimeV2({ stateForAttempt } = {}) {
if (typeof stateForAttempt !== 'function') throw new TypeError('stateForAttempt is required');
const snapshots = new WeakMap();
function capture(attempt) {
const state = stateForAttempt(attempt);
if (!state?.input) fail('Candidate attempt has no frozen input authority', 'CANDIDATE_SNAPSHOT_ADMISSION_REQUIRED');
const snapshot = captureCandidateInputSnapshotV2(state.input);
snapshots.set(attempt, snapshot);
return Object.freeze({ digest: snapshot.manifest.digest, files: snapshot.manifest.files.length, totalBytes: snapshot.manifest.totalBytes });
}
function verify(attempt) {
const snapshot = snapshots.get(attempt);
if (!snapshot) fail('Candidate snapshot is unavailable', 'CANDIDATE_SNAPSHOT_ADMISSION_REQUIRED');
return verifyCandidateInputSnapshotV2(snapshot);
}
function cwd(attempt) {
const snapshot = snapshots.get(attempt);
if (!snapshot) fail('Candidate snapshot is unavailable', 'CANDIDATE_SNAPSHOT_ADMISSION_REQUIRED');
return snapshot.inputRoot;
}
return Object.freeze({ capture, verify, cwd });
}
-81
View File
@@ -1,81 +0,0 @@
import { createHash, randomBytes } from 'node:crypto';
import { TorchError } from '../kernel/errors.mjs';
const ADMISSION_SCHEMA = 'torch.dev/candidate-source-parent-admission/v2alpha1';
const ACK_SCHEMA = 'torch.dev/candidate-source-parent-binding/v2alpha1';
const SHA256 = /^[a-f0-9]{64}$/;
const MAX_FRAME_BYTES = 64 * 1024;
function fail(message, code, details) {
throw new TorchError(message, { code, details });
}
function digest(bytes) {
return createHash('sha256').update(bytes).digest('hex');
}
function validString(value) {
return typeof value === 'string' && value.length > 0;
}
/**
* Service-only closure factory. It has no public issuer that accepts caller
* project/check/run tuples: CheckService supplies an opaque registered-plan
* handle to stateForPlan and this module serializes only that captured state.
*/
export function createCandidateSourceBootstrapRuntimeV2({ stateForPlan, now = () => new Date() } = {}) {
if (typeof stateForPlan !== 'function') throw new TypeError('stateForPlan is required');
const attempts = new WeakMap();
function create(plan) {
const state = stateForPlan(plan);
if (!state || typeof state !== 'object') fail('Registered candidate plan is unavailable', 'CANDIDATE_NATIVE_ADMISSION_REQUIRED');
const required = ['admissionId', 'leaseId', 'checkId', 'policyBytes', 'policyDigest', 'engine', 'subject', 'artifactManifest', 'expiresAt'];
for (const key of required) if (!Object.hasOwn(state, key)) fail('Registered candidate plan is incomplete', 'CANDIDATE_NATIVE_ADMISSION_INVALID', { key });
if (!Buffer.isBuffer(state.policyBytes) || state.policyBytes.length === 0 || state.policyBytes.length > 1024 * 1024
|| !SHA256.test(state.policyDigest) || digest(state.policyBytes) !== state.policyDigest
|| !validString(state.admissionId) || !validString(state.leaseId) || !validString(state.checkId)
|| !Number.isSafeInteger(state.runGeneration) || !Number.isSafeInteger(state.guardGeneration)
|| Number.isNaN(Date.parse(state.expiresAt))) fail('Registered candidate plan is invalid', 'CANDIDATE_NATIVE_ADMISSION_INVALID');
const handle = Object.freeze({});
attempts.set(handle, { state, used: false, closed: false, nonce: randomBytes(32).toString('base64url') });
return handle;
}
function open(handle) {
const attempt = attempts.get(handle);
if (!attempt || attempt.used || attempt.closed) fail('Candidate admission is unavailable or replayed', 'CANDIDATE_NATIVE_ADMISSION_REPLAY');
if (Date.parse(attempt.state.expiresAt) <= now().getTime()) {
attempt.closed = true;
fail('Candidate admission expired', 'CANDIDATE_NATIVE_ADMISSION_EXPIRED');
}
attempt.used = true;
const { state } = attempt;
const frame = Buffer.from(JSON.stringify({
schema: ADMISSION_SCHEMA, version: 2, admissionId: state.admissionId, leaseId: state.leaseId,
checkId: state.checkId, runGeneration: state.runGeneration, guardGeneration: state.guardGeneration,
policyBytesBase64: state.policyBytes.toString('base64'), policyDigest: state.policyDigest,
engine: state.engine, subject: state.subject, artifactManifest: state.artifactManifest,
receiptAdapterAdmission: null,
}), 'utf8');
if (frame.length > MAX_FRAME_BYTES) fail('Candidate parent admission frame exceeds its bound', 'CANDIDATE_NATIVE_ADMISSION_INVALID');
return Object.freeze({ frame, acknowledgement: Buffer.from(`${ACK_SCHEMA}\n${state.admissionId}\n${state.policyDigest}\n`, 'utf8'), nonce: attempt.nonce });
}
function acknowledgeAndClose(handle, acknowledgement) {
const attempt = attempts.get(handle);
if (!attempt || !attempt.used || attempt.closed || !Buffer.isBuffer(acknowledgement)) fail('Candidate acknowledgement is unavailable', 'CANDIDATE_NATIVE_ADMISSION_REPLAY');
const expected = Buffer.from(`${ACK_SCHEMA}\n${attempt.state.admissionId}\n${attempt.state.policyDigest}\n`, 'utf8');
if (!acknowledgement.equals(expected)) fail('Candidate parent acknowledgement mismatches admission', 'CANDIDATE_PARENT_ACK_MISMATCH');
attempt.closed = true;
return Object.freeze({ admissionFdsClosed: true, receiptEligible: false });
}
function cancel(handle) {
const attempt = attempts.get(handle);
if (!attempt || attempt.used || attempt.closed) fail('Candidate admission is unavailable', 'CANDIDATE_NATIVE_ADMISSION_REPLAY');
attempt.closed = true;
}
return Object.freeze({ create, open, acknowledgeAndClose, cancel });
}
-61
View File
@@ -1,61 +0,0 @@
import { spawnSync } from 'node:child_process';
import { TorchError } from '../kernel/errors.mjs';
export const CANDIDATE_EXECUTION_LIMITS_V2 = Object.freeze({ timeoutMs: 300000, maxOutputBytes: 1048576, maxArgs: 64, maxArgBytes: 4096 });
function fail(message, code, details) {
throw new TorchError(message, { code, details });
}
function validRuntime(state) {
const runtime = state?.runtime;
if (!runtime || typeof runtime.command !== 'string' || !runtime.command.startsWith('/') || !Array.isArray(runtime.args)
|| !runtime.args.every((arg) => typeof arg === 'string' && Buffer.byteLength(arg, 'utf8') <= CANDIDATE_EXECUTION_LIMITS_V2.maxArgBytes)
|| runtime.args.length > CANDIDATE_EXECUTION_LIMITS_V2.maxArgs
|| !runtime.environment || Object.keys(runtime.environment).some((key) => ['PATH', 'HOME', 'NODE_PATH', 'npm_config_cache'].includes(key))) {
fail('Candidate fixed runtime is invalid', 'CANDIDATE_EXECUTION_RUNTIME_INVALID');
}
return runtime;
}
/**
* Runs a fixed, CheckService-derived E binding. `run` takes only an opaque
* attempt; command, arguments, environment, executor, cwd and limits cannot
* be selected by callers. It is raw terminal evidence, never a receipt PASS.
*/
export function createCandidateSourceExecutionRuntimeV2({ stateForAttempt, snapshotRuntime } = {}) {
if (typeof stateForAttempt !== 'function' || !snapshotRuntime) throw new TypeError('candidate execution runtime is incomplete');
const results = new WeakMap();
function run(attempt) {
const state = stateForAttempt(attempt);
const runtime = validRuntime(state);
snapshotRuntime.verify(attempt);
const cwd = snapshotRuntime.cwd(attempt);
let raw;
try {
raw = spawnSync(runtime.command, runtime.args, {
cwd, env: Object.freeze({ ...runtime.environment }), encoding: 'buffer',
stdio: ['ignore', 'pipe', 'pipe'], timeout: CANDIDATE_EXECUTION_LIMITS_V2.timeoutMs,
maxBuffer: CANDIDATE_EXECUTION_LIMITS_V2.maxOutputBytes, killSignal: 'SIGTERM',
});
} catch (error) { raw = { status: null, error }; }
const stdout = Buffer.from(raw?.stdout ?? '');
const stderr = Buffer.from(raw?.stderr ?? '');
const overflow = stdout.length > CANDIDATE_EXECUTION_LIMITS_V2.maxOutputBytes || stderr.length > CANDIDATE_EXECUTION_LIMITS_V2.maxOutputBytes || raw?.error?.code === 'ENOBUFS';
const timeout = raw?.error?.code === 'ETIMEDOUT' || raw?.timedOut === true;
const observation = Object.freeze({
schema: 'torch.dev/candidate-source-execution/v2alpha1',
terminal: Object.freeze({ kind: timeout ? 'timeout' : overflow ? 'overflow' : raw?.signal ? 'signal' : raw?.error ? 'error' : 'exit', exitStatus: Number.isInteger(raw?.status) ? raw.status : null, signal: raw?.signal ?? null, overflow, timeout, success: !timeout && !overflow && !raw?.signal && !raw?.error && raw?.status === 0 }),
output: Object.freeze({ stdout: stdout.subarray(0, CANDIDATE_EXECUTION_LIMITS_V2.maxOutputBytes), stderr: stderr.subarray(0, CANDIDATE_EXECUTION_LIMITS_V2.maxOutputBytes) }),
});
snapshotRuntime.verify(attempt);
results.set(attempt, observation);
return observation;
}
function observation(attempt) {
const value = results.get(attempt);
if (!value) fail('Candidate execution has not run', 'CANDIDATE_EXECUTION_UNAVAILABLE');
return value;
}
return Object.freeze({ run, observation });
}
-15
View File
@@ -84,19 +84,6 @@ function captureGeneratedArtifacts({ generatedDirectory, commit, checkId, defini
};
}
// B2 admission boundary only. Kernel owns policy parsing/registration and the parent;
// this service must never synthesize either from cwd, environment, or caller JSON.
function assertCandidateNativeAdmissionAvailable(definition) {
if (!Object.hasOwn(definition ?? {}, 'candidate_execution_policy')) return;
if (!definition.candidate_execution_policy) {
throw new TorchError('Candidate execution policy is not registered', { code: 'CANDIDATE_SNAPSHOT_POLICY_UNDECLARED' });
}
// A registered policy alone is not the genuine parent issuer or receipt adapter.
throw new TorchError('Candidate native parent bootstrap is unavailable', {
code: 'CANDIDATE_PARENT_NATIVE_BOOTSTRAP_UNAVAILABLE',
});
}
export class CheckService {
constructor({
repositoryRoot, controlPlane, resourceService = null,
@@ -343,8 +330,6 @@ export class CheckService {
if (missing.length) throw new TorchError('Prepared check requires resource leases', {
code: 'CHECK_BLOCKED', details: missing.map((resourceId) => ({ code: 'RESOURCE_LEASE_REQUIRED', resourceId })),
});
// Deliberately before snapshot verification, state mutation, artifacts, or child spawn.
assertCandidateNativeAdmissionAvailable(currentDefinition);
verifyCheckSnapshot(item.snapshot, { stateRoot: this.stateRoot });
const claimed = this.controlPlane.database.prepare(`UPDATE prepared_checks SET state = 'running', runner_json = ?
WHERE id = ? AND project_id = ? AND area_id = ? AND state = 'prepared'`)
+1 -78
View File
@@ -6,10 +6,6 @@ import { readInstallManifest } from '../kernel/install.mjs';
import { loadFleetDefinition } from '../kernel/worktrees.mjs';
const GUARD_TYPES = Object.freeze(['check', 'measurement', 'pin']);
const READ_ONLY_GUARD_COLUMNS = Object.freeze([
'id', 'project_id', 'area_id', 'guard_type', 'reason', 'created_at', 'released_at',
]);
const READ_ONLY_GUARD_INDEX = 'one_open_guard_per_type';
function git(root, args, { allowFailure = false } = {}) {
const result = spawnSync('git', ['-C', root, ...args], { encoding: 'utf8' });
@@ -37,61 +33,6 @@ export function initializeWorktreeGuards(database) {
`);
}
function unavailableGuardSchema(details = null) {
throw new TorchError('Convergence guard coverage cannot be established', {
code: 'CONVERGENCE_GUARDS_UNAVAILABLE', details,
});
}
function verifyReadableGuardSchema(database) {
let columns;
let indexes;
let indexColumns;
let indexSql;
try {
columns = database.prepare('PRAGMA table_info(worktree_guards)').all();
indexes = database.prepare('PRAGMA index_list(worktree_guards)').all();
indexColumns = database.prepare(`PRAGMA index_info(${READ_ONLY_GUARD_INDEX})`).all();
indexSql = database.prepare(`
SELECT sql FROM sqlite_master WHERE type = 'index' AND name = ?
`).get(READ_ONLY_GUARD_INDEX)?.sql ?? null;
} catch (error) {
unavailableGuardSchema({ cause: error.message });
}
const actualColumns = columns.map((column) => column.name);
const expectedColumns = [...READ_ONLY_GUARD_COLUMNS];
const index = indexes.find((candidate) => candidate.name === READ_ONLY_GUARD_INDEX);
const actualIndexColumns = indexColumns.map((column) => column.name);
const normalizedIndexSql = typeof indexSql === 'string'
? indexSql.replaceAll(/\s+/g, ' ').trim().toLowerCase()
: null;
const requiredIndexSql = 'create unique index one_open_guard_per_type on worktree_guards(area_id, guard_type) where released_at is null';
if (
actualColumns.length !== expectedColumns.length
|| actualColumns.some((column, index) => column !== expectedColumns[index])
|| !index
|| Number(index.unique) !== 1
|| Number(index.partial) !== 1
|| actualIndexColumns.length !== 2
|| actualIndexColumns[0] !== 'area_id'
|| actualIndexColumns[1] !== 'guard_type'
|| normalizedIndexSql !== requiredIndexSql
) {
unavailableGuardSchema({
expectedColumns,
actualColumns,
requiredIndex: READ_ONLY_GUARD_INDEX,
actualIndexes: indexes.map((candidate) => ({
name: candidate.name, unique: candidate.unique, partial: candidate.partial,
})),
actualIndexColumns,
indexSql,
});
}
}
export function beginWorktreeGuard(controlPlane, {
areaId, type, reason, clock = () => new Date(), idFactory = randomUUID,
} = {}) {
@@ -148,7 +89,6 @@ export class ConvergenceService {
this.controlPlane = controlPlane;
this.clock = clock;
this.idFactory = idFactory;
this.readOnly = controlPlane?.readOnly === true;
const { config } = loadFleetDefinition(repositoryRoot);
this.targetBranch = config.project.main_branch;
this.policy = config.synchronization ?? {};
@@ -156,24 +96,11 @@ export class ConvergenceService {
this.worktrees = new Map((manifest.external ?? [])
.filter((entry) => entry.type === 'worktree')
.map((entry) => [entry.area, entry]));
if (!this.readOnly) initializeWorktreeGuards(controlPlane.database);
}
assertWritable() {
if (this.readOnly) {
throw new TorchError('Read-only convergence instances cannot mutate guards or worktrees', {
code: 'CONVERGENCE_READ_ONLY',
});
}
}
verifyGuardSchema() {
verifyReadableGuardSchema(this.controlPlane.database);
initializeWorktreeGuards(controlPlane.database);
}
guards(areaId) {
const area = this.controlPlane.assertIdentity(areaId);
this.verifyGuardSchema();
return this.controlPlane.database.prepare(`
SELECT id, area_id AS areaId, guard_type AS type, reason, created_at AS createdAt
FROM worktree_guards WHERE area_id = ? AND released_at IS NULL ORDER BY created_at, id
@@ -181,20 +108,17 @@ export class ConvergenceService {
}
hold({ areaId, type, reason } = {}) {
this.assertWritable();
return beginWorktreeGuard(this.controlPlane, {
areaId, type, reason, clock: this.clock, idFactory: this.idFactory,
});
}
release({ areaId, type } = {}) {
this.assertWritable();
return endWorktreeGuard(this.controlPlane, { areaId, type, clock: this.clock });
}
plan({ areaId } = {}) {
const area = this.controlPlane.assertIdentity(areaId);
this.verifyGuardSchema();
const worktree = this.worktrees.get(area);
if (!worktree) throw new TorchError(`No managed worktree for ${area}`, { code: 'WORKTREE_MISSING' });
const blockers = [];
@@ -221,7 +145,6 @@ export class ConvergenceService {
}
converge({ areaId } = {}) {
this.assertWritable();
const plan = this.plan({ areaId });
if (!plan.canProceed) throw new TorchError('Worktree convergence is blocked', { code: 'CONVERGENCE_BLOCKED', details: plan.blockers });
if (plan.upToDate) return { ...plan, changed: false };
@@ -1,13 +0,0 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { createCandidateExecutionFenceRuntimeV2 } from '../../src/checks/candidate-execution-fence.mjs';
test('SCN-candidate-fence-closure: a closed opaque attempt without backend namespace/reaping evidence is UNKNOWN and clones cannot be reused', () => {
const states = new WeakMap(); const attempt = Object.freeze({}); states.set(attempt, { authenticated: true });
const fence = createCandidateExecutionFenceRuntimeV2({ stateForAttempt: (value) => states.get(value), backendObservation: () => null });
assert.throws(() => fence.close({}), { code: 'CANDIDATE_FENCE_UNAVAILABLE' });
fence.close(attempt); const terminal = fence.terminal(attempt);
assert.equal(terminal.outcome, 'unknown'); assert.equal(terminal.terminalProof, false);
assert.throws(() => fence.terminal({ ...attempt }), { code: 'CANDIDATE_FENCE_UNAVAILABLE' });
assert.throws(() => fence.close(attempt), { code: 'CANDIDATE_FENCE_UNAVAILABLE' });
});
@@ -1,28 +0,0 @@
import assert from 'node:assert/strict';
import { chmodSync, mkdirSync, mkdtempSync, realpathSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { createCandidateInputSnapshotRuntimeV2 } from '../../src/checks/candidate-input-snapshot.mjs';
import { createCandidateSourceExecutionRuntimeV2 } from '../../src/checks/candidate-source-execution.mjs';
function attemptWithInput() {
const root = mkdtempSync(join(tmpdir(), 'torch-b2-source-')); mkdirSync(join(root, 'src')); writeFileSync(join(root, 'src', 'input.txt'), 'captured');
const states = new WeakMap(); const attempt = Object.freeze({});
states.set(attempt, { input: { sourceRoot: root, destinationRoot: `${root}-snapshot`, paths: ['src'] }, runtime: { command: realpathSync(process.execPath), args: ['-e', 'process.stdout.write(require("node:fs").readFileSync("src/input.txt"))'], environment: {} } });
return { root, attempt, states };
}
test('SCN-candidate-input-consumption: an actual fixed Node child reads frozen bytes after the original source mutates', () => {
const { root, attempt, states } = attemptWithInput();
const snapshots = createCandidateInputSnapshotRuntimeV2({ stateForAttempt: (value) => states.get(value) });
snapshots.capture(attempt); writeFileSync(join(root, 'src', 'input.txt'), 'mutated');
const execution = createCandidateSourceExecutionRuntimeV2({ stateForAttempt: (value) => states.get(value), snapshotRuntime: snapshots }).run(attempt);
assert.equal(execution.terminal.success, true); assert.equal(execution.output.stdout.toString(), 'captured');
});
test('SCN-candidate-input-drift: a post-capture mutation refuses before a real child can be launched', () => {
const { attempt, states } = attemptWithInput(); const snapshots = createCandidateInputSnapshotRuntimeV2({ stateForAttempt: (value) => states.get(value) });
snapshots.capture(attempt); const file = join(snapshots.cwd(attempt), 'src', 'input.txt'); chmodSync(file, 0o600); writeFileSync(file, 'drift');
assert.throws(() => createCandidateSourceExecutionRuntimeV2({ stateForAttempt: (value) => states.get(value), snapshotRuntime: snapshots }).run(attempt), { code: 'CANDIDATE_SNAPSHOT_DRIFT' });
});
@@ -1,14 +0,0 @@
import assert from 'node:assert/strict';
import { mkdtempSync, symlinkSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { createCandidateInputSnapshotRuntimeV2 } from '../../src/checks/candidate-input-snapshot.mjs';
test('SCN-candidate-snapshot-policy: an opaque service attempt still refuses product links before capture', () => {
const root = mkdtempSync(join(tmpdir(), 'torch-b2-policy-')); writeFileSync(join(root, 'file'), 'x'); symlinkSync('file', join(root, 'link'));
const states = new WeakMap(); const attempt = Object.freeze({}); states.set(attempt, { input: { sourceRoot: root, destinationRoot: `${root}-snapshot`, paths: ['link'] } });
const snapshots = createCandidateInputSnapshotRuntimeV2({ stateForAttempt: (value) => states.get(value) });
assert.throws(() => snapshots.capture(attempt), { code: 'CANDIDATE_SNAPSHOT_LINK_REJECTED' });
assert.throws(() => snapshots.capture(Object.freeze({})), { code: 'CANDIDATE_SNAPSHOT_ADMISSION_REQUIRED' });
});
@@ -1,28 +0,0 @@
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import test from 'node:test';
import { createCandidateSourceBootstrapRuntimeV2 } from '../../src/checks/candidate-source-bootstrap.mjs';
function planState(expiresAt = '2030-01-01T00:00:00.000Z') {
const policyBytes = Buffer.from('policy\n');
return { admissionId: 'admission-1', leaseId: 'lease-1', checkId: 'test', runGeneration: 1, guardGeneration: 1, policyBytes, policyDigest: createHash('sha256').update(policyBytes).digest('hex'), engine: { pre: {}, post: {} }, subject: {}, artifactManifest: { schema: 'torch.dev/artifact-manifest/v1alpha1', manifestSha256: 'a'.repeat(64) }, expiresAt };
}
test('SCN-candidate-bootstrap-one-shot: only a service-issued opaque plan opens once and its observed FD acknowledgement closes it', () => {
const states = new WeakMap(); const plan = Object.freeze({}); states.set(plan, planState());
const runtime = createCandidateSourceBootstrapRuntimeV2({ stateForPlan: (value) => states.get(value), now: () => new Date('2029-01-01T00:00:00.000Z') });
assert.throws(() => runtime.create(Object.freeze({})), { code: 'CANDIDATE_NATIVE_ADMISSION_REQUIRED' });
const handle = runtime.create(plan); const clone = { ...handle };
assert.throws(() => runtime.open(clone), { code: 'CANDIDATE_NATIVE_ADMISSION_REPLAY' });
const channel = runtime.open(handle);
assert.equal(JSON.parse(channel.frame).receiptAdapterAdmission, null);
runtime.acknowledgeAndClose(handle, channel.acknowledgement);
assert.throws(() => runtime.open(handle), { code: 'CANDIDATE_NATIVE_ADMISSION_REPLAY' });
assert.throws(() => runtime.acknowledgeAndClose(handle, channel.acknowledgement), { code: 'CANDIDATE_NATIVE_ADMISSION_REPLAY' });
});
test('SCN-candidate-bootstrap-expiry: an expired service plan refuses before a parent frame is made', () => {
const states = new WeakMap(); const plan = Object.freeze({}); states.set(plan, planState('2020-01-01T00:00:00.000Z'));
const runtime = createCandidateSourceBootstrapRuntimeV2({ stateForPlan: (value) => states.get(value) });
assert.throws(() => runtime.open(runtime.create(plan)), { code: 'CANDIDATE_NATIVE_ADMISSION_EXPIRED' });
});
@@ -1,16 +0,0 @@
import assert from 'node:assert/strict';
import { mkdtempSync, realpathSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { createCandidateInputSnapshotRuntimeV2 } from '../../src/checks/candidate-input-snapshot.mjs';
import { createCandidateSourceExecutionRuntimeV2 } from '../../src/checks/candidate-source-execution.mjs';
test('SCN-candidate-execution-boundary: only fixed E is run and actual zero-exit output overflow is not success', () => {
const root = mkdtempSync(join(tmpdir(), 'torch-b2-execution-')); writeFileSync(join(root, 'input'), 'x');
const states = new WeakMap(); const attempt = Object.freeze({});
states.set(attempt, { input: { sourceRoot: root, destinationRoot: `${root}-snapshot`, paths: ['input'] }, runtime: { command: realpathSync(process.execPath), args: ['-e', 'process.stdout.write("x".repeat(1048577))'], environment: {} } });
const snapshots = createCandidateInputSnapshotRuntimeV2({ stateForAttempt: (value) => states.get(value) }); snapshots.capture(attempt);
const result = createCandidateSourceExecutionRuntimeV2({ stateForAttempt: (value) => states.get(value), snapshotRuntime: snapshots }).run(attempt);
assert.equal(result.terminal.overflow, true); assert.equal(result.terminal.success, false);
});
@@ -1,14 +0,0 @@
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import test from 'node:test';
import { createCandidateSourceBootstrapRuntimeV2 } from '../../src/checks/candidate-source-bootstrap.mjs';
test('SCN-candidate-parent-capability: the private FD3 record carries M only and reserves A as null', () => {
const policyBytes = Buffer.from('policy\n'); const states = new WeakMap(); const plan = Object.freeze({});
states.set(plan, { admissionId: 'admission-2', leaseId: 'lease-2', checkId: 'test', runGeneration: 1, guardGeneration: 2, policyBytes, policyDigest: createHash('sha256').update(policyBytes).digest('hex'), engine: { pre: {}, post: {} }, subject: {}, artifactManifest: { schema: 'torch.dev/artifact-manifest/v1alpha1', manifestSha256: 'a'.repeat(64) }, expiresAt: '2030-01-01T00:00:00.000Z' });
const runtime = createCandidateSourceBootstrapRuntimeV2({ stateForPlan: (value) => states.get(value), now: () => new Date('2029-01-01T00:00:00.000Z') });
const frame = JSON.parse(runtime.open(runtime.create(plan)).frame);
for (const forbidden of ['root', 'cwd', 'environment', 'writer', 'adapter', 'receipt', 'command', 'executor']) assert.equal(Object.hasOwn(frame, forbidden), false);
assert.equal(frame.receiptAdapterAdmission, null);
assert.deepEqual(Object.keys(frame.artifactManifest).sort(), ['manifestSha256', 'schema']);
});
+66
View File
@@ -139,6 +139,24 @@ function blockedCodes(error) {
return error.details.map((blocker) => blocker.code);
}
function lifecycleBoundary(context, adoptionId) {
const record = context.service.getPreparedAdoption(adoptionId);
return {
record,
refs: context.service.adoption.refAdapter.readRefs([
record.expectedOldRef, record.candidateRef, record.archiveRef,
]),
queue: context.service.list(),
auditCount: context.control.database.prepare(`SELECT COUNT(*) AS count FROM audit_events
WHERE project_id = ? AND entity_type = 'integration-adoption' AND entity_id = ?`)
.get(context.control.projectId, adoptionId).count,
};
}
function assertLifecycleBoundaryUnchanged(context, adoptionId, before) {
assert.deepEqual(lifecycleBoundary(context, adoptionId), before);
}
test('SCN-integration-adoption-private-ref-cas: a real temporary Git transaction atomically creates private archive and candidate refs, and stale expected refs refuse', () => {
const context = fixture('torch-adoption-cas');
const adoptionId = 'fixture-adoption';
@@ -185,6 +203,54 @@ test('SCN-integration-adoption-journal-and-binding: a duplicate preparation cann
context.control.close();
});
test('SCN-integration-adoption-lifecycle-revision-cas: stale or omitted revisions for every lifecycle action refuse before refs, journal, queue, or audit effects', () => {
const cases = [
{
action: 'finalize',
setup: (context, adoptionId) => prepare(context, adoptionId),
invoke: (context, input) => context.service.finalizeAdoption(input),
},
{
action: 'reconcile',
setup: (context, adoptionId) => prepare(context, adoptionId),
invoke: (context, input) => context.service.reconcileAdoption(input),
},
{
action: 'rollback',
setup: (context, adoptionId) => {
prepare(context, adoptionId);
return context.service.finalizeAdoption(lifecycleInput(context, 'finalize', adoptionId));
},
invoke: (context, input) => context.service.rollbackAdoption(input),
},
{
action: 'request',
setup: (context, adoptionId) => {
prepare(context, adoptionId);
return context.service.finalizeAdoption(lifecycleInput(context, 'finalize', adoptionId));
},
invoke: (context, input) => context.service.requestAdoptedCandidate(input),
},
];
for (const { action, setup, invoke } of cases) {
const context = fixture(`torch-adoption-${action}-revision-boundary`);
const adoptionId = 'fixture-adoption';
setup(context, adoptionId);
for (const variant of ['omitted', 'stale']) {
const current = lifecycleInput(context, action, adoptionId);
const input = variant === 'omitted'
? (({ expectedRecordRevision: _expectedRecordRevision, ...withoutRevision }) => withoutRevision)(current)
: { ...current, expectedRecordRevision: current.expectedRecordRevision + 1 };
const before = lifecycleBoundary(context, adoptionId);
assert.throws(() => invoke(context, input), (error) => error.code === 'ADOPTION_RECORD_REVISION_STALE',
`${action} must reject a ${variant} lifecycle revision`);
assertLifecycleBoundaryUnchanged(context, adoptionId, before);
}
context.control.close();
}
});
test('SCN-integration-adoption-finalize-recovery: a crash after real ref CAS but before the journal transition reconciles once and never duplicates refs', () => {
const context = fixture('torch-adoption-finalize-recovery');
const adoptionId = 'fixture-adoption';