import test from 'node:test'; import assert from 'node:assert/strict'; import { createAlertEngine } from '../src/core/alert-engine.mjs'; function createEngine() { return createAlertEngine({ activePair: 'nep141:btc.omft.near->nep141:eure.omft.near', priceStaleMs: 30_000, inventoryStaleMs: 30_000, fundingCreditPendingMs: 300_000, fundingStuckMs: 3_600_000, evaluationIntervalMs: 5_000, }); } function createMultiRouteEngine() { return createAlertEngine({ activePair: 'nep141:btc.omft.near->nep141:eure.omft.near', activePairs: [ 'nep141:btc.omft.near->nep141:eure.omft.near', 'nep141:btc.omft.near->nep141:usdc.omft.near', ], priceRoutes: [ { pair: 'nep141:btc.omft.near->nep141:eure.omft.near', price_route_id: 'btc-eur-route', reference_pair: 'BTC/EUR', }, { pair: 'nep141:btc.omft.near->nep141:usdc.omft.near', price_route_id: 'btc-usdc-route', reference_pair: 'BTC/USDC', }, ], priceStaleMs: 30_000, inventoryStaleMs: 30_000, fundingCreditPendingMs: 300_000, fundingStuckMs: 3_600_000, evaluationIntervalMs: 5_000, }); } test('alert engine raises and clears stale state transitions', () => { const engine = createEngine(); let transitions = engine.applyEvent('ref.market_price', { price_id: 'price-1', pair: 'nep141:btc.omft.near->nep141:eure.omft.near', eur_per_btc: '100000', btc_per_eure: '0.00001', observed_at: '2026-04-03T08:00:00.000Z', }, '2026-04-03T08:00:00.000Z'); assert.equal(transitions.length, 1); assert.equal(transitions[0].alert_code, 'inventory_snapshot_stale'); assert.equal(transitions[0].status, 'raised'); transitions = engine.applyEvent('state.intent_inventory', { inventory_id: 'inventory-1', account_id: 'solver.near', reconciliation_status: 'ok', spendable: { 'nep141:btc.omft.near': '1000' }, synced_at: '2026-04-03T08:00:00.000Z', }, '2026-04-03T08:00:00.000Z'); assert.equal(transitions.length, 1); assert.equal(transitions[0].alert_code, 'inventory_snapshot_stale'); assert.equal(transitions[0].status, 'cleared'); transitions = engine.evaluate('2026-04-03T08:00:31.000Z'); assert.equal(transitions.length, 2); assert.deepEqual( transitions.map((transition) => `${transition.alert_code}:${transition.status}`).sort(), [ 'inventory_snapshot_stale:raised', 'reference_price_stale:raised', ], ); transitions = engine.applyEvent('ref.market_price', { price_id: 'price-2', pair: 'nep141:btc.omft.near->nep141:eure.omft.near', eur_per_btc: '100100', btc_per_eure: '0.00000999', observed_at: '2026-04-03T08:00:32.000Z', }, '2026-04-03T08:00:32.000Z'); assert.equal(transitions.length, 1); assert.equal(transitions[0].alert_code, 'reference_price_stale'); assert.equal(transitions[0].status, 'cleared'); }); test('executor submission failure produces an alert event and clears on recovery', () => { const engine = createEngine(); engine.applyEvent('ref.market_price', { price_id: 'price-1', pair: 'nep141:btc.omft.near->nep141:eure.omft.near', eur_per_btc: '100000', btc_per_eure: '0.00001', observed_at: '2026-04-03T08:00:00.000Z', }, '2026-04-03T08:00:00.000Z'); engine.applyEvent('state.intent_inventory', { inventory_id: 'inventory-1', account_id: 'solver.near', reconciliation_status: 'ok', spendable: { 'nep141:btc.omft.near': '1000' }, synced_at: '2026-04-03T08:00:00.000Z', }, '2026-04-03T08:00:00.000Z'); let transitions = engine.applyEvent('exec.trade_result', { command_id: 'cmd-1', quote_id: 'quote-1', pair: 'nep141:btc.omft.near->nep141:eure.omft.near', status: 'failed', result_code: 'submission_failed', error: { message: 'relay timeout' }, }, '2026-04-03T08:00:10.000Z'); assert.equal(transitions.length, 1); assert.equal(transitions[0].alert_code, 'executor_submission_failed'); assert.equal(transitions[0].status, 'raised'); transitions = engine.applyEvent('exec.trade_result', { command_id: 'cmd-2', quote_id: 'quote-2', pair: 'nep141:btc.omft.near->nep141:eure.omft.near', status: 'submitted', result_code: 'quote_response_ok', }, '2026-04-03T08:00:20.000Z'); assert.equal(transitions.length, 1); assert.equal(transitions[0].alert_code, 'executor_submission_failed'); assert.equal(transitions[0].status, 'cleared'); }); test('runtime alerts raise and clear independently from event-derived alerts', () => { const engine = createEngine(); let transitions = engine.applyRuntimeAlerts([{ alert_code: 'near_intents_quotes_stale', severity: 'critical', reason: 'quotes are stale', service_scope: 'near-intents-ingest', pair: 'nep141:btc.omft.near->nep141:eure.omft.near', asset_id: null, tx_hash: null, details: { age_ms: 100_000, }, }], '2026-04-03T08:00:00.000Z'); assert.equal(transitions.length, 1); assert.equal(transitions[0].alert_code, 'near_intents_quotes_stale'); assert.equal(transitions[0].status, 'raised'); transitions = engine.applyRuntimeAlerts([], '2026-04-03T08:00:05.000Z'); assert.equal(transitions.length, 1); assert.equal(transitions[0].alert_code, 'near_intents_quotes_stale'); assert.equal(transitions[0].status, 'cleared'); }); test('reference price stale alert is scoped to the affected route and pair', () => { const engine = createMultiRouteEngine(); const transitions = engine.applyEvent('ref.market_price', { price_id: 'price-eur-1', pair: 'nep141:btc.omft.near->nep141:eure.omft.near', price_route_id: 'btc-eur-route', reference_pair: 'BTC/EUR', quote_per_base: '50000', observed_at: '2026-04-03T08:00:00.000Z', }, '2026-04-03T08:00:00.000Z'); engine.applyEvent('state.intent_inventory', { inventory_id: 'inventory-1', spendable: {}, synced_at: '2026-04-03T08:00:00.000Z', }, '2026-04-03T08:00:00.000Z'); const stale = transitions.find((entry) => entry.alert_code === 'reference_price_stale'); assert.equal(stale.status, 'raised'); assert.equal(stale.pair, 'nep141:btc.omft.near->nep141:usdc.omft.near'); assert.equal(stale.details.price_route_id, 'btc-usdc-route'); assert.equal(stale.details.reference_pair, 'BTC/USDC'); assert.deepEqual(stale.details.active_pairs, [ 'nep141:btc.omft.near->nep141:eure.omft.near', 'nep141:btc.omft.near->nep141:usdc.omft.near', ]); assert.deepEqual(engine.getState('2026-04-03T08:00:10.000Z').active_pairs, [ 'nep141:btc.omft.near->nep141:eure.omft.near', 'nep141:btc.omft.near->nep141:usdc.omft.near', ]); });