import { type PanelLane } from "./reply.js"; import type { AiFinding } from "./engine.js"; import type { ShotRecord } from "../types.js"; import type { FindingConsensus, OracleId } from "../backlog/consensus.js"; /** One ruling on one of the first judge's findings. */ export interface ChallengeVerdict { index: number; verdict: "agree" | "dispute" | "amend"; note?: string; } /** What a challenge round produced. */ export interface ChallengeReply { verdicts: ChallengeVerdict[]; additions: AiFinding[]; /** Rows the reply got wrong, for the incident log. */ rejected: { reason: string; raw: unknown; }[]; } /** * The findings, numbered, as the challenger will address them. * * Category and attribute are shown because they are context a judge needs to * rule, and the skill tells it not to change them. Everything the challenger * sends back is keyed on the number in front. */ export declare function numberFindings(findings: readonly AiFinding[]): string; /** * The challenger's reply, turned into rulings and new findings. * * `count` is how many findings were put to it, so an index outside that range * can be rejected rather than silently indexing into nothing. */ export declare function ingestChallenge(parsed: unknown, args: { count: number; shots: ShotRecord[]; project?: string; panel?: PanelLane; }): ChallengeReply; /** The challenger's reply text, parsed, or the reason it was not usable. */ export declare function parseChallenge(text: string, args: { count: number; shots: ShotRecord[]; project?: string; panel?: PanelLane; }): ChallengeReply | null; /** * What the two judges concluded about one finding. * * A finding nobody ruled on gets a consensus naming only its reporter, so the * record still says who filed it. Silence from a challenger is not agreement * and is not recorded as any. */ export declare function consensusFor(proposer: OracleId, challenger: OracleId, verdict: ChallengeVerdict | undefined, rounds: number): FindingConsensus;