/** * Ingesting a judge reply: the output contract, enforced. * * The reply is model output and nothing in it is trusted. A category outside * the vocabulary, a severity off the ladder, or a shot id not in the batch * rejects the finding with an incident; a mangled region degrades to * "content" so the finding survives; and every shot must appear in findings * or cleanShotIds, because a shot in neither is one the judge did not rule * on. When the caller names a panel, the vocabulary narrows to that panel's * lane: a specialist filing a category another panel owns is a contract * failure even though the category exists, because the owner would file the * same defect and one defect must stay one finding. */ import type { ShotRecord } from "../types.js"; import { type ProseLapse } from "../backlog/prose.js"; import { type Category } from "./rubric.js"; import type { AiFinding } from "./engine.js"; /** The lane a panel judges in: its name, and the categories it may file. */ export interface PanelLane { name: string; categories: readonly Category[]; /** Whether this lane is shown each shot's accessibility tree. */ aria?: boolean; } /** A finding that survived ingestion with a problem written for one reader. */ export interface ContractLapse { shotId: string; category: string; title: string; judge: string; lapses: ProseLapse[]; } export interface IngestedReply { findings: AiFinding[]; cleanShotIds: string[]; unaccounted: string[]; rejected: { reason: string; raw: unknown; }[]; /** * Findings kept although their problem fails the two-part bar. Rejecting * them would throw away a real defect over its prose; counting them is * what lets the panel that wrote them be taught. */ degraded: ContractLapse[]; } export declare function ingestJudgeReply(parsed: unknown, args: { shots: ShotRecord[]; project?: string; panel?: PanelLane; }): IngestedReply;