mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-11-03 11:21:53 +00:00
runtime: fairly order eligible continuation turns
This commit is contained in:
1 parent
512b5b6e16
commit
981bc6933f
4 files changed
+25
-2
No files matched your search
@@ -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.
|
||||
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user