mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-11-04 11:51:53 +00:00
TASK-bounded-routine-coordination: test paused dispatch
Closes: TASK-bounded-routine-coordination
This commit is contained in:
1 parent
d3a679849b
commit
9394243fce
2 files changed
+50
No files matched your search
@@ -14,9 +14,14 @@ test_integrity_note:
|
||||
given: An assigned task and pending peer and owner approvals in a fixed-time local control plane
|
||||
when: The named recipient acknowledges messages and the manager attempts a non-owned decision
|
||||
then: The task and approvals remain pending until only the named peer decides its approval
|
||||
- id: SCN-routine-coordination-paused-dispatch
|
||||
given: An assigned task, an approved named-peer request, and a pending owner provider decision
|
||||
when: A public runtime start is attempted without an authorized executor
|
||||
then: The start is refused, no provider adapter runs, and the assigned task and owner wait remain unresolved
|
||||
observable_outcomes:
|
||||
- Generated tracked instruction text for fresh-install and resume surfaces
|
||||
- Durable task state, approval state, named-approver identity, and authority errors
|
||||
- Public start refusal, zero adapter invocations, offline identity state, and retained owner wait
|
||||
determinism_controls:
|
||||
- Disposable local Git repository, SQLite state, and fixed clock
|
||||
- No provider calls, network, retries, sleeps, or host timers
|
||||
|
||||
@@ -4,6 +4,7 @@ import { mkdirSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { basename, join } from 'node:path';
|
||||
import test from 'node:test';
|
||||
import { createClaudeAdapter } from '../../src/adapters/claude.mjs';
|
||||
import { createBacklogService } from '../../src/backlog/service.mjs';
|
||||
import { openControlPlane } from '../../src/control-plane/service.mjs';
|
||||
import { analyzeRepository } from '../../src/kernel/analyze.mjs';
|
||||
@@ -11,6 +12,7 @@ import { proposeDomains } from '../../src/kernel/domains.mjs';
|
||||
import { inspectRepository } from '../../src/kernel/git.mjs';
|
||||
import { installProject } from '../../src/kernel/install.mjs';
|
||||
import { createWorktrees } from '../../src/kernel/worktrees.mjs';
|
||||
import { planAreaUp, startFleet } from '../../src/runtime/lifecycle.mjs';
|
||||
|
||||
function fixture() {
|
||||
const root = mkdtempSync(join(tmpdir(), 'torch-routine-coordination-'));
|
||||
@@ -104,3 +106,46 @@ test('SCN-routine-coordination-boundaries: acknowledgement leaves work pending a
|
||||
control.close();
|
||||
}
|
||||
});
|
||||
|
||||
test('SCN-routine-coordination-paused-dispatch: an unapproved public start leaves work and owner waits unresolved', () => {
|
||||
const context = fixture();
|
||||
let adapterCalls = 0;
|
||||
const adapter = createClaudeAdapter({ executable: 'claude', runner: () => {
|
||||
adapterCalls++;
|
||||
throw new Error('A disabled provider must not run.');
|
||||
} });
|
||||
const control = openControlPlane({ repositoryRoot: context.root, env: context.env,
|
||||
clock: () => new Date('2026-09-30T12:00:00Z') });
|
||||
try {
|
||||
const backlog = createBacklogService({ repositoryRoot: context.root, controlPlane: control });
|
||||
const created = backlog.create({ actorId: 'session-manager', title: 'Paused dispatch boundary',
|
||||
description: 'Keep assigned work visible while provider execution is disabled.',
|
||||
acceptanceCriteria: ['The start boundary fails closed.'], affectedDomains: [context.worker] });
|
||||
const ready = backlog.transition({ taskId: created.id, actorId: 'session-manager', to: 'ready',
|
||||
expectedRevision: created.revision });
|
||||
const assigned = backlog.transition({ taskId: ready.id, actorId: 'session-manager', to: 'assigned',
|
||||
owner: context.worker, expectedRevision: ready.revision });
|
||||
const taskMessage = control.sendMessage({ sender: 'session-manager', recipient: context.worker,
|
||||
body: 'Wait for explicit provider authorization.', references: { task: assigned.id } });
|
||||
control.ackMessage({ recipient: context.worker, messageId: taskMessage.id });
|
||||
const peerApproval = control.requestApproval({ requester: context.worker, approver: context.peer,
|
||||
task: assigned.id, title: 'Peer consent', summary: 'Approve the bounded routine path.' });
|
||||
control.decideApproval({ approvalId: peerApproval.id, decidedBy: context.peer, decision: 'approved',
|
||||
expectedRevision: peerApproval.revision, note: 'Routine path reviewed.' });
|
||||
const ownerWait = control.requestApproval({ requester: context.worker, approver: 'owner', task: assigned.id,
|
||||
title: 'Owner provider decision', summary: 'Provider execution remains owner-reserved.' });
|
||||
|
||||
const plan = planAreaUp({ repositoryRoot: context.root, controlPlane: control, areaId: context.worker,
|
||||
adapter, fresh: true });
|
||||
assert.equal(plan.canProceed, true, JSON.stringify(plan.blockers));
|
||||
assert.throws(() => startFleet({ plan, controlPlane: control }),
|
||||
(error) => error.code === 'RUNTIME_EXECUTION_NOT_AUTHORIZED');
|
||||
assert.equal(adapterCalls, 0, 'the disabled public start cannot invoke a provider adapter');
|
||||
assert.equal(backlog.get(assigned.id).state, 'assigned', 'acknowledgement and refusal cannot complete work');
|
||||
assert.equal(control.listApprovals({ actorId: context.worker, status: 'pending' }).some((item) =>
|
||||
item.id === ownerWait.id), true, 'the owner wait remains visible after the blocked start');
|
||||
assert.equal(control.identity(context.worker).state, 'offline', 'a blocked start cannot report false idle or success');
|
||||
} finally {
|
||||
control.close();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user