| 1 | import test from 'node:test'; |
| 2 | import assert from 'node:assert/strict'; |
| 3 | import { importTrace } from '../dist/core/ingest.js'; |
| 4 | import { observeRuntimeRequests } from '../dist/core/codewhale.js'; |
| 5 | import { compilePetTelemetry } from '../dist/core/pet-telemetry.js'; |
| 6 | import { buildPyramid } from '../dist/core/signal.js'; |
| 7 | |
| 8 | const epoch = Date.parse('2026-09-12T00:00:00Z'); |
| 9 | const stamp = ms => new Date(epoch + ms).toISOString(); |
| 10 | const row = (seq, event, ms, payload, turn_id = 'turn-a') => ({ seq, event, thread_id: 'fixture', turn_id, timestamp: stamp(ms), payload }); |
| 11 | const read = rows => importTrace(JSON.stringify(rows), 'fixture', { privacy: 'metadata' })[0]; |
| 12 | |
| 13 | test('a late Runtime failure keeps the real operation interval and tears once at its receipt time', () => { |
| 14 | const trace = read([ |
| 15 | row(1, 'item.started', 0, { item: { id: 'work', kind: 'tool_call', started_at: stamp(0), status: 'running' }, tool: 'bash' }), |
| 16 | row(2, 'item.completed', 2000, { item: { id: 'work', kind: 'tool_call', started_at: stamp(0), ended_at: stamp(1000), status: 'failed', detail: 'fixture-private-result' }, tool: 'bash' }), |
| 17 | ]); |
| 18 | const item = trace.events.find(e => e.id === 'work'); |
| 19 | assert.equal(item.status, 'error'); assert.equal(item.endTime, 1000); |
| 20 | assert.equal(item.attributes['whalesong.error_onset_ms'], 2000); |
| 21 | assert.equal(trace.duration, 2000); assert.doesNotMatch(JSON.stringify(trace), /fixture-private-result/); |
| 22 | const tape = compilePetTelemetry(trace.events, 2400); |
| 23 | assert.equal(tape[0].channel, 'code'); assert.equal(tape[0].errors, 0); |
| 24 | assert.equal(tape[3].observed, 0); |
| 25 | assert.equal(tape[5].channel, 'error'); assert.equal(tape[5].observed, 1); |
| 26 | assert.equal(tape.reduce((sum, b) => sum + b.errors, 0), 1); |
| 27 | const level = buildPyramid(trace.events).levels[0], offset = 3 * level.length; |
| 28 | assert.equal(level.errors[offset], 0); |
| 29 | assert.equal(level.errors[offset + Math.floor(2000 / level.binMs)], 1); |
| 30 | }); |
| 31 | |
| 32 | test('Runtime approval and input identities retain waiting intervals through their matching terminal receipts', () => { |
| 33 | const trace = read([ |
| 34 | row(1, 'approval.required', 0, { approval_id: 'shared', description: 'fixture-private-question' }), |
| 35 | row(2, 'user_input.required', 1000, { id: 'shared', request: { questions: ['fixture-private-question'] } }), |
| 36 | row(3, 'user_input.answered', 2000, { input_id: 'shared' }, 'different-turn'), |
| 37 | row(4, 'approval.decided', 4000, { approval_id: 'shared', decision: 'deny' }), |
| 38 | row(5, 'user_input.canceled', 8000, { input_id: 'shared' }), |
| 39 | ]); |
| 40 | const approval = trace.events.find(e => e.name === 'approval.required'); |
| 41 | const input = trace.events.find(e => e.name === 'user_input.required'); |
| 42 | assert.equal(approval.endTime, 4000); assert.equal(input.endTime, 8000); |
| 43 | assert.equal(approval.openEnded, false); assert.equal(input.openEnded, false); |
| 44 | const tape = compilePetTelemetry(trace.events, 8800); |
| 45 | assert.ok(tape.slice(0, 20).every(b => b.waiting && b.channel === 'human')); |
| 46 | assert.equal(tape[20].waiting, false); assert.equal(tape[20].observed, 0); |
| 47 | assert.equal(tape.reduce((sum, b) => sum + b.errors, 0), 0); |
| 48 | assert.doesNotMatch(JSON.stringify(trace), /fixture-private-question/); |
| 49 | }); |
| 50 | |
| 51 | test('automatic consent never becomes a human wait and turn completion closes only its own requests', () => { |
| 52 | const automatic = read([ |
| 53 | row(1, 'approval.required', 0, { id: 'auto' }), |
| 54 | row(2, 'approval.decided', 500, { approval_id: 'auto', decision: 'allow', auto: true }), |
| 55 | ]); |
| 56 | assert.ok(compilePetTelemetry(automatic.events, 1200).every(b => !b.waiting && !b.observed)); |
| 57 | const trace = read([ |
| 58 | row(1, 'user_input.required', 0, { id: 'same' }), |
| 59 | row(2, 'user_input.required', 100, { id: 'same' }, 'turn-b'), |
| 60 | row(3, 'turn.completed', 2000, { turn: { status: 'completed' } }), |
| 61 | ]); |
| 62 | const requests = trace.events.filter(e => e.name === 'user_input.required'); |
| 63 | assert.equal(requests[0].openEnded, false); assert.equal(requests[0].endTime, 2000); |
| 64 | assert.equal(requests[1].openEnded, true); |
| 65 | assert.throws(() => read([row(1, 'user_input.required', 0, {})]), /identity/); |
| 66 | }); |
| 67 | |
| 68 | test('only a healthy live observation extends a witnessed request; static imports and open tools stay unknown', () => { |
| 69 | const trace = read([ |
| 70 | row(1, 'user_input.required', 0, { id: 'wait' }), |
| 71 | row(2, 'item.started', 100, { item: { id: 'work', kind: 'tool_call', status: 'running' }, tool: 'bash' }), |
| 72 | ]); |
| 73 | const snapshot = JSON.stringify(trace); |
| 74 | assert.equal(compilePetTelemetry(trace.events, 30_000)[70].observed, 0); |
| 75 | const live = observeRuntimeRequests(trace, epoch + 30_000); |
| 76 | const tape = compilePetTelemetry(live.events, live.duration); |
| 77 | assert.equal(tape[70].waiting, true); assert.equal(tape[70].activeMs[11], 400); |
| 78 | assert.equal(tape[70].activeMs[3], 0); assert.equal(JSON.stringify(trace), snapshot); |
| 79 | assert.throws(() => observeRuntimeRequests(trace, NaN), /horizon/); |
| 80 | }); |
| 81 | |
| 82 | test('a fixed recorder clock survives older source origins without replaying historical failures or shifting onsets', () => { |
| 83 | const event = { schemaVersion: 1, id: 'work', traceId: 't', startTime: 0, endTime: 1000, |
| 84 | agentId: 'parent', name: 'bash', category: 'code', status: 'error', attributes: { 'whalesong.error_onset_ms': 3000 } }; |
| 85 | const tape = compilePetTelemetry([event], 3600, 0, 400); |
| 86 | const shifted = { ...event, startTime: 5000, endTime: 6000, attributes: { 'whalesong.error_onset_ms': 8000 } }; |
| 87 | assert.deepEqual(compilePetTelemetry([shifted], 8600, 0, 5400), tape); |
| 88 | assert.equal(tape[6].errors, 1); assert.equal(tape[0].onsets[3], 0); |
| 89 | assert.equal(compilePetTelemetry([event], 4400, 0, 4000).reduce((sum, b) => sum + b.errors, 0), 0); |
| 90 | const normalized = read([row(1, 'item.completed', 3000, { item: { id: 'done', kind: 'tool_call', started_at: stamp(1000), ended_at: stamp(2000), status: 'failed' } })]); |
| 91 | assert.equal(normalized.originTime, stamp(1000)); |
| 92 | assert.equal(normalized.events[0].attributes['whalesong.error_onset_ms'], 2000); |
| 93 | const generic = importTrace(JSON.stringify([shifted]), 'event-v1', { privacy: 'metadata' })[0]; |
| 94 | assert.equal(generic.events[0].attributes['whalesong.error_onset_ms'], 3000); |
| 95 | assert.throws(() => compilePetTelemetry([{ ...event, attributes: { 'whalesong.error_onset_ms': -1 } }]), /failure observation/); |
| 96 | }); |
| 97 |