Skip to content

Review Schema

schema/review.cue is the single source of truth for what a review looks like. The binary embeds it, make vet-cue checks it, and every model answer is unified with it before any caller sees data.

package review
#Severity: "Critical" | "Major" | "Minor" | "Trivial"
#Category: "Security" | "Performance" | "Logic" | "Maintainability" | "Architecture"
#Finding: {
file: string & !=""
start_line: int & >=1
end_line: int & >=start_line
severity: #Severity
category: #Category
title: string & !=""
body: string & !=""
suggestion?: string
citations?: [...string & !=""]
if category == "Architecture" {
citations: [_, ...]
}
}
#ReviewOutput: {
summary: string
risk_score: int & >=0 & <=100
findings: [...#Finding]
}
Field Meaning
file Path exactly as shown in the diff’s ### header
start_line, end_line New-file line numbers. end_line may not precede start_line
severity Critical: exploitable or loses data. Major: wrong behavior users will hit. Minor: an edge-case bug or meaningful debt. Trivial: a small cleanup
category Security, Performance, Logic, Maintainability, or Architecture (a violated design document, which must be cited)
citations IDs of knowledge-base documents the finding relies on. Required for Architecture, and each must be a document provided to that chunk
title A short imperative headline
body What is wrong, why it matters, how it fails
suggestion Optional replacement code or a concrete fix
risk_score The model’s 0–100 estimate. Vizzini reports max(this, its own deterministic score); see Risk & Auto-Approve
  • Definitions are closed. An extra field anywhere, such as confidence or verdict, is rejected rather than ignored.
  • Exact spellings. "High" or "major" is not a severity. The answer goes back to the model for repair.
  • Integers are integers. 5.5 or "40" fails int.
  • An omitted findings field means no findings. CUE treats the open list [...#Finding] as concrete with default [].

The same package defines the describe and improve outputs (#PRDescription, #CodeSuggestion) and the policy gate:

#PolicyGate: {
fail_on: [...#Severity] | *["Critical", "Major"]
}

#RiskPolicy holds the path weights, the auto-approve rules and the high_threshold that bounds the bands (#RiskBand: low, medium, high); see Risk & Auto-Approve. #RiskAssessmentReport is the closed report pr-review --mode risk prints. Implementation plans will be added here as their milestones land. See the roadmap.

#Suppressions validates a repository’s suppression rules (see Unattended PR Review):

#Suppression: {
id: string & =~"^[A-Za-z0-9][A-Za-z0-9._-]*$"
reason: string & !=""
fingerprint?: string & =~"^v1:[0-9a-f]{16}$"
paths?: [string & !="", ...string & !=""]
categories?: [#Category, ...#Category]
title?: string & !=""
expires?: string & =~"^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
}

Every rule must name at least one of fingerprint, paths or title, so no rule silences everything. Findings a rule matched appear in the review report’s suppressed list (#SuppressedFinding: rule, reason, finding). That list is part of the closed #ReviewReport, never of the model’s #ReviewOutput, so a model cannot put anything there.