unrip/test/alert-engine.test.mjs
philipp 0b7e5e2e6c
All checks were successful
deploy / deploy (push) Successful in 26s
Implement runtime health sentinel and angry dashboard
Proof: Runtime health sentinel, alert routing, and anomaly detection for stale/disconnected quote truth, truthful dashboard severity, webhook notifications, and safe executor containment.

Assumptions: Existing control APIs remain the service-local truth surface; external notification stays as a generic webhook sink; executor disarm is an allowed non-fund-moving containment action; current dashboard/operator files in the worktree belong to this turn and are intended to ship together.

Still fake: No live external receiver is configured; webhook delivery is implemented but unverified end-to-end in production; cluster rollout still depends on deploying the new image; no automatic deployment restart path was added.
2026-04-08 19:35:07 +02:00

129 lines
4.5 KiB
JavaScript

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,
});
}
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');
});