Merge canonical for TASK-pilot-cli-suite-timeout

This commit is contained in:
thePR0M3TH3AN committed 2026-10-07 02:17:32 -04:00
commit 0c8db11bcc
41 files changed
+4544 -24

No files matched your search

+12
View File
@@ -6,6 +6,18 @@ import '../../site/live-refresh.js';
const project = (snapshot) => globalThis.TorchAttentionProjection.groups(snapshot);
test('SCN-console-continuation-stop: exhausted budget is an owner policy decision; no-progress remains manager-owned', () => {
const groups = project({ continuation: { available: true, stopReason: 'daily-turn-cap', attempts: 12,
maxTurnsPerDay: 12, day: '2026-10-03', held: [{ areaId: 'owner-console' }] } });
assert.equal(groups.owner.length, 1);
assert.match(groups.owner[0].detail, /explicitly change the limit/);
assert.equal(groups.owner[0].decisionApprovalId, null, 'No fake approval or automatic budget expansion');
assert.equal(groups.fleet.length, 1);
assert.equal(groups.fleet[0].owner, 'session-manager');
assert.equal(groups.fleet[0].requestOwner, 'session-manager');
assert.equal(project({ continuation: { available: true, stopReason: 'paused', held: [] } }).owner.length, 0);
});
test('SCN-console-attention-ownership: only owner-addressed pending decisions enter Waiting on you', () => {
const groups = project({
agents: [
+420
View File
@@ -0,0 +1,420 @@
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import { execFileSync, spawn } from 'node:child_process';
import { mkdtempSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { basename, join } from 'node:path';
import test from 'node:test';
import { openControlPlane } from '../../src/control-plane/service.mjs';
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
import { proposeDomains } from '../../src/kernel/domains.mjs';
import { inspectRepository } from '../../src/kernel/git.mjs';
import { installProject } from '../../src/kernel/install.mjs';
import { IntegrationService } from '../../src/integration/service.mjs';
const sha = value => execFileSync('git', ['-C', value, 'rev-parse', 'HEAD'], { encoding: 'utf8' }).trim();
const digest = value => createHash('sha256').update(JSON.stringify(value)).digest('hex');
function fixture(name) {
const root = mkdtempSync(join(tmpdir(), `${name}-`));
execFileSync('git', ['init', '-b', 'main', root]);
execFileSync('git', ['-C', root, 'config', 'user.email', '[email protected]']);
execFileSync('git', ['-C', root, 'config', 'user.name', 'TORCH Test']);
writeFileSync(join(root, 'package.json'), `${JSON.stringify({ name, scripts: {} })}\n`);
writeFileSync(join(root, 'app.mjs'), 'export const value = 1;\n');
execFileSync('git', ['-C', root, 'add', '.']);
execFileSync('git', ['-C', root, 'commit', '-m', 'fixture base']);
const repository = inspectRepository(root);
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
proposal.domains.push({
id: 'review-area', title: 'Review Area', kind: 'development',
scope: ['review fixtures'], not_scope: ['application source'], owned_paths: ['review/**'],
shared_paths: [], neighbours: [], required_checks: [], resources: [], runtime: 'claude', evidence: ['app.mjs'],
});
proposal.checks = [];
proposal.review = { status: 'approved', reviewedAt: '2026-10-03T00:00:00.000Z', reviewedBy: 'fixture-owner', notes: [] };
const env = { ...process.env, XDG_DATA_HOME: join(tmpdir(), `${basename(root)}-state`) };
installProject({ repository, proposal, env, projectId: name });
execFileSync('git', ['-C', root, 'add', '.torch']);
execFileSync('git', ['-C', root, 'commit', '-m', 'install fixture control plane']);
const base = sha(root);
execFileSync('git', ['-C', root, 'checkout', '-b', 'candidate']);
writeFileSync(join(root, 'candidate.mjs'), 'export const candidate = true;\n');
execFileSync('git', ['-C', root, 'add', 'candidate.mjs']);
execFileSync('git', ['-C', root, 'commit', '-m', 'candidate contribution']);
const candidate = sha(root);
execFileSync('git', ['-C', root, 'checkout', 'main']);
const control = openControlPlane({ repositoryRoot: root, env });
const service = new IntegrationService({ repositoryRoot: root, controlPlane: control, checkService: { exactPasses: () => false } });
const contributor = proposal.domains[0].id;
return { root, env, control, service, contributor, destination: 'review-area', base, candidate };
}
function concurrentAdoptedRequest(context, requestInput) {
const childSource = `
import { pathToFileURL } from 'node:url';
import { resolve } from 'node:path';
const { repositoryRoot, stateRoot, requestInput } = JSON.parse(process.argv[1]);
const sourceRoot = process.cwd();
const { openControlPlane } = await import(pathToFileURL(resolve(sourceRoot, 'src/control-plane/service.mjs')).href);
const { IntegrationService } = await import(pathToFileURL(resolve(sourceRoot, 'src/integration/service.mjs')).href);
const control = openControlPlane({ repositoryRoot, env: { ...process.env, XDG_DATA_HOME: stateRoot } });
const service = new IntegrationService({ repositoryRoot, controlPlane: control, checkService: { exactPasses: () => false } });
try {
const result = service.requestAdoptedCandidate(requestInput);
console.log(JSON.stringify({ outcome: 'requested', integrationRequestId: result.integrationRequest.id }));
} catch (error) {
console.log(JSON.stringify({ outcome: 'refused', code: error.code ?? null }));
} finally {
control.close();
}
`;
const encoded = JSON.stringify({ repositoryRoot: context.root, stateRoot: context.env.XDG_DATA_HOME, requestInput });
return new Promise((resolve, reject) => {
const child = spawn(process.execPath, ['--input-type=module', '-e', childSource, encoded], {
cwd: process.cwd(), env: process.env, stdio: ['ignore', 'pipe', 'pipe'],
});
let stdout = ''; let stderr = '';
child.stdout.on('data', chunk => { stdout += chunk; });
child.stderr.on('data', chunk => { stderr += chunk; });
child.on('error', reject);
child.on('close', (code) => {
if (code !== 0) return reject(new Error(`concurrent adopted request child failed: ${stderr}`));
try { resolve(JSON.parse(stdout.trim().split('\n').at(-1))); }
catch (error) { reject(new Error(`invalid concurrent adopted request output: ${stdout}\n${stderr}\n${error.message}`)); }
});
});
}
function authority(context, { action, adoptionId }) {
const provenance = ['fixture:owner-approved', `candidate:${context.candidate}`];
const binding = {
schema: 'torch.dev/integration-adoption-authority/v1alpha1', action, adoptionId,
candidateSha: context.candidate, baseTargetSha: context.base,
provenanceManifestDigest: digest(provenance), contributorArea: context.contributor,
destinationArea: context.destination, targetBranch: 'main',
candidateRef: `refs/torch/integration-candidates/${adoptionId}`,
expectedOldRef: 'refs/heads/main', adapter: {
name: context.service.adoption.refAdapter.name, id: context.service.adoption.refAdapter.id,
},
};
const pending = context.control.requestApproval({
requester: context.contributor, approver: 'owner', task: 'TASK-f40126ee',
title: `Fixture ${action} authority`, summary: 'Hermetic exact-source adoption scenario.',
});
const approved = context.control.decideApproval({
approvalId: pending.id, decidedBy: 'owner', decision: 'approved', expectedRevision: pending.revision,
note: JSON.stringify(binding),
});
return {
approvalId: approved.id, approvalRevision: approved.revision, provenance,
provenanceManifestDigest: binding.provenanceManifestDigest, adapter: binding.adapter,
};
}
function input(context, action, adoptionId, extra = {}) {
return {
actorId: 'owner', adoptionId, candidateSha: context.candidate, baseTargetSha: context.base,
contributorArea: context.contributor, destinationArea: context.destination,
targetBranch: 'main', candidateRef: `refs/torch/integration-candidates/${adoptionId}`,
expectedOldRef: 'refs/heads/main', ...authority(context, { action, adoptionId }), ...extra,
};
}
function prepare(context, adoptionId = 'fixture-adoption') {
const preparedInput = input(context, 'prepare', adoptionId);
const plan = context.service.planAdoption({ ...preparedInput, action: 'prepare' });
assert.deepEqual(plan.blockers, [], `preparation must begin from an exact clean fixture: ${JSON.stringify(plan.blockers)}`);
return context.service.prepareAdoption(preparedInput);
}
function lifecycleInput(context, action, adoptionId, extra = {}) {
const { approvalId, approvalRevision, adapter } = authority(context, { action, adoptionId });
const record = context.service.getPreparedAdoption(adoptionId);
return { actorId: 'owner', adoptionId, expectedRecordRevision: record.revision, approvalId, approvalRevision, adapter, ...extra };
}
function blockedCodes(error) {
assert.equal(error.code.endsWith('_BLOCKED'), true, `expected a blocked adoption transition, got ${error.code}`);
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';
prepare(context, adoptionId);
const finalized = context.service.finalizeAdoption(lifecycleInput(context, 'finalize', adoptionId));
const refs = context.service.adoption.refAdapter.readRefs([
'refs/heads/main', finalized.candidateRef, finalized.archiveRef,
]);
assert.deepEqual(refs, {
'refs/heads/main': context.base,
[finalized.candidateRef]: context.candidate,
[finalized.archiveRef]: context.base,
});
assert.throws(() => context.service.adoption.refAdapter.compareAndSwapRefs({
expected: [{ ref: finalized.candidateRef, sha: context.base }],
writes: [{ ref: finalized.candidateRef, sha: null }],
}), (error) => error.code === 'ADOPTION_REF_CAS_FAILED');
assert.equal(context.service.adoption.getPrepared(adoptionId).state, 'finalized');
context.control.close();
});
test('SCN-integration-adoption-journal-and-binding: a duplicate preparation cannot overwrite the journal and lifecycle input cannot alter its immutable candidate binding', () => {
const context = fixture('torch-adoption-journal');
const adoptionId = 'fixture-adoption';
const prepared = prepare(context, adoptionId);
assert.throws(() => context.service.prepareAdoption(input(context, 'prepare', adoptionId)),
(error) => error.code === 'ADOPTION_RECORD_REVISION_STALE');
assert.throws(() => context.service.finalizeAdoption(lifecycleInput(context, 'finalize', adoptionId, { candidateSha: context.base })),
(error) => error.code === 'ADOPTION_IMMUTABLE_BINDING_STALE');
assert.throws(() => context.service.finalizeAdoption(lifecycleInput(context, 'finalize', adoptionId, {
expectedRecordRevision: prepared.revision + 1,
})), (error) => error.code === 'ADOPTION_RECORD_REVISION_STALE');
const refs = context.service.adoption.refAdapter.readRefs([
prepared.expectedOldRef, prepared.candidateRef, prepared.archiveRef,
]);
assert.deepEqual(refs, {
[prepared.expectedOldRef]: context.base,
[prepared.candidateRef]: null,
[prepared.archiveRef]: null,
});
const { mutationPerformed, ...durablePrepared } = prepared;
assert.equal(mutationPerformed, true);
assert.deepEqual(context.service.adoption.getPrepared(adoptionId), durablePrepared);
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';
const prepared = prepare(context, adoptionId);
context.service.adoption.refAdapter.compareAndSwapRefs({
expected: [
{ ref: prepared.expectedOldRef, sha: prepared.baseTargetSha },
{ ref: prepared.candidateRef, sha: null },
{ ref: prepared.archiveRef, sha: null },
],
writes: [
{ ref: prepared.archiveRef, sha: prepared.baseTargetSha },
{ ref: prepared.candidateRef, sha: prepared.candidateSha },
],
});
const recovered = context.service.reconcileAdoption(lifecycleInput(context, 'reconcile', adoptionId));
assert.equal(recovered.state, 'recovered-finalized');
assert.equal(recovered.record.recovery, 'private-ref-cas-completed-before-journal');
const replay = context.service.reconcileAdoption(lifecycleInput(context, 'reconcile', adoptionId));
assert.equal(replay.state, 'consistent');
assert.equal(replay.mutationPerformed, false);
context.control.close();
});
test('SCN-integration-adoption-rollback-recovery: a journal-missing rollback completes without a second deletion, while divergent candidate bytes refuse', () => {
const context = fixture('torch-adoption-rollback-recovery');
const adoptionId = 'fixture-adoption';
prepare(context, adoptionId);
const finalized = context.service.finalizeAdoption(lifecycleInput(context, 'finalize', adoptionId));
assert.equal(finalized.state, 'finalized');
context.service.adoption.refAdapter.compareAndSwapRefs({
expected: [{ ref: finalized.candidateRef, sha: finalized.candidateSha }],
writes: [{ ref: finalized.candidateRef, sha: null }],
});
const recovered = context.service.rollbackAdoption(lifecycleInput(context, 'rollback', adoptionId));
assert.equal(recovered.state, 'rolled-back');
assert.equal(recovered.recovery, 'private-ref-rollback-completed-before-journal');
const divergent = fixture('torch-adoption-rollback-divergence');
const divergentId = 'fixture-adoption';
prepare(divergent, divergentId);
const divergentFinal = divergent.service.finalizeAdoption(lifecycleInput(divergent, 'finalize', divergentId));
divergent.service.adoption.refAdapter.compareAndSwapRefs({
expected: [{ ref: divergentFinal.candidateRef, sha: divergentFinal.candidateSha }],
writes: [{ ref: divergentFinal.candidateRef, sha: divergent.base }],
});
assert.throws(() => divergent.service.rollbackAdoption(lifecycleInput(divergent, 'rollback', divergentId)),
(error) => error.code === 'ADOPTION_ROLLBACK_REF_DIVERGED');
context.control.close();
divergent.control.close();
});
test('SCN-integration-adoption-private-ref-intake: finalized private refs enter the ordinary native integration queue, not a specialist branch shortcut', () => {
const unfinalized = fixture('torch-adoption-unfinalized-intake');
const unfinalizedId = 'fixture-adoption';
const unfinalizedRef = `refs/torch/integration-candidates/${unfinalizedId}`;
unfinalized.service.adoption.refAdapter.compareAndSwapRefs({
expected: [{ ref: unfinalizedRef, sha: null }],
writes: [{ ref: unfinalizedRef, sha: unfinalized.candidate }],
});
assert.throws(() => unfinalized.service.requestCandidate({
areaId: unfinalized.contributor, commit: unfinalized.candidate, candidateRef: unfinalizedRef,
}), (error) => error.code === 'INTEGRATION_ADOPTED_INTAKE_INTERNAL_ONLY');
assert.deepEqual(unfinalized.service.list(), []);
unfinalized.control.close();
const context = fixture('torch-adoption-native-intake');
const adoptionId = 'fixture-adoption';
prepare(context, adoptionId);
const finalized = context.service.finalizeAdoption(lifecycleInput(context, 'finalize', adoptionId));
assert.throws(() => context.service.requestAdoptedCandidate(lifecycleInput(context, 'request', adoptionId, {
expectedRecordRevision: finalized.revision + 1,
})), (error) => error.code === 'ADOPTION_RECORD_REVISION_STALE');
assert.deepEqual(context.service.list(), []);
const requested = context.service.requestAdoptedCandidate(lifecycleInput(context, 'request', adoptionId));
assert.equal(requested.state, 'requested');
assert.equal(requested.integrationRequest.sourceBranch, finalized.candidateRef);
assert.equal(requested.integrationRequest.sourceCommit, context.candidate);
assert.equal(requested.integrationRequest.state, 'testing');
assert.equal(requested.integrationRequest.targetBranch, 'main');
context.control.close();
});
test('SCN-integration-adoption-approval-boundaries: unrelated or source-only approval records cannot authorize an owner adoption, and actor, action, revision, and provenance mismatches each refuse', () => {
const unrelated = fixture('torch-adoption-unrelated-approval');
const unrelatedId = 'fixture-adoption';
const unrelatedApproval = unrelated.control.requestApproval({
requester: unrelated.contributor, approver: 'owner', task: 'TASK-unrelated',
title: 'Ordinary source branch review', summary: 'Not an integration-adoption authority.',
});
const unrelatedApproved = unrelated.control.decideApproval({
approvalId: unrelatedApproval.id, decidedBy: 'owner', decision: 'approved', expectedRevision: unrelatedApproval.revision,
note: JSON.stringify({ schema: 'torch.dev/ordinary-source-review/v1alpha1', sourceArea: unrelated.contributor }),
});
const unrelatedInput = {
actorId: 'owner', adoptionId: unrelatedId, candidateSha: unrelated.candidate, baseTargetSha: unrelated.base,
contributorArea: unrelated.contributor, destinationArea: unrelated.destination, targetBranch: 'main',
candidateRef: `refs/torch/integration-candidates/${unrelatedId}`, expectedOldRef: 'refs/heads/main',
approvalId: unrelatedApproved.id, approvalRevision: unrelatedApproved.revision,
provenance: ['fixture:owner-approved', `candidate:${unrelated.candidate}`],
provenanceManifestDigest: digest(['fixture:owner-approved', `candidate:${unrelated.candidate}`]),
adapter: { name: unrelated.service.adoption.refAdapter.name, id: unrelated.service.adoption.refAdapter.id },
};
assert.throws(() => unrelated.service.prepareAdoption(unrelatedInput), (error) => blockedCodes(error).includes('ADOPTION_APPROVAL_BINDING_INVALID'));
assert.deepEqual(unrelated.service.list(), []);
unrelated.control.close();
const wrongActor = fixture('torch-adoption-wrong-actor');
assert.throws(() => wrongActor.service.prepareAdoption({
...input(wrongActor, 'prepare', 'fixture-adoption'), actorId: wrongActor.contributor,
}), (error) => blockedCodes(error).includes('OWNER_ACTOR_REQUIRED'));
wrongActor.control.close();
const wrongAction = fixture('torch-adoption-wrong-action');
prepare(wrongAction, 'fixture-adoption');
assert.throws(() => wrongAction.service.finalizeAdoption(lifecycleInput(wrongAction, 'rollback', 'fixture-adoption')),
(error) => blockedCodes(error).includes('ADOPTION_APPROVAL_BINDING_INVALID'));
wrongAction.control.close();
const staleRevision = fixture('torch-adoption-stale-revision');
prepare(staleRevision, 'fixture-adoption');
const staleInput = lifecycleInput(staleRevision, 'finalize', 'fixture-adoption');
assert.throws(() => staleRevision.service.finalizeAdoption({ ...staleInput, approvalRevision: staleInput.approvalRevision - 1 }),
(error) => blockedCodes(error).includes('ADOPTION_APPROVAL_REVISION_STALE'));
staleRevision.control.close();
const wrongProvenance = fixture('torch-adoption-wrong-provenance');
assert.throws(() => wrongProvenance.service.prepareAdoption({
...input(wrongProvenance, 'prepare', 'fixture-adoption'), provenance: ['fixture:owner-approved', 'unapproved:alternate-provenance'],
}), (error) => blockedCodes(error).includes('ADOPTION_PROVENANCE_DIGEST_MISMATCH'));
wrongProvenance.control.close();
});
test('SCN-integration-adoption-request-replay: concurrent authenticated API callers serialize on the adoption journal and create exactly one private-ref queue request', async () => {
const context = fixture('torch-adoption-request-replay');
const adoptionId = 'fixture-adoption';
prepare(context, adoptionId);
context.service.finalizeAdoption(lifecycleInput(context, 'finalize', adoptionId));
const requestInput = lifecycleInput(context, 'request', adoptionId);
const outcomes = await Promise.all([
concurrentAdoptedRequest(context, requestInput),
concurrentAdoptedRequest(context, requestInput),
]);
assert.deepEqual(outcomes.map((entry) => entry.outcome).sort(), ['refused', 'requested']);
assert.equal(outcomes.find((entry) => entry.outcome === 'refused').code, 'ADOPTION_RECORD_REVISION_STALE');
const requests = context.service.list();
assert.equal(requests.length, 1);
assert.equal(context.service.getPreparedAdoption(adoptionId).state, 'requested');
context.control.close();
});
test('SCN-integration-adoption-legacy-retries: historical ordinary-request retries remain readable when integration service starts', () => {
const context = fixture('torch-adoption-legacy-retries');
const insert = context.control.database.prepare(`INSERT INTO integration_requests (
id, project_id, source_area, source_branch, source_commit, target_branch,
base_target_commit, state, reason, required_checks, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
for (const [id, state] of [['historical-failed', 'blocked'], ['historical-retry', 'superseded']]) {
insert.run(id, context.control.projectId, context.contributor, 'refs/heads/candidate', context.candidate,
'main', context.base, state, 'historical-retry', '[]', '2026-10-03T00:00:00.000Z', '2026-10-03T00:00:00.000Z');
}
assert.doesNotThrow(() => new IntegrationService({
repositoryRoot: context.root, controlPlane: context.control, checkService: { exactPasses: () => false },
}));
assert.equal(context.service.list().length, 2);
context.control.close();
});
+433
View File
@@ -0,0 +1,433 @@
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
import { inspectRepository } from '../../src/kernel/git.mjs';
import { proposeDomains } from '../../src/kernel/domains.mjs';
import { installProject } from '../../src/kernel/install.mjs';
import { openControlPlane } from '../../src/control-plane/service.mjs';
import { issueStoppedExecutorEvidence } from '../../src/runtime/stopped-executor-evidence.mjs';
import { observeRuntimeTurn, withRuntimeTurnGuard } from '../../src/runtime/turn-guard.mjs';
import { observeProject } from '../../src/observability/snapshot.mjs';
import { configureContinuation, observeContinuation, planContinuation, runContinuation } from '../../src/runtime/continuation.mjs';
function fixture({ recoveryWorktree = true, extraWorker = false, workerCount = 0 } = {}) {
const root = mkdtempSync(join(tmpdir(), 'torch-legacy-recovery-'));
for (const args of [['init', '-b', 'main'], ['config', 'user.email', '[email protected]'],
['config', 'user.name', 'Recovery Fixture']]) execFileSync('git', args, { cwd: root, stdio: 'pipe' });
writeFileSync(join(root, 'app.js'), 'export const ready = true;\n');
execFileSync('git', ['add', '.'], { cwd: root });
execFileSync('git', ['commit', '-m', 'fixture'], { cwd: root, stdio: 'pipe' });
const repository = inspectRepository(root);
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
if (extraWorker) proposal.domains.push({ ...proposal.domains[0], id: 'extra-worker', title: 'Extra worker', owned_paths: ['extra/**'] });
for (let i = 0; i < workerCount; i++) proposal.domains.push({ ...proposal.domains[0], id: `worker-${i}`, title: `Worker ${i}`, owned_paths: [`worker-${i}/**`] });
proposal.review = { status: 'approved', reviewedAt: '2026-10-03T00:00:00Z', reviewedBy: 'owner', notes: [] };
const env = { ...process.env, XDG_DATA_HOME: join(root, '.data') };
installProject({ repository, proposal, env, projectId: 'recovery-fixture' });
const actualPath = join(root, '.torch', 'install-manifest.json');
const manifest = JSON.parse(readFileSync(actualPath, 'utf8'));
const areaId = proposal.domains[0].id;
if (recoveryWorktree) manifest.external.push({ type: 'worktree', area: areaId, path: join(root, 'worker') });
writeFileSync(actualPath, JSON.stringify(manifest));
let time = Date.parse('2026-10-03T00:00:00Z');
const control = openControlPlane({ repositoryRoot: root, env, clock: () => new Date(time) });
control.reportStatus({ areaId, state: 'working', runtime: 'codex', runtimeSessionId: 'fixture-session',
task: 'TASK-preserved', summary: 'Runtime executor completion is unknown; duplicate launch is blocked pending reconciliation.' });
const identity = control.getAgent(areaId);
const unit = `torch-${control.projectId}-worker.service`;
const properties = { Id: unit, ActiveState: 'failed', SubState: 'failed', MainPID: '0', ControlPID: '0',
ControlGroup: '', InvocationID: 'a'.repeat(32), ExecStart: `node /tmp/probe.mjs ${areaId} ;`,
WorkingDirectory: root, ExecMainExitTimestamp: identity.updatedAt };
let processes = [];
const issue = () => issueStoppedExecutorEvidence({ controlPlane: control, actorId: 'owner', areaId, unit,
invocationId: 'a'.repeat(32), readUnit: () => ({ ...properties }), readProcesses: () => processes, now: () => time });
const apply = issued => control.recoverOwnerStoppedUnknownIdentity({ actorId: 'owner', areaId,
expectedIdentity: issued.plan.expectedIdentity, evidence: issued.evidence });
return { root, env, control, identity, areaId, properties, issue, apply,
advance: ms => { time += ms; }, processes: value => { processes = value; } };
}
test('SCN-legacy-runtime-recovery: owner recovery preserves task/session/unknown and records exactly one owner audit', () => {
const f = fixture();
try {
const issued = f.issue();
assert.equal(f.control.getAgent(f.areaId).state, 'working');
const result = f.apply(issued);
assert.equal(result.identity.state, 'offline');
assert.equal(result.identity.currentTask, 'TASK-preserved');
assert.equal(result.identity.runtimeSessionId, 'fixture-session');
assert.equal(result.priorOutcome, 'unknown');
assert.equal(result.sessionsStarted, false);
const audits = f.control.readAudit({ limit: 100 }).filter(x => x.operation === 'runtime.legacy-unknown.recover-stopped');
assert.equal(audits.length, 1);
assert.equal(audits[0].actorId, 'owner');
assert.equal(audits[0].details.outcome, 'unknown');
assert.throws(() => f.apply(issued), { code: 'RUNTIME_RECOVERY_SNAPSHOT_CONFLICT' });
} finally { f.control.close(); }
});
test('SCN-legacy-runtime-recovery-refusal: live, foreign invocation, area, time and process mismatches cannot issue proof', () => {
for (const patch of [{ MainPID: '99' }, { ControlPID: '99' }, { ActiveState: 'active' },
{ InvocationID: 'b'.repeat(32) }, { ExecStart: 'node other-area' },
{ ExecMainExitTimestamp: '2026-10-02T00:00:00Z' }, { ControlGroup: '/live' }]) {
const f = fixture();
try { Object.assign(f.properties, patch); assert.throws(f.issue, { code: 'RUNTIME_RECOVERY_UNVERIFIED' });
assert.equal(f.control.getAgent(f.areaId).state, 'working'); } finally { f.control.close(); }
}
const f = fixture();
try { f.processes([{ pid: 999, argv: ['codex', 'resume', 'fixture-session'], cwd: '/tmp' }]);
assert.throws(f.issue, { code: 'RUNTIME_RECOVERY_UNVERIFIED' }); } finally { f.control.close(); }
});
test('SCN-legacy-runtime-recovery-cas: changed snapshot, live recheck, expiry and caller-forged proof refuse without mutation', () => {
for (const scenario of ['changed', 'live', 'expired', 'forged']) {
const f = fixture();
try {
const issued = f.issue();
if (scenario === 'changed') { f.advance(1); f.control.reportStatus({ areaId: f.areaId, state: 'working', runtimeSessionId: 'different', summary: 'Runtime executor completion is unknown' }); }
if (scenario === 'live') f.properties.MainPID = '99';
if (scenario === 'expired') f.advance(60_001);
if (scenario === 'forged') issued.evidence = { stopped: true };
assert.throws(() => f.apply(issued));
assert.equal(f.control.getAgent(f.areaId).state, 'working');
assert.equal(f.control.readAudit({ limit: 100 }).filter(x => x.operation === 'runtime.legacy-unknown.recover-stopped').length, 0);
} finally { f.control.close(); }
}
});
test('SCN-legacy-runtime-recovery-authority: specialist and incomplete snapshot cannot use owner recovery', () => {
const f = fixture();
try {
const issued = f.issue();
assert.throws(() => f.control.recoverOwnerStoppedUnknownIdentity({ actorId: f.areaId, areaId: f.areaId,
expectedIdentity: issued.plan.expectedIdentity, evidence: issued.evidence }), { code: 'OWNER_AUTHORITY_REQUIRED' });
assert.throws(() => f.control.recoverOwnerStoppedUnknownIdentity({ actorId: 'owner', areaId: f.areaId,
expectedIdentity: {}, evidence: issued.evidence }), { code: 'RUNTIME_RECOVERY_SNAPSHOT_REQUIRED' });
assert.equal(f.control.getAgent(f.areaId).state, 'working');
} finally { f.control.close(); }
});
test('SCN-runtime-turn-guard: overlapping executors refuse even if an agent reports idle; terminal turns release their own guard', () => {
const f = fixture();
try {
let launches = 0;
withRuntimeTurnGuard(f.control, f.areaId, () => {
launches++;
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Agent reported idle before physical exit' });
assert.throws(() => withRuntimeTurnGuard(f.control, f.areaId, () => { launches++; }), { code: 'RUNTIME_TURN_ACTIVE' });
});
withRuntimeTurnGuard(f.control, f.areaId, () => { launches++; });
assert.equal(launches, 2);
} finally { f.control.close(); }
});
test('SCN-runtime-live-presence: live guard phases override stale idle display without changing durable reports or waits', { skip: process.platform !== 'linux' }, () => {
const f = fixture({ recoveryWorktree: false });
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Previous turn completed' });
const observe = () => observeProject({ repositoryRoot: f.root, env: f.env }).agents.find(a => a.areaId === f.areaId);
withRuntimeTurnGuard(f.control, f.areaId, phase => {
let agent = observe();
assert.equal(agent.state, 'starting');
assert.equal(agent.reportedState, 'idle');
assert.equal(agent.executor.source, 'live-process-and-turn-guard');
phase('working');
agent = observe();
assert.equal(agent.state, 'working');
assert.equal(f.control.getAgent(f.areaId).state, 'idle', 'Observation is not an identity mutation');
f.control.reportStatus({ areaId: f.areaId, state: 'waiting', summary: 'Waiting for named approval' });
assert.equal(observe().state, 'waiting', 'Live execution must not conceal semantic approval waits');
});
assert.equal(observe().executor.state, 'inactive');
assert.equal(observe().state, 'waiting');
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Turn completed' });
assert.equal(observe().state, 'idle');
} finally { f.control.close(); }
});
test('SCN-runtime-live-presence-refusal: dead, replaced, foreign-user and malformed guards never claim active execution', () => {
const f = fixture();
try {
withRuntimeTurnGuard(f.control, f.areaId, () => {
const path = join(f.control.stateRoot, 'sessions', 'turn-guards', f.areaId, 'owner.json');
const original = JSON.parse(readFileSync(path, 'utf8'));
writeFileSync(path, JSON.stringify({ ...original, startTicks: 'fixture-start' }));
const read = live => observeRuntimeTurn({ stateRoot: f.control.stateRoot, repositoryRoot: f.root,
projectId: f.control.projectId, areaId: f.areaId, uid: 1000, inspectProcess: () => live });
const live = { uid: 1000, startTicks: 'fixture-start', state: 'S' };
assert.equal(read(live).state, 'active');
for (const mismatch of [{ ...live, uid: 2000 }, { ...live, startTicks: 'reused-pid' }, { ...live, state: 'Z' }]) {
assert.equal(read(mismatch).state, 'unknown');
}
const absent = observeRuntimeTurn({ stateRoot: f.control.stateRoot, repositoryRoot: f.root,
projectId: f.control.projectId, areaId: f.areaId, inspectProcess: () => { throw new Error('Process gone'); } });
assert.equal(absent.state, 'unknown');
writeFileSync(path, JSON.stringify({ ...original, projectId: 'foreign' }));
assert.equal(read(live).reason, 'guard-invalid');
writeFileSync(path, JSON.stringify(original));
});
} finally { f.control.close(); }
});
test('SCN-runtime-live-presence-legacy: pre-observation guards require exact TORCH identity and project cwd', () => {
const f = fixture();
try {
withRuntimeTurnGuard(f.control, f.areaId, () => {
const path = join(f.control.stateRoot, 'sessions', 'turn-guards', f.areaId, 'owner.json');
const original = JSON.parse(readFileSync(path, 'utf8'));
const legacy = { ...original };
delete legacy.startTicks;
delete legacy.phase;
writeFileSync(path, JSON.stringify(legacy));
const inspect = live => observeRuntimeTurn({ stateRoot: f.control.stateRoot, repositoryRoot: f.root,
projectId: f.control.projectId, areaId: f.areaId, uid: 1000, inspectProcess: () => live });
const live = { uid: 1000, state: 'S', cwd: f.root, argv: ['node', '/runtime/bin/torch.mjs', 'up', '--only', f.areaId] };
assert.equal(inspect(live).phase, 'working');
assert.equal(inspect({ ...live, cwd: '/foreign' }).state, 'unknown');
assert.equal(inspect({ ...live, argv: ['node', 'torch.mjs', 'up', '--only', 'someone-else'] }).state, 'unknown');
writeFileSync(path, JSON.stringify(original));
});
} finally { f.control.close(); }
});
test('SCN-runtime-continuation: explicit enable, event deduplication, daily cap and pause govern authorized turns', async () => {
const f = fixture();
const backlog = { list: () => [] };
const at = new Date('2026-10-03T00:00:00Z');
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Physical turn completed' });
f.control.sendOwnerRequest({ actorId: 'owner', recipient: f.areaId, body: 'Continue assigned work' });
assert.equal(planContinuation(f.control, backlog, { at }).reason, 'paused');
assert.throws(() => configureContinuation(f.control, { actorId: f.areaId, enabled: true }), { code: 'OWNER_AUTHORITY_REQUIRED' });
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 1 });
assert.equal(planContinuation(f.control, backlog, { at }).candidates.length, 1);
let calls = 0;
const run = () => runContinuation(f.control, backlog, { actorId: 'owner', at, launch: async area => { assert.equal(area, f.areaId); calls++; return 0; } });
assert.equal((await run()).launched.length, 1);
assert.equal((await run()).launched.length, 0);
f.control.sendOwnerRequest({ actorId: 'owner', recipient: f.areaId, body: 'New work' });
assert.equal(planContinuation(f.control, backlog, { at }).reason, 'daily-turn-cap');
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 2 });
assert.equal(planContinuation(f.control, backlog, { at }).candidates.length, 1);
configureContinuation(f.control, { actorId: 'owner', enabled: false, maxTurnsPerDay: 2 });
assert.equal((await run()).launched.length, 0);
assert.equal(calls, 1);
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-day-override: owner extra allowance preserves charges and expires at UTC reset', async () => {
const f = fixture();
const backlog = { list: () => [] };
const at = new Date('2026-10-03T00:00:00Z');
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Ready' });
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 1 });
f.control.sendOwnerRequest({ actorId: 'owner', recipient: f.areaId, body: 'First work' });
const run = () => runContinuation(f.control, backlog, { actorId: 'owner', at, launch: async () => 0 });
assert.equal((await run()).launched.length, 1);
assert.equal(planContinuation(f.control, backlog, { at }).reason, 'daily-turn-cap');
assert.throws(() => configureContinuation(f.control, { actorId: f.areaId, enabled: true, todayMaxTurns: 3 }), { code: 'OWNER_AUTHORITY_REQUIRED' });
for (const todayMaxTurns of [0, 97, 1.5]) assert.throws(() => configureContinuation(f.control,
{ actorId: 'owner', enabled: true, todayMaxTurns }), { code: 'CONTINUATION_POLICY_INVALID' });
configureContinuation(f.control, { actorId: 'owner', enabled: true, todayMaxTurns: 3 });
assert.equal(planContinuation(f.control, backlog, { at }).attempts, 1, 'Previously charged turn is retained');
assert.equal(planContinuation(f.control, backlog, { at }).remainingTurns, 2);
f.control.sendOwnerRequest({ actorId: 'owner', recipient: f.areaId, body: 'Additional work' });
assert.equal((await run()).launched.length, 1);
configureContinuation(f.control, { actorId: 'owner', enabled: false });
const sameDay = observeContinuation({ stateRoot: f.control.stateRoot, now: () => at });
assert.equal(sameDay.attempts, 2);
assert.equal(sameDay.maxTurnsPerDay, 3);
assert.equal(sameDay.stopReason, 'paused');
const nextDay = observeContinuation({ stateRoot: f.control.stateRoot, now: () => new Date('2026-10-04T00:00:00Z') });
assert.equal(nextDay.maxTurnsPerDay, 1, 'Override cannot widen future daily allowances');
assert.equal(nextDay.attempts, 0);
assert.ok(f.control.readAudit({ limit: 100 }).some(a => a.operation === 'runtime.continuation.configure'
&& a.details?.dailyOverride?.maxTurns === 3));
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-concurrency: seven authorized starts preserve budget and obey tighter limits', async () => {
const f = fixture({ workerCount: 5 });
const backlog = { list: () => [] };
const at = new Date('2026-10-03T00:00:00Z');
try {
for (const agent of f.control.listAgents()) {
f.control.reportStatus({ areaId: agent.areaId, state: 'idle', summary: 'Ready' });
f.control.sendOwnerRequest({ actorId: 'owner', recipient: agent.areaId, body: 'Review work' });
}
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 48 });
assert.equal(planContinuation(f.control, backlog, { at }).maxConcurrency, 3);
assert.equal(planContinuation(f.control, backlog, { at, limit: 7 }).candidates.length, 3, 'Tick cannot exceed approved capacity');
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxConcurrency: 7 });
assert.equal(observeContinuation({ stateRoot: f.control.stateRoot }).maxTurnsPerDay, 48);
assert.equal(planContinuation(f.control, backlog, { at, limit: 2 }).candidates.length, 2);
for (const value of [0, 8, 1.5]) assert.throws(() => configureContinuation(f.control,
{ actorId: 'owner', enabled: true, maxConcurrency: value }), { code: 'CONTINUATION_POLICY_INVALID' });
const completions = [];
const running = runContinuation(f.control, backlog, { actorId: 'owner', at,
launch: () => new Promise(resolve => completions.push(resolve)) });
assert.equal(completions.length, 7, 'All seven start before any finishes');
assert.equal(planContinuation(f.control, backlog, { at }).attempts, 7);
configureContinuation(f.control, { actorId: 'owner', enabled: false });
assert.equal(observeContinuation({ stateRoot: f.control.stateRoot, now: () => at }).attempts, 7);
assert.equal(observeContinuation({ stateRoot: f.control.stateRoot }).maxConcurrency, 7);
completions.forEach(resolve => resolve(0));
assert.equal((await running).launched.length, 7);
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-signals: acknowledgements do not wake; eligible turns start concurrently within the limit', async () => {
const f = fixture();
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Idle' });
const messages = [];
for (const recipient of [f.areaId, 'session-manager']) {
messages.push(f.control.sendOwnerRequest({ actorId: 'owner', recipient, body: 'Review current work' }));
f.control.sendOwnerRequest({ actorId: 'owner', recipient, body: 'Second handoff' });
}
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 4 });
const completions = [];
const running = runContinuation(f.control, { list: () => [] }, { actorId: 'owner', limit: 2,
launch: () => new Promise(resolve => completions.push(resolve)) });
assert.equal(completions.length, 2, 'Both starts occur without waiting for the first provider to finish');
assert.equal((await runContinuation(f.control, { list: () => [] }, { actorId: 'owner', launch: () => 0 })).reason,
'controller-active-or-unreconciled');
completions.forEach(resolve => resolve(0));
assert.equal((await running).launched.length, 2);
for (const message of messages) f.control.ackMessage({ recipient: message.recipient, messageId: message.id });
assert.equal(planContinuation(f.control, { list: () => [] }).candidates.length, 0);
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-pause: a pause during one turn prevents another queued turn', async () => {
const f = fixture();
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Idle' });
for (const recipient of [f.areaId, 'session-manager']) f.control.sendOwnerRequest({ actorId: 'owner', recipient, body: 'Review current work' });
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 3 });
const result = await runContinuation(f.control, { list: () => [] }, { actorId: 'owner',
launch: async () => { configureContinuation(f.control, { actorId: 'owner', enabled: false, maxTurnsPerDay: 3 }); return 0; } });
assert.equal(result.launched.length, 1);
assert.equal(planContinuation(f.control, { list: () => [] }).reason, 'paused');
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-refill: a short turn frees capacity while the manager remains running', async () => {
const f = fixture({ extraWorker: true });
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Idle' });
for (const recipient of ['session-manager', f.areaId, 'extra-worker']) {
f.control.sendOwnerRequest({ actorId: 'owner', recipient, body: 'Eligible handoff' });
}
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 3 });
const starts = [];
const finishes = new Map();
let thirdStarted;
const third = new Promise(resolve => { thirdStarted = resolve; });
const run = runContinuation(f.control, { list: () => [] }, { actorId: 'owner', limit: 2,
launch: area => { starts.push(area); if (starts.length === 3) thirdStarted();
return new Promise(resolve => finishes.set(area, resolve)); } });
assert.deepEqual(starts, ['session-manager', f.areaId]);
finishes.get(f.areaId)(0);
await third;
assert.deepEqual(starts, ['session-manager', f.areaId, 'extra-worker']);
assert.equal(finishes.has('session-manager'), true, 'Manager completion was not required for refill');
finishes.get('extra-worker')(0);
finishes.get('session-manager')(0);
assert.equal((await run).launched.length, 3);
assert.equal(planContinuation(f.control, { list: () => [] }).reason, 'daily-turn-cap');
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-no-progress: unfinished assignment continues once then escalates rather than busy-looping', async () => {
const f = fixture();
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Idle' });
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 8 });
const task = { id: 'TASK-continue', owner: f.areaId, state: 'assigned', revision: 1, dependencies: [] };
let specialistTurns = 0;
const result = await runContinuation(f.control, { list: () => [task] }, { actorId: 'owner', limit: 1,
launch: area => { if (area === f.areaId) specialistTurns++; return 0; } });
assert.equal(specialistTurns, 2);
assert.equal(result.launched.filter(t => t.areaId === f.areaId).length, 2);
const messages = f.control.readMessages({ recipient: 'session-manager', unacknowledgedOnly: true, limit: 1000 });
assert.equal(messages.filter(m => m.body.includes('two turns without advancing')).length, 1);
assert.equal(planContinuation(f.control, { list: () => [task] }).candidates.some(c => c.areaId === f.areaId), false);
task.revision++;
assert.equal(planContinuation(f.control, { list: () => [task] }).candidates.some(c => c.areaId === f.areaId), true);
task.dependencies = ['TASK-unfinished'];
assert.equal(planContinuation(f.control, { list: () => [task] }).candidates.some(c => c.areaId === f.areaId), false);
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-capacity: a manually held executor counts against automatic fleet capacity', async () => {
const f = fixture();
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Idle' });
f.control.sendOwnerRequest({ actorId: 'owner', recipient: f.areaId, body: 'Eligible handoff' });
configureContinuation(f.control, { actorId: 'owner', enabled: true });
let running;
withRuntimeTurnGuard(f.control, 'session-manager', () => {
running = runContinuation(f.control, { list: () => [] }, { actorId: 'owner', limit: 1,
launch: () => { throw new Error('Capacity must not be exceeded'); } });
});
assert.deepEqual((await running).launched, []);
assert.equal(planContinuation(f.control, { list: () => [] }).attempts, 0);
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-fairness: a fresh task revision does not let one specialist starve an unstarted peer', async () => {
const f = fixture({ extraWorker: true });
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Idle' });
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 3 });
const task = { id: 'TASK-changing', owner: f.areaId, state: 'assigned', revision: 1, dependencies: [] };
f.control.sendOwnerRequest({ actorId: 'owner', recipient: 'extra-worker', body: 'Peer work' });
const starts = [];
await runContinuation(f.control, { list: () => [task] }, { actorId: 'owner', limit: 1,
launch: area => { starts.push(area); if (area === f.areaId) task.revision++; return 0; } });
assert.deepEqual(starts.slice(0, 2), [f.areaId, 'extra-worker']);
} finally { f.control.close(); }
});
test('SCN-runtime-continuation-health: budget stops, day reset, pause and unreadable ledgers are visible without mutation', async () => {
const f = fixture({ recoveryWorktree: false });
const at = new Date('2026-10-03T00:00:00Z');
try {
f.control.reportStatus({ areaId: f.areaId, state: 'idle', summary: 'Idle' });
f.control.sendOwnerRequest({ actorId: 'owner', recipient: f.areaId, body: 'Work' });
configureContinuation(f.control, { actorId: 'owner', enabled: true, maxTurnsPerDay: 1 });
await runContinuation(f.control, { list: () => [] }, { actorId: 'owner', at, launch: () => 0 });
const path = join(f.control.stateRoot, 'continuation.json');
const before = readFileSync(path, 'utf8');
const health = observeContinuation({ stateRoot: f.control.stateRoot, now: () => at });
assert.equal(health.stopReason, 'daily-turn-cap');
assert.equal(health.remainingTurns, 0);
assert.equal(health.manualTurnsIncluded, false);
assert.equal(health.timerInstallationVerified, false);
const snapshot = observeProject({ repositoryRoot: f.root, env: f.env, now: () => at });
assert.equal(snapshot.continuation.stopReason, 'daily-turn-cap');
assert.equal(readFileSync(path, 'utf8'), before);
assert.equal(observeContinuation({ stateRoot: f.control.stateRoot, now: () => new Date('2026-10-04T00:00:00Z') }).remainingTurns, 1);
configureContinuation(f.control, { actorId: 'owner', enabled: false, maxTurnsPerDay: 1 });
assert.equal(observeContinuation({ stateRoot: f.control.stateRoot, now: () => at }).stopReason, 'paused');
writeFileSync(path, 'not-json');
assert.equal(observeContinuation({ stateRoot: f.control.stateRoot, now: () => at }).stopReason, 'policy-or-ledger-unreadable');
assert.equal(readFileSync(path, 'utf8'), 'not-json', 'Observation must not repair or reset the attempt ledger');
} finally { f.control.close(); }
});
test('SCN-legacy-runtime-recovery-project: evidence cannot be applied to a different checkout with cloned project/session fields', () => {
const first = fixture();
const second = fixture();
try {
assert.throws(() => second.control.recoverOwnerStoppedUnknownIdentity({ actorId: 'owner', areaId: second.areaId,
expectedIdentity: second.identity, evidence: first.issue().evidence }), { code: 'RUNTIME_RECOVERY_UNVERIFIED' });
assert.equal(second.control.getAgent(second.areaId).state, 'working');
} finally { first.control.close(); second.control.close(); }
});
+38
View File
@@ -14,6 +14,7 @@ import { installProject } from '../../src/kernel/install.mjs';
import { defaultManagerCheckInSchedule, organizationGraphFromConfig } from '../../src/kernel/organization.mjs';
import { createWorktrees } from '../../src/kernel/worktrees.mjs';
import { ResourceService } from '../../src/resources/service.mjs';
import { createTorchToolset } from '../../src/mcp/tools.mjs';
import {
createFleetBrief, detachFleet, planAreaUp, planFleetDetach, planFleetDown, planFleetUp, startFleet, stopFleet,
} from '../../src/runtime/lifecycle.mjs';
@@ -83,6 +84,43 @@ function fleetFixture({ workerRuntime = 'claude', hierarchy = false } = {}) {
return { root, env, worker: proposal.domains[0].id, middleManager: hierarchy ? 'runtime-lead' : null };
}
test('SCN-fleet-startup-inbox: fresh and resumed launch instructions retrieve newer unread handoffs beyond the default history page', () => {
const fixture = fleetFixture();
const control = openControlPlane({ repositoryRoot: fixture.root, env: fixture.env });
const adapters = new Map([['claude', createClaudeAdapter({ executable: 'claude' })]]);
let tick = 0;
control.clock = () => new Date(Date.parse('2026-10-03T00:00:00Z') + tick++);
try {
const newest = new Map();
for (const areaId of ['session-manager', fixture.worker]) {
for (let i = 0; i < 102; i++) newest.set(areaId, control.sendOwnerRequest({ actorId: 'owner', recipient: areaId, body: `Current handoff ${i}` }));
const history = control.readMessages({ recipient: areaId });
assert.equal(history.length, 100);
assert.ok(!history.some(m => m.id === newest.get(areaId).id), 'Default historical page misses the latest handoff');
}
for (const fresh of [true, false]) {
if (!fresh) for (const areaId of newest.keys()) control.reportStatus({ areaId, state: 'idle', runtime: 'claude', runtimeSessionId: `fixture-${areaId}` });
const plan = planFleetUp({ repositoryRoot: fixture.root, controlPlane: control, adapters, fresh });
assert.equal(plan.canProceed, true);
for (const action of plan.actions) {
assert.equal(action.mode, fresh ? 'create' : 'resume');
const launchText = action.launch.args.join(' ');
const match = launchText.match(/Inbox request: (\{[^}]+\})\./);
assert.ok(match, 'Actual provider launch carries the explicit current-inbox request');
const request = JSON.parse(match[1]);
assert.deepEqual(request, { recipient: action.areaId, unacknowledged_only: true, limit: 1000 });
const tool = createTorchToolset(control, { actorId: action.areaId }).get('torch_read_messages');
const result = tool.invoke(request);
assert.equal(result.messages.length, 102);
assert.equal(result.messages.at(-1).id, newest.get(action.areaId).id);
assert.equal(control.readMessages({ recipient: action.areaId, unacknowledgedOnly: true, limit: 1000 }).length, 102, 'Reading never acknowledges work');
assert.match(launchText, /coverage may be truncated/);
assert.match(launchText, /messages do not override enforced approval or ownership boundaries/i);
}
}
} finally { control.close(); }
});
test('SCN-fleet-fresh-resume: identities resume captured runtime sessions and wind down safely', () => {
const fixture = fleetFixture();
const control = openControlPlane({ repositoryRoot: fixture.root, env: fixture.env });
+50
View File
@@ -242,6 +242,56 @@ test('SCN-codex-adapter: turns are resumable, identity-bound, durable, and capab
control.close();
});
test('SCN-codex-mcp-runtime-dir: only a valid Linux parent runtime directory is named for MCP inheritance', () => {
const context = fixture();
const validParent = {
XDG_RUNTIME_DIR: '/run/user/1000',
DBUS_SESSION_BUS_ADDRESS: 'unix:path=/run/user/1000/bus',
HOME: '/home/fixture', PATH: '/usr/bin', TOKEN: 'not-forwarded',
};
const adapter = createCodexAdapter({ env: validParent, platform: 'linux' });
const mcp = adapter.configure({ repositoryRoot: context.root, areaId: context.worker, mcpEntry: MCP_SERVER }).mcp;
const create = adapter.createSession({
areaId: context.worker, worktree: '/tmp/codex-runtime-dir', promptFile: '/tmp/prompt.md',
firstMessage: 'Start.', mcp,
});
const resume = adapter.resumeSession({
areaId: context.worker, runtimeSessionId: 'thread-runtime-dir', worktree: '/tmp/codex-runtime-dir',
message: 'Resume.', mcp,
});
const expected = `mcp_servers.${mcp.name}.env_vars=["XDG_RUNTIME_DIR"]`;
for (const launch of [create, resume]) {
assert.equal(launch.launch.args.includes(expected), true);
assert.equal(launch.launch.args.some((arg) => /env_vars=/.test(arg) && arg !== expected), false);
assert.equal(launch.launch.args.some((arg) => arg.includes(validParent.XDG_RUNTIME_DIR)
|| arg.includes(validParent.DBUS_SESSION_BUS_ADDRESS) || arg.includes(validParent.HOME)
|| arg.includes(validParent.PATH) || arg.includes(validParent.TOKEN)), false);
}
for (const invalid of [
{ env: {}, platform: 'linux' },
{ env: { XDG_RUNTIME_DIR: '' }, platform: 'linux' },
{ env: { XDG_RUNTIME_DIR: 'relative/runtime' }, platform: 'linux' },
{ env: validParent, platform: 'darwin' },
]) {
const unsupported = createCodexAdapter(invalid);
const unsupportedMcp = unsupported.configure({
repositoryRoot: context.root, areaId: context.worker, mcpEntry: MCP_SERVER,
}).mcp;
const createPlan = unsupported.createSession({
areaId: context.worker, worktree: '/tmp/codex-runtime-dir', promptFile: '/tmp/prompt.md',
firstMessage: 'Start.', mcp: unsupportedMcp,
});
const resumePlan = unsupported.resumeSession({
areaId: context.worker, runtimeSessionId: 'thread-runtime-dir', worktree: '/tmp/codex-runtime-dir',
message: 'Resume.', mcp: unsupportedMcp,
});
for (const plan of [createPlan, resumePlan]) {
assert.equal(plan.launch.args.some((arg) => /env_vars=/.test(arg)), false);
}
}
});
test('SCN-mcp-stdio: an MCP host can initialize and list the TORCH tool surface over stdio', async () => {
const context = fixture();
const child = spawn(process.execPath, [MCP_SERVER, '--root', context.root, '--area', context.worker], {
+145
View File
@@ -0,0 +1,145 @@
import assert from 'node:assert/strict';
import { execFileSync, spawn } from 'node:child_process';
import { mkdtempSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { openControlPlane } from '../../src/control-plane/service.mjs';
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
import { proposeDomains } from '../../src/kernel/domains.mjs';
import { inspectRepository } from '../../src/kernel/git.mjs';
import { installProject } from '../../src/kernel/install.mjs';
const MCP_SERVER = new URL('../../src/mcp/server.mjs', import.meta.url).pathname;
function installedFixture() {
const root = mkdtempSync(join(tmpdir(), 'torch-mcp-owner-reply-'));
execFileSync('git', ['init', '-b', 'main', root]);
execFileSync('git', ['-C', root, 'config', 'user.email', '[email protected]']);
execFileSync('git', ['-C', root, 'config', 'user.name', 'TORCH Test']);
writeFileSync(join(root, 'index.js'), 'export const fixture = true;\n');
execFileSync('git', ['-C', root, 'add', '.']);
execFileSync('git', ['-C', root, 'commit', '-m', 'fixture']);
const repository = inspectRepository(root);
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
proposal.review = { status: 'approved', reviewedAt: '2026-10-03T00:00:00Z', reviewedBy: 'fixture-owner', notes: [] };
const env = { ...process.env, XDG_DATA_HOME: join(root, '.data') };
installProject({ repository, proposal, env, projectId: 'mcp-owner-reply-fixture' });
const control = openControlPlane({ repositoryRoot: root, env });
const identities = control.listAgents().map((agent) => agent.areaId);
control.close();
const worker = identities.find((areaId) => areaId !== 'qa' && areaId !== 'session-manager')
?? identities.find((areaId) => areaId !== 'qa')
?? identities[0];
const other = identities.find((areaId) => areaId !== worker);
assert.ok(other, 'fixture requires a second registered Fleet identity');
return { root, env, worker, other };
}
async function connectMcp({ root, env, actorId }) {
const child = spawn(process.execPath, [MCP_SERVER, '--root', root, '--area', actorId], {
cwd: root, env, stdio: ['pipe', 'pipe', 'pipe'],
});
const responses = new Map();
let stdout = '';
let stderr = '';
child.stderr.on('data', (chunk) => { stderr += chunk; });
child.stdout.on('data', (chunk) => {
stdout += chunk;
const lines = stdout.split('\n');
stdout = lines.pop();
for (const line of lines.filter(Boolean)) {
const message = JSON.parse(line);
if (message.id !== undefined) responses.get(message.id)?.(message);
}
});
let nextId = 0;
const request = (method, params) => new Promise((resolve, reject) => {
const id = ++nextId;
const timeout = setTimeout(() => reject(new Error(`MCP response timeout. stderr: ${stderr}`)), 5000);
responses.set(id, (response) => { clearTimeout(timeout); resolve(response); });
child.stdin.write(`${JSON.stringify({ jsonrpc: '2.0', id, method, params })}\n`);
});
const initialized = await request('initialize', {
protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'torch-test', version: '1.0.0' },
});
assert.equal(initialized.result.serverInfo.name, 'torch-agent-fleet');
child.stdin.write(`${JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' })}\n`);
return {
request,
async close() {
child.stdin.end();
await new Promise((resolve) => {
const timeout = setTimeout(() => { child.kill('SIGTERM'); resolve(); }, 1000);
child.once('exit', () => { clearTimeout(timeout); resolve(); });
});
},
};
}
test('SCN-mcp-owner-reply-public-boundary: a bound MCP identity can reply only to its own owner request', async () => {
const fixture = installedFixture();
let control = openControlPlane({ repositoryRoot: fixture.root, env: fixture.env });
const request = control.sendOwnerRequest({ actorId: 'owner', recipient: fixture.worker, body: 'Report the durable outcome.' });
control.close();
const workerMcp = await connectMcp({ ...fixture, actorId: fixture.worker });
try {
const listed = await workerMcp.request('tools/list', {});
const replyTool = listed.result.tools.find((tool) => tool.name === 'torch_reply_to_owner');
assert.ok(replyTool);
assert.deepEqual(Object.keys(replyTool.inputSchema.properties).sort(), ['body', 'request_id']);
assert.equal(replyTool.inputSchema.additionalProperties, false);
assert.equal(listed.result.tools.some((tool) => /owner.*conversation|history/i.test(tool.name)), false);
const replied = await workerMcp.request('tools/call', {
name: 'torch_reply_to_owner', arguments: { request_id: request.id, body: 'The durable outcome is ready.' },
});
assert.equal(replied.result.isError, undefined);
const reply = JSON.parse(replied.result.content[0].text);
control = openControlPlane({ repositoryRoot: fixture.root, env: fixture.env });
const conversation = control.readOwnerConversation({ actorId: 'owner', requestId: request.id, limit: 10 });
assert.deepEqual(conversation.replies.map((message) => message.id), [reply.id]);
assert.equal(conversation.replies[0].references.replyTo, request.id);
const audit = control.readAudit().find((event) => event.operation === 'message.reply-owner' && event.entityId === reply.id);
assert.deepEqual(audit && { actorId: audit.actorId, details: audit.details }, { actorId: fixture.worker, details: { requestId: request.id } });
const before = { audit: control.readAudit().length, replies: conversation.replies.length };
control.close();
const schemaRefusal = await workerMcp.request('tools/call', {
name: 'torch_reply_to_owner',
arguments: { request_id: request.id, body: 'Attempt to select a sender.', sender: fixture.other },
});
assert.equal(schemaRefusal.result.isError, true);
control = openControlPlane({ repositoryRoot: fixture.root, env: fixture.env });
assert.equal(control.readAudit().length, before.audit);
assert.equal(control.readOwnerConversation({ actorId: 'owner', requestId: request.id, limit: 10 }).replies.length, before.replies);
control.close();
} finally {
await workerMcp.close();
}
control = openControlPlane({ repositoryRoot: fixture.root, env: fixture.env });
const beforeWrongActor = {
audit: control.readAudit().length,
replies: control.readOwnerConversation({ actorId: 'owner', requestId: request.id, limit: 10 }).replies.length,
};
control.close();
const otherMcp = await connectMcp({ ...fixture, actorId: fixture.other });
try {
const wrongActor = await otherMcp.request('tools/call', {
name: 'torch_reply_to_owner', arguments: { request_id: request.id, body: 'A valid identity cannot reply for another agent.' },
});
assert.equal(wrongActor.result.isError, true);
assert.match(wrongActor.result.content[0].text, /owner request addressed to the sender/i);
} finally {
await otherMcp.close();
}
control = openControlPlane({ repositoryRoot: fixture.root, env: fixture.env });
assert.equal(control.readAudit().length, beforeWrongActor.audit);
assert.equal(control.readOwnerConversation({ actorId: 'owner', requestId: request.id, limit: 10 }).replies.length, beforeWrongActor.replies);
control.close();
});
@@ -0,0 +1,91 @@
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { mkdtempSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import { openControlPlane } from '../../src/control-plane/service.mjs';
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
import { proposeDomains } from '../../src/kernel/domains.mjs';
import { inspectRepository } from '../../src/kernel/git.mjs';
import { installProject } from '../../src/kernel/install.mjs';
function installedFixture({ projectId = 'owner-reply-fixture', sequencePrefix = 'main' } = {}) {
const root = mkdtempSync(join(tmpdir(), 'torch-owner-reply-'));
execFileSync('git', ['init', '-b', 'main', root]);
execFileSync('git', ['-C', root, 'config', 'user.email', '[email protected]']);
execFileSync('git', ['-C', root, 'config', 'user.name', 'TORCH Test']);
writeFileSync(join(root, 'index.js'), 'export const fixture = true;\n');
execFileSync('git', ['-C', root, 'add', '.']);
execFileSync('git', ['-C', root, 'commit', '-m', 'fixture']);
const repository = inspectRepository(root);
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
proposal.review = { status: 'approved', reviewedAt: '2026-10-03T00:00:00Z', reviewedBy: 'fixture-owner', notes: [] };
const env = { ...process.env, XDG_DATA_HOME: join(root, '.data') };
installProject({ repository, proposal, env, projectId });
let sequence = 0;
let seconds = 0;
return {
root, env,
worker: proposal.domains.find((domain) => domain.id !== 'qa')?.id ?? proposal.domains[0].id,
options: {
repositoryRoot: root, env,
idFactory: () => `${sequencePrefix}-${++sequence}`,
clock: () => new Date(Date.UTC(2026, 9, 3, 12, 0, seconds++)),
},
};
}
test('SCN-owner-addressed-reply-durability: a registered agent replies to its owner request with durable attribution', () => {
const fixture = installedFixture();
let control = openControlPlane(fixture.options);
const request = control.sendOwnerRequest({ actorId: 'owner', recipient: fixture.worker, body: 'Report the persisted outcome.' });
const first = control.sendOwnerReply({ sender: fixture.worker, requestId: request.id, body: 'The durable outcome is ready.' });
const second = control.sendOwnerReply({ sender: fixture.worker, requestId: request.id, body: 'The evidence remains bounded.' });
control.close();
control = openControlPlane(fixture.options);
const firstPage = control.readOwnerConversation({ actorId: 'owner', requestId: request.id, limit: 1 });
assert.equal(firstPage.request.id, request.id);
assert.deepEqual(firstPage.replies.map((message) => message.id), [first.id]);
assert.equal(firstPage.replies[0].recipient, 'owner');
assert.equal(firstPage.replies[0].references.replyTo, request.id);
assert.equal(firstPage.page.truncated, true);
const secondPage = control.readOwnerConversation({ actorId: 'owner', requestId: request.id, cursor: firstPage.page.nextCursor, limit: 1 });
assert.deepEqual(secondPage.replies.map((message) => message.id), [second.id]);
assert.equal(secondPage.page.complete, true);
assert.equal(secondPage.page.nextCursor, null);
const audit = control.readAudit().find((event) => event.operation === 'message.reply-owner' && event.entityId === first.id);
assert.deepEqual(audit && { actorId: audit.actorId, details: audit.details }, { actorId: fixture.worker, details: { requestId: request.id } });
control.close();
});
test('SCN-owner-addressed-reply-refusal: forged owner recipients, senders, and references leave durable state untouched', () => {
const fixture = installedFixture();
const foreign = installedFixture({ projectId: 'foreign-owner-reply-fixture', sequencePrefix: 'foreign' });
const control = openControlPlane(fixture.options);
const request = control.sendOwnerRequest({ actorId: 'owner', recipient: fixture.worker, body: 'Respond only from your registered identity.' });
const foreignControl = openControlPlane(foreign.options);
const foreignRequest = foreignControl.sendOwnerRequest({ actorId: 'owner', recipient: foreign.worker, body: 'Foreign request.' });
foreignControl.close();
const beforeAudit = control.readAudit().length;
const beforeMessages = control.readMessages({ recipient: fixture.worker }).length;
const beforeConversation = control.readOwnerConversation({ actorId: 'owner', requestId: request.id, limit: 10 });
assert.deepEqual(beforeConversation.replies, []);
assert.throws(() => control.sendMessage({ sender: fixture.worker, recipient: 'owner', body: 'Bypass the reply boundary.' }), (error) => error.code === 'UNKNOWN_FLEET_IDENTITY');
assert.throws(() => control.sendOwnerReply({ sender: 'owner', requestId: request.id, body: 'Spoofed sender.' }), (error) => error.code === 'UNKNOWN_FLEET_IDENTITY');
assert.throws(() => control.sendOwnerReply({ sender: 'session-manager', requestId: request.id, body: 'Valid identity, wrong addressee.' }), (error) => error.code === 'OWNER_REPLY_REFERENCE_INVALID');
assert.throws(() => control.sendOwnerReply({ sender: fixture.worker, requestId: foreignRequest.id, body: 'Foreign reference.' }), (error) => error.code === 'OWNER_REPLY_REFERENCE_INVALID');
assert.throws(() => control.sendOwnerReply({ sender: fixture.worker, requestId: 'forged-message-id', body: 'Forged reference.' }), (error) => error.code === 'OWNER_REPLY_REFERENCE_INVALID');
assert.throws(() => control.readOwnerConversation({ actorId: fixture.worker, requestId: request.id, limit: 1 }), (error) => error.code === 'OWNER_AUTHORITY_REQUIRED');
assert.equal(control.readAudit().length, beforeAudit);
assert.equal(control.readMessages({ recipient: fixture.worker }).length, beforeMessages);
const afterConversation = control.readOwnerConversation({ actorId: 'owner', requestId: request.id, limit: 10 });
assert.deepEqual(afterConversation.replies, []);
assert.deepEqual(afterConversation.page, beforeConversation.page);
const direct = control.sendMessage({ sender: 'session-manager', recipient: fixture.worker, body: 'Existing direct delivery.' });
const broadcast = control.sendMessage({ sender: fixture.worker, recipient: 'all', body: 'Existing broadcast delivery.' });
assert.deepEqual(control.readMessages({ recipient: fixture.worker }).slice(-2).map((message) => message.id), [direct.id, broadcast.id]);
control.close();
});
+163
View File
@@ -0,0 +1,163 @@
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { chmodSync, existsSync, mkdtempSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { basename, join } from 'node:path';
import { DatabaseSync } from 'node:sqlite';
import test from 'node:test';
import { openControlPlane, openControlPlaneReadOnly } from '../../src/control-plane/service.mjs';
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
import { proposeDomains } from '../../src/kernel/domains.mjs';
import { inspectRepository } from '../../src/kernel/git.mjs';
import { installProject } from '../../src/kernel/install.mjs';
import { projectStatePath } from '../../src/kernel/paths.mjs';
import { setupProject } from '../../src/kernel/setup.mjs';
const now = () => new Date('2026-10-03T10:00:00Z');
function fixture() {
const root = mkdtempSync(join(tmpdir(), 'torch-read-only-control-plane-'));
const git = (args) => execFileSync('git', ['-C', root, ...args], {
env: { ...process.env, GIT_AUTHOR_DATE: '2026-10-03T10:00:00Z', GIT_COMMITTER_DATE: '2026-10-03T10:00:00Z' },
});
git(['init', '-b', 'main']);
git(['config', 'user.email', '[email protected]']);
git(['config', 'user.name', 'TORCH Test']);
writeFileSync(join(root, 'app.js'), 'export const value = 1;\n');
git(['add', '.']);
git(['commit', '-m', 'fixture']);
const repository = inspectRepository(root);
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
proposal.review = { status: 'approved', reviewedAt: now().toISOString(), reviewedBy: 'owner', notes: [] };
const env = { ...process.env, XDG_DATA_HOME: mkdtempSync(join(tmpdir(), 'torch-read-only-state-')) };
const projectId = 'read-only-fixture';
installProject({ repository, proposal, env, projectId });
setupProject({ repository: inspectRepository(root), env, parentOverride: join(tmpdir(), `${basename(root)}-trees`), authorized: true });
const writer = openControlPlane({ repositoryRoot: root, env, clock: now });
const worker = proposal.domains[0].id;
writer.reportStatus({ areaId: worker, state: 'idle', summary: 'registered v2 snapshot' });
writer.close();
const stateRoot = projectStatePath(projectId, env);
const stable = new DatabaseSync(join(stateRoot, 'state.db'));
stable.exec('PRAGMA journal_mode = DELETE');
stable.close();
return { root, env, worker, stateRoot };
}
function sidecars(stateRoot) {
return readdirSync(stateRoot).filter((name) => name === 'state.db-wal' || name === 'state.db-shm').sort();
}
test('SCN-read-only-v2-control-plane: a write-refusing state directory yields a stable v2 snapshot and rejects mutation', (t) => {
const context = fixture();
const statePath = join(context.stateRoot, 'state.db');
const before = readFileSync(statePath);
const beforeSidecars = sidecars(context.stateRoot);
assert.deepEqual(beforeSidecars, [], 'fixture must prove sidecar-free reader behavior');
chmodSync(statePath, 0o444);
chmodSync(context.stateRoot, 0o555);
t.after(() => {
chmodSync(context.stateRoot, 0o755);
chmodSync(statePath, 0o644);
});
const reader = openControlPlaneReadOnly({ repositoryRoot: context.root, env: context.env, clock: now });
assert.equal(reader.identity(context.worker).summary, 'registered v2 snapshot');
assert.deepEqual(reader.observeMessages({ recipient: context.worker, selection: 'unread', limit: 1 }), {
recipient: context.worker,
messages: [],
observation: { selection: 'unread', requestedLimit: 1, returnedCount: 0, complete: true, truncated: false, pendingUnreadCount: 0 },
});
assert.throws(
() => reader.reportStatus({ areaId: context.worker, state: 'working', summary: 'must not persist' }),
(error) => error.code === 'CONTROL_PLANE_READ_ONLY',
);
reader.close();
assert.deepEqual(readFileSync(statePath), before, 'the database bytes remain unchanged');
assert.deepEqual(sidecars(context.stateRoot), beforeSidecars, 'the reader creates no WAL or SHM sidecar');
});
test('SCN-read-only-v2-control-plane-race: a concurrent v2 writer produces one coherent snapshot or a typed refusal', () => {
const context = fixture();
const statePath = join(context.stateRoot, 'state.db');
const wal = new DatabaseSync(statePath);
wal.exec('PRAGMA journal_mode = WAL');
wal.close();
const writer = new DatabaseSync(statePath);
writer.exec('BEGIN IMMEDIATE');
writer.prepare('UPDATE identities SET summary = ?, updated_at = ? WHERE area_id = ?')
.run('writer committed after reader snapshot', '2026-10-03T10:01:00Z', context.worker);
let reader;
let refusal = null;
try { reader = openControlPlaneReadOnly({ repositoryRoot: context.root, env: context.env, clock: now }); } catch (error) { refusal = error; }
writer.exec('COMMIT');
writer.close();
if (refusal) {
assert.equal(refusal.code, 'CONTROL_PLANE_READ_ONLY_UNAVAILABLE');
return;
}
const observed = reader.identity(context.worker).summary;
assert.ok(observed === 'registered v2 snapshot' || observed === 'writer committed after reader snapshot', `reader must expose one whole SQLite snapshot, received ${observed}`);
reader.close();
});
test('SCN-read-only-pinned-correlated-snapshot: one reader cannot combine generations across an atomic writer commit', () => {
const context = fixture();
const statePath = join(context.stateRoot, 'state.db');
const generationA = '2026-10-03T10:00:00.000Z';
const generationB = '2026-10-03T10:01:00.000Z';
const correlated = [context.worker, 'session-manager'];
const seed = new DatabaseSync(statePath);
seed.exec('PRAGMA journal_mode = WAL');
const setGeneration = seed.prepare('UPDATE identities SET summary = ?, updated_at = ? WHERE area_id = ?');
for (const areaId of correlated) setGeneration.run('generation A', generationA, areaId);
seed.close();
const reader = openControlPlaneReadOnly({ repositoryRoot: context.root, env: context.env, clock: now });
const first = reader.identity(context.worker);
assert.deepEqual({ summary: first.summary, updatedAt: first.updatedAt }, { summary: 'generation A', updatedAt: generationA });
const writer = new DatabaseSync(statePath);
writer.exec('BEGIN IMMEDIATE');
const update = writer.prepare('UPDATE identities SET summary = ?, updated_at = ? WHERE area_id = ?');
for (const areaId of correlated) update.run('generation B', generationB, areaId);
writer.exec('COMMIT');
writer.close();
let second;
try { second = reader.identity('session-manager'); } catch (error) { assert.equal(error.code, 'CONTROL_PLANE_READ_ONLY_UNAVAILABLE'); }
if (second) {
assert.deepEqual({ summary: second.summary, updatedAt: second.updatedAt }, { summary: 'generation A', updatedAt: generationA }, 'the same reader must not combine generations');
}
reader.close();
const fresh = openControlPlaneReadOnly({ repositoryRoot: context.root, env: context.env, clock: now });
assert.deepEqual(
Object.fromEntries(correlated.map((areaId) => {
const identity = fresh.identity(areaId);
return [areaId, { summary: identity.summary, updatedAt: identity.updatedAt }];
})),
Object.fromEntries(correlated.map((areaId) => [areaId, { summary: 'generation B', updatedAt: generationB }])),
);
fresh.close();
});
test('SCN-read-only-v2-control-plane-schema: unknown schema revisions are refused instead of guessed', () => {
const context = fixture();
const statePath = join(context.stateRoot, 'state.db');
const writer = new DatabaseSync(statePath);
writer.exec('PRAGMA user_version = 3');
writer.close();
assert.ok(existsSync(statePath));
assert.throws(
() => openControlPlaneReadOnly({ repositoryRoot: context.root, env: context.env }),
(error) => error.code === 'CONTROL_PLANE_READ_ONLY_UNAVAILABLE',
);
});
test('SCN-read-only-v2-control-plane-input-drift: tracked identity inputs changing after snapshot make reads unavailable', () => {
const context = fixture();
const rosterPath = join(context.root, '.torch', 'roster.yaml');
const original = readFileSync(rosterPath, 'utf8');
const reader = openControlPlaneReadOnly({ repositoryRoot: context.root, env: context.env });
writeFileSync(rosterPath, `${original}\n`);
assert.throws(() => reader.identity(context.worker), (error) => error.code === 'CONTROL_PLANE_READ_ONLY_UNAVAILABLE');
writeFileSync(rosterPath, original);
reader.close();
});