feat: add watchdog recovery decisions
This commit is contained in:
@@ -202,6 +202,72 @@ ${result.stderr}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
test('watchdog prefers fetch_history recovery when child run is done but no forwarded completion receipt exists', () => {
|
||||
const runner = createFixtureRunner();
|
||||
|
||||
try {
|
||||
const inputPath = runner.writeFixture('dispatch-done-not-forwarded-recovery.json', {
|
||||
runId: 'fixture-run-done-not-forwarded-recovery',
|
||||
childSessionKey: 'session:done-not-forwarded-recovery',
|
||||
dispatchAt: '2026-04-24T10:00:00.000Z',
|
||||
expectedBy: '2026-04-24T10:10:00.000Z',
|
||||
currentTime: '2026-04-24T10:05:00.000Z',
|
||||
childRunStatus: 'done',
|
||||
forwardedToMain: false,
|
||||
recoveryAttemptCount: 0,
|
||||
});
|
||||
|
||||
const result = runner.runWatchdog(['--compact', '--input', inputPath]);
|
||||
|
||||
assert.equal(result.status, 0, `expected zero exit status, got ${result.status}
|
||||
${result.stderr}`);
|
||||
assert.equal(result.stderr, '');
|
||||
|
||||
const payload = JSON.parse(result.stdout);
|
||||
assert.equal(payload.ok, true);
|
||||
assert.equal(payload.result.status, 'done_but_not_forwarded');
|
||||
assert.equal(payload.result.recoveryDecision, 'fetch_history');
|
||||
} finally {
|
||||
runner.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
test('watchdog escalates to respawn when fetch_history recovery was already attempted and delivery is still not forwarded', () => {
|
||||
const runner = createFixtureRunner();
|
||||
|
||||
try {
|
||||
const inputPath = runner.writeFixture('dispatch-done-not-forwarded-respawn.json', {
|
||||
runId: 'fixture-run-done-not-forwarded-respawn',
|
||||
childSessionKey: 'session:done-not-forwarded-respawn',
|
||||
dispatchAt: '2026-04-24T10:00:00.000Z',
|
||||
expectedBy: '2026-04-24T10:10:00.000Z',
|
||||
currentTime: '2026-04-24T10:06:00.000Z',
|
||||
childRunStatus: 'done',
|
||||
forwardedToMain: false,
|
||||
recoveryAttemptCount: 1,
|
||||
recoveryAction: 'fetch_history',
|
||||
lastRecoveryAt: '2026-04-24T10:05:30.000Z',
|
||||
});
|
||||
|
||||
const result = runner.runWatchdog(['--compact', '--input', inputPath]);
|
||||
|
||||
assert.equal(result.status, 0, `expected zero exit status, got ${result.status}
|
||||
${result.stderr}`);
|
||||
assert.equal(result.stderr, '');
|
||||
|
||||
const payload = JSON.parse(result.stdout);
|
||||
assert.equal(payload.ok, true);
|
||||
assert.equal(payload.result.status, 'done_but_not_forwarded');
|
||||
assert.equal(payload.result.recoveryDecision, 'respawn');
|
||||
} finally {
|
||||
runner.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
test('fixture runner exposes missing-input behavior for future fail-first cases', () => {
|
||||
const runner = createFixtureRunner();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user