/**
 * Normalize the review's free-form / emoji severity into a stable tier.
 * The real review schema defaults severity to '🟡'; reviews also emit 🔴/🟢 and
 * words. Anything unrecognized falls back to 'should-fix' (never throws).
 */
export function normalizeSeverity(raw: any): "should-fix" | "blocker" | "nit";
/**
 * Build a fresh review record from the review node's (post-verification)
 * findings. `findings` is the REAL review shape:
 *   { file, line?, severity, category, claim, evidence, suggestion?, confidence? }
 * Assigns stable ids (f1..fN), normalizes severity, caps long text, status:'open'.
 * `nowIso` is injected (callers pass new Date().toISOString()) so this stays pure.
 */
export function buildReviewRecord({ headSha, verdict, objectivesChecked, findings, nowIso, }?: {
    headSha?: any;
    verdict?: string;
    objectivesChecked?: boolean;
    findings?: any[];
    nowIso?: any;
}): {
    schemaVersion: number;
    kind: string;
    headSha: any;
    verdict: string;
    objectivesChecked: boolean;
    reviewedAt: any;
    findings: {
        id: string;
        file: string;
        line: any;
        severity: string;
        category: string;
        claim: string;
        evidence: string;
        suggestion: string;
        confidence: any;
        status: string;
    }[];
};
/**
 * Record the OUTCOME of a comment_reply against a finding. IDEMPOTENT: it SETS
 * findings[id].status (and an optional one-line note) — running the same reply
 * twice (webhook redelivery) yields the identical record, no double-append.
 * Returns a NEW record (does not mutate the input). If findingId is unknown, the
 * record is returned unchanged (best-effort, never throws).
 */
export function upsertReplyOutcome(record: any, { findingId, status, note }?: {}): any;
/**
 * Serialize a record to a string that FITS CONTENT_MAX_BYTES. Deterministic:
 * findings are stably sorted by (severityRank, file, line, id); if still over
 * budget, the LOWEST-priority findings are dropped until it fits and
 * `truncated:true` is set. Text fields are already capped by buildReviewRecord.
 */
export function serializeReviewRecord(record: any): string;
/**
 * Tolerant reader — NEVER throws. Accepts whatever kv_recall returns for the
 * value (a JSON string, an already-parsed metadata object, a legacy prose
 * string, an {error} envelope, null/'').
 * Returns one of:
 *   { kind:'empty' }                         — nothing usable
 *   { kind:'record',  record, future?:bool } — a structured record (future=newer schemaVersion)
 *   { kind:'legacy',  legacyNote:string }    — an old freeform note; advisory only
 */
export function parseReviewMemory(raw: any): {
    kind: string;
    record?: undefined;
    future?: undefined;
    legacyNote?: undefined;
} | {
    kind: string;
    record: any;
    future: boolean;
    legacyNote?: undefined;
} | {
    kind: string;
    legacyNote: string;
    record?: undefined;
    future?: undefined;
};
/**
 * Render a parsed memory into prompt text for the review/reply LLM. Compact,
 * human-readable, and it NEVER assumes a shape it didn't verify (a future
 * schemaVersion is surfaced as advisory). Empty → '' (caller omits the block).
 */
export function summarizeForPrompt(parsed: any): string;
/**
 * reviewRecord — a GENERIC, provider-agnostic structured record for the
 * code-review → comment_reply memory (shared by gitlab-code-review and
 * github-code-review). Replaces the freeform prose kv note with a versioned,
 * queryable record.
 *
 * DELIBERATELY TRANSPORT-AGNOSTIC. This module does NO I/O: it only builds,
 * serializes, parses and renders the record. WHO stores/recalls it (the JS node
 * vs the LLM via kv_store/kv_recall) is a separate wiring decision — these pure
 * functions are correct either way. The per-PR/MR KEY stays provider-specific
 * (reviewMemoryScopeFor in each review-node.js); the record BODY here carries
 * zero provider fields (identity lives in the key, not the body).
 *
 * Contract facts this module mirrors (source of truth = backend
 * src/handlers/review-memory.js + packages/skills/src/kvMemory.js):
 *   - kv `content` is a STRING, hard-capped at 200KB (CONTENT_MAX). We serialize
 *     to a string and truncate deterministically to fit — an over-cap store is
 *     rejected (HTTP 400) and SILENTLY lost, so truncation must happen here,
 *     before the write.
 *   - kv also has an optional `metadata` OBJECT channel; parseReviewMemory
 *     therefore accepts an already-parsed object too, so the record can ride in
 *     either channel without changing this code.
 *
 * Reviewed by two adversarial design agents (2026-07-04): schema aligned to the
 * REAL finding shape ({file,line,severity,category,claim,evidence,suggestion,
 * confidence}); replies modeled as an IDEMPOTENT findingId→status set (NOT an
 * append log, which double-appends on webhook redelivery); headSha carried but
 * treated as advisory (its plumbing is deferred — today it is undefined).
 */
export const REVIEW_RECORD_SCHEMA_VERSION: 1;
export const REVIEW_RECORD_KIND: "review-record";
export const CONTENT_MAX_BYTES: number;
export const FIELD_MAX_CHARS: 2000;
export const SEVERITY_TIERS: string[];
export const FINDING_STATUSES: string[];
