/** * One ruling's record: the judge's account in one sentence, what lookout * observed in the repository, and the attempt as state.json keeps it. * * Both channels rule the same way and write the same shape, and they used to * do it from two copies of the code. This is the one copy, so a fact added to * the record reaches both verify-fix and the source-scan ruling at once. */ import { type AttemptRecord, type RepoObservation, type RulingBaseline } from "../fix/state.js"; import { type ShotMove } from "./moved.js"; import type { PixelDiff } from "./pixels.js"; import type { Verdict } from "../fix/rule.js"; import type { ResolvedConfig, ShotRecord } from "../types.js"; export interface JudgeNoteInput { nothingChanged: boolean; baselineShots: number; /** Every screenshot in the verify scope, changed or not. */ totalShots: number; stillOpen: { observed: string; }[]; unmet: { text: string; }[]; unclosable: { route: string; }[]; } /** * What the judge still sees, as one sentence: the first thing that explains * why this attempt did not pass, from the cause that forecloses the others * (nothing was re-rendered) down to the one that only matters once every * other check is clean. */ export declare function judgeNoteFor(i: JudgeNoteInput): string; export declare function narrowingFlags(flags: Record): Record | undefined; /** HEAD of the target repository, when it is a git checkout. */ export declare function headSha(cwd: string): Promise; /** * What git says about the repository at ruling time. A claim in `--note` is * the fixer's; this is lookout's own observation, and it answers the two * questions a second attempt asks first: was anything committed, and did the * change land in the files the fix was meant to touch. `.lookout/` is left * out of the dirty list, because the ruling itself is what writes there. * Undefined when the project is not a git checkout. */ export declare function observeRepo(cwd: string, previousCommit?: string | null, commit?: string | null): Promise; export interface AttemptInput { n: number; commit?: string | null; note?: string | null; verdict: Verdict; judgeNote?: string; spawned?: string[]; runId?: string; totalShots?: number; changedShots?: number; baselineShots?: number; moved?: ShotMove[]; stillOpen?: { title: string; shotId: string; observed: string; }[]; unclosable?: string[]; criteria?: { id: string; text: string; verdict: string; note?: string; }[]; contactSheet?: string | null; flags?: Record; observed?: RepoObservation; baseline?: AttemptRecord["baseline"]; } /** The attempt as state.json keeps it: nothing absent is written as empty. */ export declare function attemptRecord(a: AttemptInput): AttemptRecord; /** * One ruling, recorded: what the repository looked like, the attempt itself, * and this capture becoming the baseline the next ruling is measured against. * * Assembled here rather than in the verb, because both the shape of the record * and the order of the writes are facts about the record, not about the * command. The two derived lists come back out because the outcome report * prints the same ones. */ export declare function recordRuling(a: { resolved: ResolvedConfig; issueId: string; n: number; commit?: string | null; note?: string | null; verdict: Verdict; judgeNote: string; spawned: string[]; runId: string; shotsById: ReadonlyMap; changedShots: ReadonlySet; baselineShots: number; /** How far each changed shot moved, for the shots that could be measured. */ changes: ReadonlyMap; stillOpen: { title: string; observed: string; evidence: { shotId: string; }[]; }[]; unclosable: { route: string; }[]; criteria: { id: string; text: string; verdict: string; note?: string; }[]; contactSheet: string | null; flags: Record; baseline: AttemptRecord["baseline"]; }): Promise<{ stillOpen: { title: string; shotId: string; observed: string; }[]; unclosable: string[]; observed?: RepoObservation; }>; /** The last attempt recorded for an issue, for what the next one is measured against. */ export declare function previousAttempt(resolved: ResolvedConfig, issueId: string): Promise; /** * Write the attempt, and when the ruling captured anything, make its capture * the baseline the next ruling is measured against. */ export declare function recordAttempt(resolved: ResolvedConfig, issueId: string, attempt: AttemptRecord, baseline?: RulingBaseline): Promise;