/** * Two-pass hub prioritization judge. * * Pass 1 (relevance): For filtered scope, applies pure-JS applyFilter with zero LLM calls. * For general/decision scopes, calls the injected LLM per finding and parses with * validateRelevanceVerdict (fail-closed: null drops the finding; decision scope additionally * drops findings whose relevantTo is "neither" or undefined). * * Pass 2 (prioritization): For each survivor, fans out the four hub lenses (urgency, impact, * effort, deadline-risk). Aggregate score = SUM of per-lens scores (0–40; 4 × 0–10). Reconcile: * STRICT MAJORITY, FAIL-CLOSED ON TIE: passVotes > failVotes → normal ranking; * passVotes ≤ failVotes → kept but tagged "flagged-for-review" (immutable copy, never mutate input). * * Final order: deterministic JS sort — aggregate score DESC, urgency DESC, severity DESC, * dueBy ASC (undefined LAST, treated as +Infinity), id ASC. LLM never emits the final order. */ import type { LLMClient } from "../providers/types.js"; import type { Finding } from "./finding.js"; import { type Scope } from "./scope.js"; /** * Two-pass hub prioritization judge. * * @param findings Pool of Finding[] to rank (input array and Finding objects are never mutated). * @param scope Ephemeral query scope — not persisted anywhere. * @param llm Injected LLMClient. Tests pass a ScriptedClient fake; Sprint 4 passes a real client. * @param now Injected clock for dueWithinDays math in filtered mode. Never call Date.now() here. * @returns Ranked Finding[]; tie-voted findings carry the "flagged-for-review" tag. */ export declare function rankFindings(findings: Finding[], scope: Scope, llm: LLMClient, now: Date): Promise; //# sourceMappingURL=judge.d.ts.map