/** * 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 declare const REVIEW_RECORD_SCHEMA_VERSION = 1; export declare const REVIEW_RECORD_KIND = "review-record"; export declare const CONTENT_MAX_BYTES: number; export declare const FIELD_MAX_CHARS = 2000; export declare const SEVERITY_TIERS: string[]; export declare const FINDING_STATUSES: string[]; /** * 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 declare function normalizeSeverity(raw: any): "blocker" | "should-fix" | "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 declare function buildReviewRecord({ headSha, verdict, objectivesChecked, findings, 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 declare function upsertReplyOutcome(record: any, { findingId, status, note }?: any): 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 declare 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 declare 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 declare function summarizeForPrompt(parsed: any): string;