/** * federation/trust.ts — TrustEvaluator: peer allowlist + recent fail * rate + envelope age → trust score. * * F-038 — ported from ruflo * `v3/@claude-flow/plugin-agent-federation/src/application/trust-evaluator.ts` * (computeScore shape), stripped down for the skeleton: * * evaluate(envelope, peer) → { allowed, reason, score } * * Inputs: * - peer (PeerState): { nodeId, allowlisted, recentFailRate, lastSeenMs } * - envelope: FederationEnvelope * * Scoring (pure function): * baseScore = peer.allowlisted ? 0.6 : 0.0 * freshness = clamp(1 - ageMs / MAX_AGE_MS, 0, 1) * 0.2 * reliability = clamp(1 - peer.recentFailRate, 0, 1) * 0.2 * score = baseScore + freshness + reliability * * Decision: * allowed = peer.allowlisted AND ageMs <= MAX_AGE_MS AND score >= MIN_SCORE * * State — per-node recent fail rate + last-seen are tracked * in a Map so repeated calls from the same peer update the * picture. Failures can be recorded via `recordFailure(nodeId)`. */ import { type FederationEnvelope } from "./envelope.js"; /** Maximum envelope age we'll trust (5 minutes — matches the * HMAC freshness window). Older envelopes fail freshness * independently of HMAC verification. */ export declare const MAX_TRUST_AGE_MS: number; /** Minimum composite trust score required to admit an envelope. */ export declare const MIN_TRUST_SCORE = 0.7; export interface PeerState { readonly nodeId: string; readonly allowlisted: boolean; /** Failure rate over the last `FAILURE_WINDOW` calls (0..1). */ readonly recentFailRate: number; /** Last activity timestamp (ms epoch). Used as a tiebreaker. */ readonly lastSeenMs?: number; } export type TrustDecision = { allowed: true; score: number; reason: string; } | { allowed: false; score: number; reason: string; }; export declare class TrustEvaluator { private readonly allowlist; private readonly failHistory; constructor(opts?: { allowlist?: readonly string[]; }); /** Add or remove a node from the trust allowlist at runtime. */ setAllowlisted(nodeId: string, allowlisted: boolean): void; isAllowlisted(nodeId: string): boolean; /** Snapshot the per-peer state seen by `evaluate()`. */ getPeerState(nodeId: string, _now?: number): PeerState; /** Record that an exchange with `nodeId` succeeded/failed. Sliding * window of `FAILURE_WINDOW` most-recent events. */ recordOutcome(nodeId: string, ok: boolean, now?: number): void; /** Compute the trust score (0..1). Pure function — useful for tests * and for the orchestrator's `status` tool. * * baseScore = 0.3 if allowlisted else 0.0 (allowlist is necessary, not sufficient) * freshness = (1 - ageMs / MAX_TRUST_AGE_MS) * 0.3 (envelope must be fresh) * reliability = (1 - peer.recentFailRate) * 0.4 (peer must be reliable) * * MIN_TRUST_SCORE = 0.5 — a peer needs AT LEAST 2 of the 3 axes * in good standing to pass. */ computeScore(envelope: FederationEnvelope, peer: PeerState, now?: number): number; /** Admit or reject an envelope based on the per-peer trust state. */ evaluate(envelope: FederationEnvelope, peer: PeerState, now?: number): TrustDecision; } //# sourceMappingURL=trust.d.ts.map