/**
 * MachineLoadBroker — the machine-local shared-load accounting for L6 (Multi-Agent-
 * Per-Machine). Multiple instar agents share one machine; each agent's router must
 * see the TRUE machine load, not just its own, so it won't pile sessions onto a
 * machine another agent is already saturating.
 *
 * Critically, the broker does NOT trust agent self-reports for the authoritative
 * number (Structure > Willpower — "no cross-agent trust required" only holds if an
 * agent cannot lie itself idle). The MACHINE independently reads OS ground truth
 * (loadavg, process footprint); agents report only their own session count + claimed
 * footprint; the broker CROSS-CHECKS and, when an agent under-reports its footprint
 * beyond `loadReportDivergenceTolerance`, marks it `suspect-overloaded`, reduces its
 * placement weight, and escalates — so a lying agent cannot make itself look idle.
 *
 * Pure functions over their inputs — no I/O, no clock; the caller samples the OS.
 */
const SUSPECT_PLACEMENT_WEIGHT = 0.1;
/**
 * Compute the machine's shared load view from OS ground truth + agent self-reports.
 * Accounts for ALL resident agents' sessions. Cross-checks each agent's claimed
 * footprint against its OS-measured footprint; an agent measured to use materially
 * MORE than it claims (the lie-idle case) is flagged `suspect-overloaded`. Pure.
 */
export function computeMachineLoad(input) {
    const tolerance = input.loadReportDivergenceTolerance ?? 0.20;
    const measuredByAgent = new Map();
    for (const s of input.osSamples) {
        measuredByAgent.set(s.agentId, (measuredByAgent.get(s.agentId) ?? 0) + s.measuredFootprintMB);
    }
    const verdicts = input.agentReports.map((r) => {
        const measured = measuredByAgent.get(r.agentId) ?? 0;
        const denom = Math.max(r.reportedFootprintMB, 1);
        const divergence = (measured - r.reportedFootprintMB) / denom;
        // Only an UNDER-report (measured materially exceeds claimed) is dangerous — it lets
        // an agent look idle while saturating the machine. Over-reporting is conservative.
        const suspect = divergence > tolerance;
        return {
            agentId: r.agentId,
            status: suspect ? 'suspect-overloaded' : 'ok',
            reportedFootprintMB: r.reportedFootprintMB,
            measuredFootprintMB: measured,
            divergence,
            placementWeight: suspect ? SUSPECT_PLACEMENT_WEIGHT : 1.0,
        };
    });
    const suspectAgents = verdicts.filter((v) => v.status === 'suspect-overloaded').map((v) => v.agentId);
    const activeSessionCount = input.agentReports.reduce((sum, r) => sum + Math.max(0, r.reportedSessionCount), 0);
    return {
        loadAvg: input.loadAvg,
        activeSessionCount,
        sessionCountTrustworthy: suspectAgents.length === 0,
        agentVerdicts: verdicts,
        suspectAgents,
    };
}
/**
 * Verify the L6 isolation invariant: resident agents never share a port or identity,
 * and no agent's home dir is nested inside another's (which would let one read/write
 * the other's state). Pure — returns the list of violations (empty = isolated).
 */
export function checkAgentIsolation(agents) {
    const violations = [];
    const byPort = new Map();
    const byFp = new Map();
    for (const a of agents) {
        byPort.set(a.port, [...(byPort.get(a.port) ?? []), a.agentId]);
        byFp.set(a.identityFingerprint, [...(byFp.get(a.identityFingerprint) ?? []), a.agentId]);
    }
    for (const [port, ids] of byPort)
        if (ids.length > 1)
            violations.push({ kind: 'duplicate-port', port, agents: ids });
    for (const [fingerprint, ids] of byFp)
        if (ids.length > 1)
            violations.push({ kind: 'duplicate-fingerprint', fingerprint, agents: ids });
    const norm = (p) => (p.endsWith('/') ? p : p + '/');
    for (const a of agents) {
        for (const b of agents) {
            if (a.agentId === b.agentId)
                continue;
            if (norm(b.homeDir).startsWith(norm(a.homeDir))) {
                violations.push({ kind: 'nested-home', outer: a.homeDir, inner: b.homeDir });
            }
        }
    }
    return violations;
}
//# sourceMappingURL=MachineLoadBroker.js.map