runtime: fairly order eligible continuation turns

This commit is contained in:
thePR0M3TH3AN committed 2026-10-03 00:34:53 -04:00
1 parent 512b5b6e16
commit 981bc6933f
4 files changed
+25 -2

No files matched your search

+4
View File
@@ -18,6 +18,10 @@ test_integrity_note:
given: "An owner-started executor already occupies the configured automatic capacity"
when: "The continuation controller runs"
then: "No additional automatic turn starts and no attempt is charged"
- id: SCN-runtime-continuation-fairness
given: "One specialist keeps advancing revisions while another eligible identity has not started"
when: "A slot becomes available"
then: "The least-recently-dispatched peer starts before the returning specialist"
observable_outcomes:
- "Actual launch ordering, daily charges, coordination messages and explicit held-work reason"
determinism_controls:
@@ -12,4 +12,6 @@ Resume instructions now request eligible implementation/verification/coordinatio
Status exposes occupied guard identities and no-progress holds. Installed release and reboot persistence remain unqualified. Existing native pilot service executes this source candidate on its next activation; the daily limit remains 12 automatic attempts, not a token-cost governor.
Eligible identities are ordered least-recently-dispatched within the current UTC day, with the Manager first only on ties. A repeatedly revised specialist task must not consume every freed slot while an eligible peer has never started.
Deterministic acceptance scenarios and anti-cheat notes are in docs/TEST_INTEGRITY.md. Independent live qualification remains necessary; do not close broader event-driven or persistent-operations umbrellas based on this source fix alone.
+5 -2
View File
@@ -77,7 +77,9 @@ export function planContinuation(control, backlog, { at = new Date(), limit = 3
candidates.push({ areaId, fingerprint, signal, workKey: taskKey(active),
messageCount: freshMessages.length, taskIds: active.map(t => t.id), continueWork });
}
candidates.sort((a, b) => Number(b.areaId === 'session-manager') - Number(a.areaId === 'session-manager'));
const ordinal = area => state.handled[area]?.dispatchedDay === day ? state.handled[area].dispatchedOrdinal ?? 0 : 0;
candidates.sort((a, b) => ordinal(a.areaId) - ordinal(b.areaId)
|| Number(b.areaId === 'session-manager') - Number(a.areaId === 'session-manager'));
return { enabled: true, day, attempts, remainingTurns: state.maxTurnsPerDay - attempts,
occupiedAreas: occupiedAreas(control), held,
candidates: candidates.slice(0, Math.min(limit, state.maxTurnsPerDay - attempts)), mutationPerformed: false };
@@ -106,7 +108,8 @@ export async function runContinuation(control, backlog, { actorId, launch, at, c
const state = read(control);
if (state.day !== current.day) { state.day = current.day; state.attempts = 0; }
state.attempts++;
state.handled[candidate.areaId] = candidate.signal;
state.handled[candidate.areaId] = { ...candidate.signal,
dispatchedDay: current.day, dispatchedOrdinal: state.attempts };
save(control, state); // Reserve before launch; unknown attempts are never refunded.
let result;
try { result = launch(candidate.areaId); } catch { result = null; }
@@ -318,6 +318,20 @@ test('SCN-runtime-continuation-capacity: a manually held executor counts against
} 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-legacy-runtime-recovery-project: evidence cannot be applied to a different checkout with cloned project/session fields', () => {
const first = fixture();
const second = fixture();