From 2647ff579e68c321542e321c4a3ff869f791e4b0 Mon Sep 17 00:00:00 2001 From: Eve Date: Fri, 24 Apr 2026 11:23:02 +0800 Subject: [PATCH] test: detect done but not forwarded state --- scripts/test_subagent_delivery_watchdog.mjs | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/scripts/test_subagent_delivery_watchdog.mjs b/scripts/test_subagent_delivery_watchdog.mjs index 379f320..017a83b 100644 --- a/scripts/test_subagent_delivery_watchdog.mjs +++ b/scripts/test_subagent_delivery_watchdog.mjs @@ -114,6 +114,94 @@ ${result.stderr}`); } }); + +test('watchdog reports suspect delivery failure after SLA when dispatch exists and no completion receipt has arrived yet', () => { + const runner = createFixtureRunner(); + + try { + const inputPath = runner.writeFixture('dispatch-beyond-sla.json', { + runId: 'fixture-run-suspect-delivery-failure', + childSessionKey: 'session:suspect-delivery-failure', + dispatchAt: '2026-04-24T10:00:00.000Z', + expectedBy: '2026-04-24T10:10:00.000Z', + currentTime: '2026-04-24T10:15:00.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.input.path, inputPath); + assert.equal(payload.input.exists, true); + assert.equal(payload.result.status, 'suspect_delivery_failure'); + } finally { + runner.cleanup(); + } +}); + + +test('watchdog reports completed when dispatch exists and completion receipt has arrived', () => { + const runner = createFixtureRunner(); + + try { + const inputPath = runner.writeFixture('dispatch-completed.json', { + runId: 'fixture-run-completed', + childSessionKey: 'session:completed', + dispatchAt: '2026-04-24T10:00:00.000Z', + expectedBy: '2026-04-24T10:10:00.000Z', + currentTime: '2026-04-24T10:05:00.000Z', + completionReceiptAt: '2026-04-24T10:04:00.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.input.path, inputPath); + assert.equal(payload.input.exists, true); + assert.equal(payload.result.status, 'completed'); + } finally { + runner.cleanup(); + } +}); + +test('watchdog reports done but not forwarded when child run is marked done without a main-thread completion receipt', () => { + const runner = createFixtureRunner(); + + try { + const inputPath = runner.writeFixture('dispatch-done-not-forwarded.json', { + runId: 'fixture-run-done-not-forwarded', + childSessionKey: 'session:done-not-forwarded', + dispatchAt: '2026-04-24T10:00:00.000Z', + expectedBy: '2026-04-24T10:10:00.000Z', + currentTime: '2026-04-24T10:05:00.000Z', + childRunStatus: 'done', + }); + + 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.input.path, inputPath); + assert.equal(payload.input.exists, true); + assert.equal(payload.result.status, 'done_but_not_forwarded'); + } finally { + runner.cleanup(); + } +}); + test('fixture runner exposes missing-input behavior for future fail-first cases', () => { const runner = createFixtureRunner();