/** * View groups, and the batches they are judged in. * * A view group is one route and state across its form factors and colour * schemes, and it is the unit almost everything here counts in: the rubric * compares within it, the ledger caches by it, and a batch is one of them. * Making the batch any larger buys nothing the judge can use and holds every * finding in it hostage until the whole batch returns, which on full-page * screenshots ran to several silent minutes. */ import type { ShotRecord } from "../types.js"; export declare function kebab(s: string): string; /** Pack shots into judge batches: same target+route stays together, max size. */ /** * The view a shot belongs to: everything the rubric compares across. * * Structural in its argument so a frozen case, which carries the same four axes * without being a ShotRecord, can be grouped by the identical formula rather * than by a copy of it. */ export declare function viewGroupId(shot: Pick): string; /** Partition shots into view groups, preserving encounter order. */ export declare function groupShots(shots: ShotRecord[]): Map; /** * One judge call per VIEW GROUP: the same unit the rubric compares within, and * the same unit the ledger caches. * * This used to pack several small groups into one call to save subprocesses, * which quietly broke the cache. The rubric asks for one finding per distinct * defect, filed on the most representative shot, with the other affected shots * named in the prose. When two groups shared a batch and shared a defect, the * judge filed it against one of them and the contract then put the other * group's shots in `cleanShotIds`, so that view was recorded clean and a later * scoped re-check served "clean" from cache while the defect stood. Keeping the * prompt unit and the ledger unit identical is what makes a cached verdict mean * anything. * * A group is never split either: a comparison needs both sides in one context. */ export declare function batchShots(shots: ShotRecord[]): ShotRecord[][];