Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Archive failed epidemiology strains to museum hospice with SQLite persistence, operator/AI/court triggers, breeding and graft guards, topology museum nodes, and Seer plus oath ledger accountability.
83 lines
3.4 KiB
TypeScript
83 lines
3.4 KiB
TypeScript
/** Seer feed event from WS `seer_events` or GET /api/v1/seer/stream. */
|
|
export interface SeerEventRecord {
|
|
id?: number;
|
|
event_type: string;
|
|
agent_id?: string;
|
|
payload?: Record<string, unknown>;
|
|
ts?: string;
|
|
}
|
|
|
|
export function isPathTraceTimelineEvent(event: SeerEventRecord): boolean {
|
|
return event.event_type === 'pathtrace_timeline';
|
|
}
|
|
|
|
export function isOnionMinerLogEvent(event: SeerEventRecord): boolean {
|
|
return event.event_type === 'onion_miner_log';
|
|
}
|
|
|
|
export function onionMinerLogSummary(event: SeerEventRecord): string {
|
|
if (!isOnionMinerLogEvent(event)) return '';
|
|
const p = event.payload ?? {};
|
|
const method = typeof p.method === 'string' ? p.method : 'branch';
|
|
const outcome = typeof p.outcome === 'string' ? p.outcome : 'update';
|
|
const depth = typeof p.contingency_depth === 'number' ? p.contingency_depth : undefined;
|
|
const ghost = p.is_ghost === true ? ' · ghost' : '';
|
|
const hr = typeof p.hashrate === 'number' && p.hashrate > 0 ? ` · ${Math.round(p.hashrate)} H/s` : '';
|
|
if (outcome === 'exhausted') {
|
|
return `Contingency exhausted${depth != null ? ` · depth ${depth}` : ''} — awaiting court branch params`;
|
|
}
|
|
if (outcome === 'strain_retired') {
|
|
return 'Contingency hospice — strain retired after max exhaustion cycles';
|
|
}
|
|
if (outcome === 'won' || outcome === 'ghost_won') {
|
|
return `Contingency ${method} linked${hr}${ghost}${depth != null ? ` · depth ${depth}` : ''}`;
|
|
}
|
|
return `Contingency ${method} ${outcome}${ghost}${depth != null ? ` · depth ${depth}` : ''}`;
|
|
}
|
|
|
|
export function pathTraceTimelineSummary(event: SeerEventRecord): string {
|
|
if (!isPathTraceTimelineEvent(event)) return '';
|
|
const p = event.payload ?? {};
|
|
const ev = typeof p.event === 'string' ? p.event : 'update';
|
|
const branch = p.branch as { persona?: string; status?: string; hashrate?: number } | undefined;
|
|
if (ev === 'fork') return 'Path Tracer fork — ghost branches spawned';
|
|
if (ev === 'branch_won') {
|
|
return `Path Tracer branch won (${branch?.persona ?? 'unknown'})${branch?.hashrate ? ` · ${Math.round(branch.hashrate)} H/s` : ''}`;
|
|
}
|
|
if (ev === 'merge') return `Path Tracer merged ${branch?.persona ?? 'winner'} into canonical timeline`;
|
|
return `Path Tracer timeline ${ev}`;
|
|
}
|
|
|
|
export function isSurgicalReplayEvent(event: SeerEventRecord): boolean {
|
|
return event.event_type === 'surgical_replay';
|
|
}
|
|
|
|
export { isMiningSelfSurgeryEvent, miningSelfSurgerySummary } from './miningSelfSurgery';
|
|
|
|
export function surgicalReplaySummary(event: SeerEventRecord): string {
|
|
if (!isSurgicalReplayEvent(event)) {
|
|
return '';
|
|
}
|
|
const p = event.payload ?? {};
|
|
const tier = typeof p.failed_tier === 'string' ? p.failed_tier : 'tier';
|
|
const fix = typeof p.fix_type === 'string' ? p.fix_type : 'fix';
|
|
const outcome = typeof p.outcome === 'string' ? p.outcome : '';
|
|
return `Surgical replay ${tier} → ${fix}${outcome ? ` (${outcome})` : ''}`;
|
|
}
|
|
|
|
export function mergeSeerEvents(
|
|
existing: SeerEventRecord[],
|
|
incoming: SeerEventRecord | SeerEventRecord[],
|
|
): SeerEventRecord[] {
|
|
const batch = Array.isArray(incoming) ? incoming : [incoming];
|
|
const seen = new Set(existing.map((e) => `${e.id ?? ''}:${e.event_type}:${e.ts ?? ''}`));
|
|
const merged = [...existing];
|
|
for (const ev of batch) {
|
|
const key = `${ev.id ?? ''}:${ev.event_type}:${ev.ts ?? ''}`;
|
|
if (seen.has(key)) continue;
|
|
seen.add(key);
|
|
merged.unshift(ev);
|
|
}
|
|
return merged.slice(0, 200);
|
|
}
|