mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-11-06 12:51:54 +00:00
TASK-bounded-routine-coordination: qualify paused schedule dispatch
Closes: TASK-bounded-routine-coordination
This commit is contained in:
1 parent
9394243fce
commit
114e952407
2 files changed
+66
-1
No files matched your search
@@ -18,10 +18,15 @@ test_integrity_note:
|
||||
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
|
||||
- id: SCN-routine-coordination-paused-schedule-dispatch
|
||||
given: An assigned waiting task, a pending owner provider decision, and an installed manager check-in schedule with wake.enabled false
|
||||
when: The public system scheduler dispatches the due owner-authorized coordination schedule
|
||||
then: It queues a durable manager review without planning or invoking a provider, while the 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
|
||||
- Installed wake policy, public scheduled-dispatch receipt, zero provider or command invocations, retained assignment and owner wait
|
||||
determinism_controls:
|
||||
- Disposable local Git repository, SQLite state, and fixed clock
|
||||
- No provider calls, network, retries, sleeps, or host timers
|
||||
@@ -31,6 +36,7 @@ test_integrity_note:
|
||||
- Letting a manager decide an owner or peer approval
|
||||
- Omitting policy boundaries from one generated startup surface
|
||||
- Re-enabling paused execution or granting starts, spending, publication, destructive recovery, or arbitrary dispatch
|
||||
- Treating a queued manager check-in as authorization to start a provider or resolve the underlying wait
|
||||
relaxation:
|
||||
did_relax_any_assertion: false
|
||||
if_true_explain_spec_basis: ""
|
||||
|
||||
@@ -13,8 +13,9 @@ 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';
|
||||
import { ScheduleService } from '../../src/schedules/service.mjs';
|
||||
|
||||
function fixture() {
|
||||
function fixture({ pausedManagerWake = false } = {}) {
|
||||
const root = mkdtempSync(join(tmpdir(), 'torch-routine-coordination-'));
|
||||
execFileSync('git', ['init', '-b', 'main', root]);
|
||||
execFileSync('git', ['-C', root, 'config', 'user.email', '[email protected]']);
|
||||
@@ -27,6 +28,11 @@ function fixture() {
|
||||
execFileSync('git', ['-C', root, 'commit', '-m', 'fixture']);
|
||||
const repository = inspectRepository(root);
|
||||
const proposal = proposeDomains({ repository, analysis: analyzeRepository(repository) });
|
||||
if (pausedManagerWake) {
|
||||
const schedule = proposal.schedules.find((entry) => entry.action?.type === 'manager-check-in');
|
||||
assert.ok(schedule, 'fixture must configure the Session Manager check-in schedule');
|
||||
schedule.action = { ...schedule.action, wake: { enabled: false } };
|
||||
}
|
||||
proposal.review = {
|
||||
status: 'approved', reviewedAt: '2026-09-30T00:00:00Z', reviewedBy: 'fixture-owner', notes: [],
|
||||
};
|
||||
@@ -149,3 +155,56 @@ test('SCN-routine-coordination-paused-dispatch: an unapproved public start leave
|
||||
control.close();
|
||||
}
|
||||
});
|
||||
|
||||
test('SCN-routine-coordination-paused-schedule-dispatch: configured paused wakes queue attention without a provider invocation', () => {
|
||||
const context = fixture({ pausedManagerWake: true });
|
||||
const at = new Date('2026-09-30T12:00:00Z');
|
||||
let providerWakeCalls = 0;
|
||||
let commandCalls = 0;
|
||||
const control = openControlPlane({ repositoryRoot: context.root, env: context.env, clock: () => at });
|
||||
try {
|
||||
const backlog = createBacklogService({ repositoryRoot: context.root, controlPlane: control });
|
||||
const created = backlog.create({ actorId: 'session-manager', title: 'Paused scheduled dispatch',
|
||||
description: 'Keep assigned work and the owner wait visible while wakes are paused.',
|
||||
acceptanceCriteria: ['The paused schedule queues review without a provider invocation.'],
|
||||
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 });
|
||||
control.reportStatus({ areaId: context.worker, state: 'waiting', task: assigned.id,
|
||||
summary: 'Waiting for the owner provider decision.' });
|
||||
const ownerWait = control.requestApproval({ requester: context.worker, approver: 'owner', task: assigned.id,
|
||||
title: 'Owner provider decision', summary: 'Automatic provider execution is paused.' });
|
||||
const schedules = new ScheduleService({
|
||||
repositoryRoot: context.root, controlPlane: control, clock: () => at,
|
||||
executor: () => { commandCalls++; throw new Error('Manager check-in must not invoke a shell command.'); },
|
||||
wakeManager: {
|
||||
plan: () => { providerWakeCalls++; throw new Error('A paused schedule must not plan a provider wake.'); },
|
||||
invoke: () => { providerWakeCalls++; throw new Error('A paused schedule must not invoke a provider.'); },
|
||||
},
|
||||
});
|
||||
|
||||
const plan = schedules.plan({ scheduleId: 'session-manager-check-in', actorId: 'owner', at });
|
||||
assert.equal(plan.wakeEnabled, false, 'the installed schedule must expose an explicit paused wake policy');
|
||||
assert.deepEqual(plan.schedule.action.wake, { enabled: false });
|
||||
const dispatched = schedules.dispatchSystem({ actorId: 'owner', approved: true, at });
|
||||
assert.deepEqual(dispatched.due, ['session-manager-check-in']);
|
||||
assert.equal(dispatched.runs[0].result, 'succeeded');
|
||||
const observed = JSON.parse(dispatched.runs[0].stdout);
|
||||
assert.equal(observed.checkIn.queued, true);
|
||||
assert.equal(observed.wake.attempted, false);
|
||||
assert.equal(observed.wake.reason, 'wake-disabled');
|
||||
assert.equal(providerWakeCalls, 0, 'the public scheduled dispatch cannot plan or invoke a paused provider');
|
||||
assert.equal(commandCalls, 0, 'the typed check-in cannot fall through to a shell command');
|
||||
assert.equal(backlog.get(assigned.id).state, 'assigned', 'the scheduled review cannot complete assigned work');
|
||||
assert.equal(control.listApprovals({ actorId: context.worker, status: 'pending' }).some((item) =>
|
||||
item.id === ownerWait.id), true, 'the owner decision remains a durable wait');
|
||||
assert.equal(control.identity(context.worker).state, 'waiting', 'the worker cannot report false idle or success');
|
||||
assert.equal(control.identity('session-manager').state, 'offline', 'queued review cannot report a manager provider turn');
|
||||
assert.equal(control.readMessages({ recipient: 'session-manager', unacknowledgedOnly: true })
|
||||
.some((message) => message.kind === 'manager-check-in'), true, 'the manager receives durable attention instead of a wake');
|
||||
} finally {
|
||||
control.close();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user