import type { AuditTask } from "../types.js"; import { type ValidationIssue } from "audit-tools/shared"; export type IssueSeverity = "error" | "warning"; /** * THE one statement of each finding/result rule that is NOT expressible as a * per-finding zod refinement — it needs cross-record context (the declared * coverage, the zero/positive finding count) or the assigned task. The dispatch * prompt's contract block renders every `statement` verbatim * (`findingContractPromptLines`), and each validator site below emits its issue * message FROM its registry entry, so the prompt the tool generates states * exactly what the validator enforces: one source, not two. * * Rules expressible IN the schemas are not here — they live where they are * enforced (the finding/location contracts in `audit-tools/shared`, which the * prompt renders from `WorkerFindingSchema`). */ export declare const AUDIT_RESULT_RULES: readonly [{ readonly id: "affected_span_within_coverage"; readonly statement: "Every affected_files line span must fall inside the declared file_coverage for its file."; }, { readonly id: "reviewed_clean_affirmation"; readonly statement: "A result with zero findings must set reviewed_clean: true; reviewed_clean must never be set when findings are reported."; }, { readonly id: "finding_lens_matches_task"; readonly statement: "Each finding's lens must match the assigned task lens (or be omitted to default from it)."; }]; /** Look up one registry entry by id (validator sites emit FROM this text). */ export declare function auditResultRule(id: (typeof AUDIT_RESULT_RULES)[number]["id"]): string; /** * True when a declared `total_lines` diverges from the actual line count by * enough to treat the result as semantically wrong (CE-009), rather than an S7 * advisory. Requires divergence past BOTH the absolute floor and the ratio; an * `expected` of 0 makes any delta past the floor significant (no ratio to take). */ export declare function isSignificantLineCountDivergence(got: number, expected: number): boolean; /** * THE ONE KEY SPACE for every path this module joins on: * coverage entries, affected-finding locations, followup-task file paths, the * line index, and the packet boundary. Delegates to the shared * {@link normalizeGraphPath} — the same normalizer `taskBuilder` applies once at * the coverage/flow-planning boundary — rather than re-deriving the rules here, * because two hand-rolled normalizers ARE two key spaces the moment one of them * learns something the other has not (this one previously stripped only a * LEADING `./`, so an interior `src/./x.ts` was a different key from `src/x.ts`). * * Case is preserved: a repo path is the identity of a real file on disk, and * lowercasing it would make two genuinely different files collide on * case-sensitive filesystems. * * An empty (or whitespace-only) path stays empty rather than becoming posix's * `"."`, so callers can keep testing `length > 0` for "no usable path". */ export declare function normalizeCoveragePath(path: string): string; export interface AuditResultIssue extends ValidationIssue { result_index: number; task_id: string; severity: IssueSeverity; field: string; } export interface ValidateAuditResultOptions { lineIndex?: Record; /** * Packet/unit boundary file list: the union of the file_paths of every sibling * task dispatched in the same packet. When provided and non-empty, the two * hard-reject evidence gates (`file_coverage` paths and * `verification.followup_tasks.file_paths`) are widened from the single task's * assigned files to this boundary — a result may declare coverage of, or queue * a followup over, any file a sibling task in the packet was assigned, without * a hard reject. `affected_files` stays warn-and-retain regardless (INV-09). * * Fail-closed: an empty/undefined boundary falls back to the per-task assigned * set, so the gates never widen by accident. */ boundaryPaths?: string[]; } /** * The PER-RESULT half of {@link validateAuditResults}, exported for callers * that must apply exactly the same rules to ONE result before admitting it — * the host-handoff ingest validates each converted result BEFORE writing it to * the accepted pair, so a result the batch gate would later reject is never * accepted in the first place. One rule body: this delegates to the same * internal `validateSingleAuditResult` the batch walk uses, so the two cannot * drift. * * Returns the issues (possibly empty); it never throws and never writes the * batch summary to stderr — a single-result caller surfaces outcomes in its own * vocabulary. */ export declare function validateOneAuditResult(result: unknown, tasks: AuditTask[], options?: ValidateAuditResultOptions): AuditResultIssue[]; export declare function validateAuditResults(results: unknown, tasks: AuditTask[], options?: ValidateAuditResultOptions): AuditResultIssue[]; export declare function formatAuditResultIssues(issues: AuditResultIssue[]): string; //# sourceMappingURL=auditResults.d.ts.map