Add mining self-surgery for on-host recovery when AI control detects stalls.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

When ai_control_enabled and mining interrupts or hashrate drops, the server composes same-agent fix plans (container restart, chain reorder, GPU swap, idle tune, RandomX restart) with Seer and oath ledger audit — no spread or lateral escalation.
This commit is contained in:
AetherForge
2026-06-07 09:27:26 -07:00
parent d605ef4adb
commit fac324ff80
18 changed files with 1166 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
import { describe, expect, it } from 'vitest';
import { isMiningSelfSurgeryEvent, miningSelfSurgerySummary } from './miningSelfSurgery';
describe('miningSelfSurgery', () => {
it('detects mining_self_surgery seer events', () => {
expect(isMiningSelfSurgeryEvent({ event_type: 'mining_self_surgery' })).toBe(true);
expect(isMiningSelfSurgeryEvent({ event_type: 'surgical_replay' })).toBe(false);
});
it('summarizes trigger, actions, and outcome', () => {
const summary = miningSelfSurgerySummary({
event_type: 'mining_self_surgery',
payload: {
trigger: 'mining_interrupt',
actions: ['container_restart', 'randomx_restart'],
outcome: 'ok',
},
});
expect(summary).toContain('mining_interrupt');
expect(summary).toContain('container_restart');
expect(summary).toContain('ok');
});
it('never mentions spread commands in summary helper', () => {
const summary = miningSelfSurgerySummary({
event_type: 'mining_self_surgery',
payload: { trigger: 'low_hashrate', actions: ['idle_threshold_tune'] },
});
expect(summary).not.toContain('discover');
expect(summary).not.toContain('spread');
});
});

View File

@@ -0,0 +1,21 @@
import type { SeerEventRecord } from './seerEvents';
/** Seer feed row for on-host mining self-surgery (no spread). */
export function isMiningSelfSurgeryEvent(event: SeerEventRecord): boolean {
return event.event_type === 'mining_self_surgery';
}
export function miningSelfSurgerySummary(event: SeerEventRecord): string {
if (!isMiningSelfSurgeryEvent(event)) {
return '';
}
const p = event.payload ?? {};
const trigger = typeof p.trigger === 'string' ? p.trigger : 'mining';
const outcome = typeof p.outcome === 'string' ? p.outcome : '';
const actions = Array.isArray(p.actions) ? p.actions.join(', ') : '';
const base = `Mining self-surgery (${trigger})`;
if (actions) {
return `${base}: ${actions}${outcome ? `${outcome}` : ''}`;
}
return outcome ? `${base}${outcome}` : base;
}