/** * The findings-file grammar. One parser, more than one caller. * * Extracted from `commands/review.ts` because compliance packs need to parse the * same block format with one extra field, and `extractBulletField` was * module-private — so "extend the parsing shape" would have meant a second * grammar. `commands/transition.ts` already documents why that is forbidden: * *"ONE parser for one format. A second grammar for the same format is the bug * class this instance exists to prevent."* * * A second grammar would drift on exactly what a fresh one omits: the * `## F1: title [critical] [open]` heading form as well as the bullet form, the * status and severity normalisation, and the placeholder sentinels. A scaffolded * compliance file whose placeholder the compliance parser did not recognise would * satisfy control coverage with no review having happened. * * Nothing here is compliance-specific. `compliance/findings.ts` wraps it. * * Requirements: compliance-packs/AC-81, and the behaviour * `retire-owner-quote-titles` and the review-gate work established. */ import type { Finding, FindingSeverity, FindingStatus } from '../core/types.js'; /** Parsed findings-file frontmatter. */ export interface FindingsFileMeta { artifact: string; reviewed_at: string; reviewer: string; } /** Extract a simple `key: value` field from a YAML block. */ export declare function extractField(block: string, key: string): string | undefined; /** Parse the frontmatter of a findings file. Missing fields read as empty. */ export declare function parseFrontmatter(content: string): FindingsFileMeta; /** The body of a findings file, with frontmatter removed. */ export declare function stripFrontmatter(content: string): string; /** * Extract a bullet field value: `- **FieldName:** value`. * * The single definition of the bullet grammar. `compliance/findings.ts` calls this * for its `Control` field rather than writing a second regex. */ export declare function extractBulletField(block: string, fieldName: string): string | undefined; /** * Normalize a `- **Status:**` value. * * An unrecognized leading token is a WARNING and the finding is treated as `open` — * the conservative direction. Skipping an unparseable status would silently remove a * finding that might be critical and open. */ export declare function normalizeStatus(raw: string): { status: FindingStatus; note?: string; warning?: string; }; /** * Normalize a `- **Severity:**` value. An unrecognized leading token defaults to the * MOST severe reading (`critical`), not the least — the same conservative direction. */ export declare function normalizeSeverity(raw: string): { severity: FindingSeverity; note?: string; warning?: string; }; /** * Sentinels from `generatePlaceholderFindings`. BOTH are matched so that a reword * of one does not silently defeat the guard — and the round-trip test asserts the * live scaffold still flags, so a reword fails the test rather than the gate. */ export declare const PLACEHOLDER_SECTION = "(pending review)"; export declare const PLACEHOLDER_ISSUE = "Review has not yet been performed"; /** Whether a parsed finding is the scaffold `aidlc review` writes, not a real finding. */ export declare function isPlaceholderFinding(f: { section?: string; issue?: string; }): boolean; /** * Split a findings-file body into `## `-headed blocks. * * Returns every block, including non-finding sections such as * `## Controls Checked` — a caller decides what each heading means. */ export declare function splitBlocks(body: string): string[]; /** * Parse a single finding block, or null when it is not a finding. * * A block with no severity — in a bullet or in the heading — is not a finding. * That is what lets a `## Controls Checked` section coexist with finding blocks in * one file without being miscounted as a finding. */ export declare function parseSingleFinding(block: string, index: number): Finding | null; /** Parse every finding block in a findings-file body. */ export declare function parseFindings(content: string): Finding[]; //# sourceMappingURL=findings-parser.d.ts.map