fix(orchestration): ignore context row order for worker reports

This commit is contained in:
Jinwoo-H
2026-08-16 23:26:13 -04:00
parent 5f1eee0903
commit a4d4c15a0f
2 changed files with 32 additions and 9 deletions
@@ -83,6 +83,29 @@ describe('Task/Dispatch lifecycle guards', () => {
}
)
it('settles a newer context-only legacy sibling after a worker report', () => {
const database = createDatabase()
const task = database.createTask({ spec: 'reversed legacy mixed split' })
const worker = startWorker(database, task.id, 'reversed_reporter')
sqliteFor(database).prepare("UPDATE tasks SET status = 'ready' WHERE id = ?").run(task.id)
const contextOnly = database.createDispatchContext(task.id, 'term_reversed_context')
expect(
database.settleWorkerReport({
taskId: task.id,
dispatchId: worker.dispatchId,
outcome: 'succeeded',
result: 'reversed sibling completed'
})
).toEqual({ action: 'settled', outcome: 'succeeded', duplicate: false })
expect(database.getTask(task.id)?.status).toBe('completed')
expect(database.getDispatchContextById(contextOnly.id)).toMatchObject({
status: 'completed',
capability_revoked_at: expect.any(String)
})
expect(database.getActiveDispatchForTerminal('term_reversed_context')).toBeUndefined()
})
it('rejects generic failure while a supervised worker remains active', () => {
const database = createDatabase()
const task = database.createTask({ spec: 'supervised failure guard' })
+9 -9
View File
@@ -7608,15 +7608,6 @@ export class OrchestrationDb {
reason: `inactive dispatch ${params.dispatchId}: it or task ${params.taskId} is already settled.`
}
}
const latest = this.getActiveDispatchForTask(params.taskId)
if (latest?.id !== params.dispatchId) {
return {
action: 'rejected',
code: 'stale_dispatch',
reason: `Dispatch ${params.dispatchId} is not the current dispatch for task ${params.taskId}.`
}
}
const conflictingWorker = this.db
.prepare(
`SELECT active.id
@@ -7635,6 +7626,15 @@ export class OrchestrationDb {
reason: `Task ${params.taskId} still has active supervised Dispatch ${conflictingWorker.id}; stop or settle it before completing ${params.dispatchId}.`
}
}
const reportingWorker = this.getWorkerDispatch(params.dispatchId)
const latest = this.getActiveDispatchForTask(params.taskId)
if (!reportingWorker && latest?.id !== params.dispatchId) {
return {
action: 'rejected',
code: 'stale_dispatch',
reason: `Dispatch ${params.dispatchId} is not the current dispatch for task ${params.taskId}.`
}
}
const siblingDispatchIds = this.db
.prepare(
`SELECT id FROM dispatch_contexts