/** * Whether a finding's problem text is written for both of its readers. * * The rubric asks the judge for a `problem` in two parts: a plain sentence a * person who has never seen the screen can follow, then the precise statement * an agent acts on, separated by a blank line. Nothing on the code side read * that rule, so a reply that skipped the plain half, or repeated the title, * was ingested as written and the document had two places quietly hiding * the degenerate case at render time. This is the one bar, used at ingest * (to count the lapse), by the refuter (to know when its own sentence is * needed), by `backlog check` (to flag the record) and by the renderers. */ export type ProseLapse = "empty" | "title-again" | "one-part" | "plain-too-short" | "label-in-plain"; /** The plain half and the precise half, split on the first blank line. */ export declare function splitProblem(problem: string): { plain: string; detail: string | null; }; /** The lapses in a problem text, worst first; empty when it meets the bar. */ export declare function problemLapses(f: { title: string; problem: string; attribute?: string; }): ProseLapse[]; /** The degenerate case a renderer drops: nothing, or the title over again. */ export declare function isTitleAgain(problem: string, title: string): boolean; /** Written for both readers: no hard lapse. The soft ones are advice, not failure. */ export declare function isExplained(problem: string, title: string): boolean; /** * The refuter's plain sentence, put above the judge's text when the judge * wrote none, never in place of it. Null when the sentence fails the same * bar it is meant to satisfy, or is too long to be the plain half. */ export declare function withPlainHalf(problem: string, plain: string, title: string, attribute?: string): string | null;