live-completion.test.mjs

 1import { describe, it } from 'node:test';
 2import assert from 'node:assert/strict';
 3
 4import {
 5  completionAckForAcceptResult,
 6  completionTypeForAcceptResult,
 7} from '../skill/scripts/live-completion.mjs';
 8
 9describe('live completion type classification', () => {
10  it('treats generated-file fallback accept as normal agent handoff, not error', () => {
11    assert.equal(
12      completionTypeForAcceptResult('accept', { handled: false, mode: 'fallback' }),
13      'agent_done',
14      'event=live_poll.fallback_completion actor=agent operation=accept_generated_file risk=fallback_handoff_recorded_as_agent_error expected=agent_done actual=error',
15    );
16  });
17
18  it('treats unhandled non-error accept as normal manual agent handoff', () => {
19    assert.equal(
20      completionTypeForAcceptResult('accept', { handled: false, error: 'Session markers not found' }),
21      'agent_done',
22      'event=live_poll.manual_accept_completion actor=agent operation=accept_manual_cleanup risk=manual_handoff_recorded_as_agent_error expected=agent_done actual=error',
23    );
24  });
25
26  it('keeps carbonize-required accepts recoverable until cleanup is completed', () => {
27    assert.equal(
28      completionTypeForAcceptResult('accept', { handled: true, carbonize: true }),
29      'agent_done',
30      'event=live_poll.carbonize_completion actor=agent operation=accept_with_carbonize risk=carbonize_session_marked_completed_before_cleanup expected=agent_done actual=complete',
31    );
32  });
33
34  it('marks carbonize acknowledgements as non-final and requiring explicit completion', () => {
35    assert.deepEqual(
36      completionAckForAcceptResult('carbonize-1', 'agent_done', { handled: true, carbonize: true }),
37      {
38        ok: true,
39        type: 'agent_done',
40        final: false,
41        requiresComplete: true,
42        nextCommand: 'live-complete.mjs --id carbonize-1',
43        message: 'Carbonize cleanup must be verified, then the session must be completed explicitly before polling again.',
44      },
45      'event=live_poll.carbonize_ack actor=agent operation=accept_with_carbonize risk=active_session_never_completed expected=explicit_complete_required actual=missing_requires_complete',
46    );
47  });
48
49  it('keeps normal handled accepts terminal', () => {
50    assert.deepEqual(
51      completionAckForAcceptResult('done-1', 'complete', { handled: true, carbonize: false }),
52      { ok: true, type: 'complete' },
53    );
54  });
55
56  it('classifies handled accept/discard and real failures explicitly', () => {
57    assert.equal(completionTypeForAcceptResult('accept', { handled: true }), 'complete');
58    assert.equal(completionTypeForAcceptResult('discard', { handled: true }), 'discarded');
59    assert.equal(completionTypeForAcceptResult('accept', { handled: false, mode: 'error', error: 'boom' }), 'error');
60  });
61});