mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 16:02:50 +00:00
fix(orchestration): stop certifying an unproven process exit
An unproven stop wrote stage=process_exited with termination_reason=unknown, and the fleet projection read that stage alone as a death certificate, so worker-list and worker-show published liveness=exited and nextAction=recover for a possibly-live agent. Only certify the stage when the cause was observed.
This commit is contained in:
@@ -420,6 +420,43 @@ describe('fleet liveness and attention after a host verdict', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('refuses to certify a process_exited stage whose cause was never observed', () => {
|
||||
const projected = projectOrchestrationFleet({
|
||||
workers: [
|
||||
worker('1', {
|
||||
workerStage: 'process_exited',
|
||||
workerState: 'failed',
|
||||
terminationReason: 'unknown'
|
||||
})
|
||||
],
|
||||
statuses: [],
|
||||
now: 10_000
|
||||
})
|
||||
expect(projected.workers[0]!.liveness).toEqual({
|
||||
verdict: 'unverifiable',
|
||||
reason: 'missing_status'
|
||||
})
|
||||
expect(projected.workers[0]!.nextAction.kind).toBe('inspect')
|
||||
})
|
||||
|
||||
it('certifies a process_exited stage whose exit was observed', () => {
|
||||
const projected = projectOrchestrationFleet({
|
||||
workers: [
|
||||
worker('1', {
|
||||
workerStage: 'process_exited',
|
||||
workerState: 'failed',
|
||||
terminationReason: 'exited'
|
||||
})
|
||||
],
|
||||
statuses: [],
|
||||
now: 10_000
|
||||
})
|
||||
expect(projected.workers[0]!.liveness).toEqual({
|
||||
verdict: 'exited',
|
||||
source: 'execution_host'
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps an unverifiable worker on inspect: absence is never authority to stop', () => {
|
||||
const now = 10 * AGENT_STATUS_STALE_AFTER_MS
|
||||
const projected = projectOrchestrationFleet({
|
||||
|
||||
@@ -26,7 +26,10 @@ const SETTLED_WORKER_STATES = new Set(['succeeded', 'failed', 'stopped', 'abando
|
||||
* `unknown` is a death certificate — regardless of which state the worker settled into. */
|
||||
function hasCertifiedExit(worker: FleetLivenessSubject): boolean {
|
||||
return (
|
||||
worker.workerStage === 'process_exited' ||
|
||||
// `process_exited` is written from the same cause as the reason beside it, and
|
||||
// `unknown` there means a stop was issued and no exit was ever observed. A null
|
||||
// reason is a pre-v29 row whose stage write was the only exit record.
|
||||
(worker.workerStage === 'process_exited' && worker.terminationReason !== 'unknown') ||
|
||||
worker.terminationReason === 'operator_close' ||
|
||||
worker.terminationReason === 'signaled' ||
|
||||
worker.terminationReason === 'exited'
|
||||
|
||||
Reference in New Issue
Block a user