import { type ScopeCheck } from "../config-scope.js"; import { type Backlog } from "../backlog/lib.js"; import type { DeterministicFinding, FormFactor, PlatformKind, ResolvedConfig, Scheme, ShotRecord } from "../types.js"; /** Mirrors the acceptance verifier's cap: one judgement, one context. */ export declare const MAX_FROZEN_SHOTS = 20; export interface RegressionClaim { category: string; attribute: string; /** * The panel that owns the category, stamped at freeze time. The gate decides * a mustFile claim at this granularity (verdict.ts), so the committed * manifest says so rather than leaving a reader to derive it. Optional * because manifests frozen before the field exists still grade. */ panel?: string; /** Why this claim stands: a human's reason, or the verifier's confirmation. */ why: string; } export interface RegressionCase { shotId: string; /** Filename under regression/shots/. */ file: string; target: string; route: string; routeName: string; state: string; formFactor: FormFactor; scheme: Scheme; platform: PlatformKind; width: number; height: number; /** * What lookout measured on this shot, and what scrolls in it. * * Carried because the refuter's prompt carries them in production, and a * gate that grades an amendment under different evidence than the run it is * grading is not grading that run. Optional: sets frozen before this field * existed still replay, with the evidence they were frozen with. */ deterministicFindings?: DeterministicFinding[]; scrollers?: ShotRecord["scrollers"]; /** True when the shot's provenance sidecar was copied beside it. */ provenance?: boolean; /** * True when the shot's accessibility-tree sidecar was copied beside it. * * Same argument as the findings above, and it applies harder: the integrity * and text panels are GIVEN the tree in production, so a replay without it * grades those two under evidence they never actually judge on. */ aria?: boolean; mustNotFile: RegressionClaim[]; mustFile: RegressionClaim[]; } export interface RegressionSet { note: string; frozenAt: string; cases: RegressionCase[]; } export declare function regressionDir(resolved: ResolvedConfig): string; export declare function regressionManifestPath(resolved: ResolvedConfig): string; export declare function loadRegressionSet(resolved: ResolvedConfig): Promise; /** * Can this set actually grade anything right now? * * The manifest is committed and the pixels are not, so a fresh clone has the * claims but not the evidence for them. That is a gate that cannot run, and a * gate that cannot run must never be mistaken for one that passed. */ export declare function usableCases(resolved: ResolvedConfig, set: RegressionSet): RegressionCase[]; /** * Which claims a backlog can settle, keyed by the screenshot that proves them. * Pure, so the selection can be argued with without touching disk: `inScope` * is the config's reach handed in rather than read here. */ export declare function claimsByShot(backlog: Backlog, inScope: ScopeCheck): Map; path: string; }>; /** * Freeze the settled claims into a set that survives an evidence clean. * * Shots carrying the most claims come first: the cap is on screenshots, and the * gate is stronger the more it can decide per image. * * `outOfScope` is how many settled screenshots the current config no longer * reaches. It is reported rather than persisted, because a set that comes back * empty for that reason needs a different answer from one that is empty because * nothing has been adjudicated. * * Selection is by shot and not by view group, which means a six-shot group can * come through as one. That matters for the two categories the rubric defines * as comparisons (responsive is "a smaller form factor losing content the * LARGER ONE has"; colour-scheme is about what happens "after a scheme * switch"), and it is tempting to drop such a claim here when its comparison * is not frozen alongside it. Deliberately not done: both categories also list * single-shot cases the judge can still file from one image, so dropping the * claim would delete settled evidence on an inference. A claim the current * skills genuinely cannot reproduce is caught by measurement instead, in the * gate's control round (gate.ts), which reports it as stale without deleting * anything from the committed record. */ export declare function freezeRegressionSet(resolved: ResolvedConfig, backlog: Backlog, now: string, max?: number): Promise<{ set: RegressionSet; outOfScope: number; }>; /** The frozen cases as shots the judge can be pointed at. */ export declare function casesAsShots(set: RegressionSet, runId?: string): ShotRecord[];