Documentation
¶
Overview ¶
Package schemas ports PR-AF's pydantic schema layer to Go: the input, pipeline, gate, and output structs plus the canonical severity vocabulary.
Parity rules (design §B.2 / §C.1):
- Every field Python's model_dump() always emits carries a snake_case json tag and NO omitempty (model_dump emits every field, no exclude_none).
- Pydantic `X | None` fields map to Go pointers so an unset value marshals to JSON null exactly as Python does.
- Structs with a non-zero pydantic default get an UnmarshalJSON that seeds the default before decoding (defaults.go), so an absent key keeps the default while a present key (even false/0/"") overrides it.
Index ¶
- Variables
- type AdversaryResult
- type AnatomyResult
- type BudgetAllocation
- type ChangeCluster
- type ChangedFile
- type CoverageGate
- type DiffStats
- type FileChange
- type GitHubComment
- type GitHubPRData
- type GitHubReview
- type Hunk
- type IntakeGate
- type IntakeResult
- type MetaDimensionResult
- type ReviewDimension
- type ReviewFinding
- type ReviewInput
- type ReviewMetadata
- type ReviewPlan
- type ReviewResult
- type ReviewSummary
- type ScoredFinding
- type Severity
- type SubReviewRequest
Constants ¶
This section is empty.
Variables ¶
var ValidSeverities = []Severity{"critical", "important", "suggestion", "nitpick"}
ValidSeverities is the four canonical severities, in decreasing urgency.
Functions ¶
This section is empty.
Types ¶
type AdversaryResult ¶
type AdversaryResult struct {
FindingTitle string `json:"finding_title"`
Verdict string `json:"verdict"` // confirmed | challenged | missed_trap
Reason string `json:"reason"`
SeverityAdjustment string `json:"severity_adjustment"` // boost | discount | none
HiddenTrap *string `json:"hidden_trap"` // set when verdict is missed_trap
}
AdversaryResult is the adversary reviewer's assessment of a finding. Seeded (defaults.go): severity_adjustment="none". HiddenTrap is Optional (nil -> null).
func (*AdversaryResult) UnmarshalJSON ¶
func (a *AdversaryResult) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds AdversaryResult.SeverityAdjustment="none".
type AnatomyResult ¶
type AnatomyResult struct {
// Structured — consumed by planner for routing.
Files []FileChange `json:"files"`
Clusters []ChangeCluster `json:"clusters"`
BlastRadius []string `json:"blast_radius"` // Files affected but not changed
DependencyGraph map[string][]string `json:"dependency_graph"` // file -> [files that import it]
Stats DiffStats `json:"stats"`
// String — consumed by planner LLM for reasoning.
PrNarrative string `json:"pr_narrative"`
RiskSurfaces []string `json:"risk_surfaces"`
IntentGaps []string `json:"intent_gaps"`
ContextNotes string `json:"context_notes"`
}
AnatomyResult is Phase 2 output: structured clusters for routing plus strings for LLM context.
type BudgetAllocation ¶
type BudgetAllocation struct {
MaxCostUSD float64 `json:"max_cost_usd"`
MaxDurationSeconds int `json:"max_duration_seconds"`
MaxReferenceFollows int `json:"max_reference_follows"`
MaxChildSpawns int `json:"max_child_spawns"`
}
BudgetAllocation is a budget cap for an agent or phase. Seeded (defaults.go): max_cost_usd=0.5, max_duration_seconds=60, max_reference_follows=3, max_child_spawns=2.
func (*BudgetAllocation) UnmarshalJSON ¶
func (a *BudgetAllocation) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds BudgetAllocation defaults (0.5 / 60 / 3 / 2).
type ChangeCluster ¶
type ChangeCluster struct {
ID string `json:"id"`
Name string `json:"name"` // Human-readable cluster name
Files []string `json:"files"` // File paths in this cluster
PrimaryLanguage string `json:"primary_language"`
Description string `json:"description"`
}
ChangeCluster is a group of related file changes (e.g. all auth-related files).
type ChangedFile ¶
type ChangedFile struct {
Path string `json:"path"`
Status string `json:"status"` // added | modified | removed | renamed
Additions int `json:"additions"`
Deletions int `json:"deletions"`
Patch string `json:"patch"` // Unified diff patch for this file
PreviousPath *string `json:"previous_path"` // For renames
}
ChangedFile is a single file changed in the PR.
type CoverageGate ¶
type CoverageGate struct {
FullyCovered bool `json:"fully_covered"`
GapDescriptions []string `json:"gap_descriptions"`
Confident bool `json:"confident"`
}
CoverageGate checks whether the review plan covered all change clusters. Seeded (defaults.go): confident=true, gap_descriptions=[].
func (*CoverageGate) UnmarshalJSON ¶
func (c *CoverageGate) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds CoverageGate.Confident=true.
type DiffStats ¶
type DiffStats struct {
TotalFiles int `json:"total_files"`
TotalAdditions int `json:"total_additions"`
TotalDeletions int `json:"total_deletions"`
FilesAdded int `json:"files_added"`
FilesModified int `json:"files_modified"`
FilesRemoved int `json:"files_removed"`
FilesRenamed int `json:"files_renamed"`
TestFilesChanged int `json:"test_files_changed"`
TestToCodeRatio float64 `json:"test_to_code_ratio"`
}
DiffStats holds aggregate statistics about the diff.
type FileChange ¶
type FileChange struct {
Path string `json:"path"`
Status string `json:"status"` // added | modified | removed | renamed
Language string `json:"language"`
LinesAdded int `json:"lines_added"`
LinesRemoved int `json:"lines_removed"`
Hunks []Hunk `json:"hunks"`
}
FileChange is a programmatic representation of a single file change.
type GitHubComment ¶
type GitHubComment struct {
Path string `json:"path"`
Line int `json:"line"`
Side string `json:"side"`
Body string `json:"body"`
}
GitHubComment is a single inline comment for the GitHub PR Review API. Seeded (defaults.go): side="RIGHT".
func (*GitHubComment) UnmarshalJSON ¶
func (c *GitHubComment) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds GitHubComment.Side="RIGHT".
type GitHubPRData ¶
type GitHubPRData struct {
Owner string `json:"owner"`
Repo string `json:"repo"`
Number int `json:"number"`
Title string `json:"title"`
Description string `json:"description"`
Labels []string `json:"labels"`
Author string `json:"author"`
BaseSHA string `json:"base_sha"`
HeadSHA string `json:"head_sha"`
CommitMessages []string `json:"commit_messages"`
Diff string `json:"diff"` // Unified diff text
ChangedFiles []ChangedFile `json:"changed_files"`
}
GitHubPRData is the data fetched from the GitHub API for a pull request.
type GitHubReview ¶
type GitHubReview struct {
Body string `json:"body"` // Executive summary
Event string `json:"event"` // APPROVE | COMMENT | REQUEST_CHANGES
Comments []GitHubComment `json:"comments"`
}
GitHubReview is the complete GitHub PR review payload. comments is a list default in Python — construct it non-nil upstream to marshal as [].
type Hunk ¶
type Hunk struct {
OldStart int `json:"old_start"`
OldCount int `json:"old_count"`
NewStart int `json:"new_start"`
NewCount int `json:"new_count"`
Header string `json:"header"` // @@ line
Content string `json:"content"` // The actual diff content
}
Hunk is a single diff hunk within a file.
type IntakeGate ¶
type IntakeGate struct {
PrType string `json:"pr_type"` // feature | bugfix | refactor | docs | infra | mixed
Complexity string `json:"complexity"` // trivial | standard | complex | massive
Confident bool `json:"confident"` // Whether classification is confident enough
}
IntakeGate is the fast PR classification. It escalates to .harness() when not confident. No non-zero defaults, so not seeded.
type IntakeResult ¶
type IntakeResult struct {
PrType string `json:"pr_type"` // feature | bugfix | refactor | docs | infra | mixed
Complexity string `json:"complexity"` // trivial | standard | complex | massive
Languages []string `json:"languages"`
AreasTouched []string `json:"areas_touched"` // auth, database, api, frontend, config...
RiskSignals []string `json:"risk_signals"` // "touches auth", "modifies schema", ...
AIGenerated float64 `json:"ai_generated"` // 0.0-1.0 confidence
ReviewDepth string `json:"review_depth"` // quick | standard | deep
PrSummary string `json:"pr_summary"` // Brief narrative (string for LLM context)
}
IntakeResult is Phase 1 output: structured fields for routing plus a pr_summary string for LLM context. All fields are required in Python (no defaults) so none are seeded.
type MetaDimensionResult ¶
type MetaDimensionResult struct {
Lens string `json:"lens"` // "semantic" | "mechanical" | "systemic"
Dimensions []ReviewDimension `json:"dimensions"`
Confidence float64 `json:"confidence"` // How complete this lens's coverage is (0-1)
Rationale string `json:"rationale"`
}
MetaDimensionResult is the output of a meta-dimension selector (Semantic, Mechanical, or Systemic). Seeded (defaults.go): confidence=0.7. Dimensions is a required field in Python (no default) so it is not seeded.
func (*MetaDimensionResult) UnmarshalJSON ¶
func (m *MetaDimensionResult) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds MetaDimensionResult.Confidence=0.7. Dimensions is a required field in Python (no default), so it is not seeded.
type ReviewDimension ¶
type ReviewDimension struct {
ID string `json:"id"`
Name string `json:"name"` // Human-readable (attributed in comments)
ReviewPrompt string `json:"review_prompt"` // Dynamically crafted (reviewer LLM prompt)
TargetFiles []string `json:"target_files"`
ContextFiles []string `json:"context_files"`
Priority int `json:"priority"` // Higher = more important = gets budget first
Budget BudgetAllocation `json:"budget"`
}
ReviewDimension is one parallel reviewer instance. Seeded (defaults.go): priority=1, budget=default BudgetAllocation, context_files=[].
func (*ReviewDimension) UnmarshalJSON ¶
func (d *ReviewDimension) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds ReviewDimension.Priority=1 and a default Budget. When a "budget" key is present, BudgetAllocation's own UnmarshalJSON re-seeds it before applying the overrides.
type ReviewFinding ¶
type ReviewFinding struct {
DimensionID string `json:"dimension_id"`
DimensionName string `json:"dimension_name"`
FilePath string `json:"file_path"`
LineStart int `json:"line_start"`
LineEnd int `json:"line_end"`
HunkContext string `json:"hunk_context"` // Code context around the finding
Severity Severity `json:"severity"`
Title string `json:"title"`
Body string `json:"body"` // Detailed explanation (GitHub comment)
Suggestion *string `json:"suggestion"` // Concrete fix (code block)
Evidence string `json:"evidence"` // Code references supporting this finding
Confidence float64 `json:"confidence"`
Tags []string `json:"tags"` // security, correctness, ...
}
ReviewFinding is emitted to the findings queue as reviewers work. Seeded (defaults.go): confidence=0.5, severity="suggestion", tags=[]. Suggestion is Optional (nil -> null).
func (*ReviewFinding) UnmarshalJSON ¶
func (f *ReviewFinding) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds ReviewFinding.Confidence=0.5, Severity="suggestion".
func (ReviewFinding) ValidateConsistency ¶
func (f ReviewFinding) ValidateConsistency() error
type ReviewInput ¶
type ReviewInput struct {
// Mode 1: GitHub PR URL.
PrURL *string `json:"pr_url"`
// Mode 2: Raw diff.
DiffText *string `json:"diff_text"`
// Mode 3: Local repo.
RepoPath *string `json:"repo_path"`
BaseRef *string `json:"base_ref"`
HeadRef *string `json:"head_ref"`
// Configuration overrides.
Depth string `json:"depth"` // auto | quick | standard | deep
MaxCostUSD *float64 `json:"max_cost_usd"`
MaxDurationSeconds *int `json:"max_duration_seconds"`
Focus string `json:"focus"` // auto | security | correctness | performance | tests
IgnorePaths []string `json:"ignore_paths"`
Hints []string `json:"hints"` // Project-specific review hints
// Model overrides (per-call). Keys match ModelConfig field names.
Models map[string]string `json:"models"`
// Budget overrides.
MaxConcurrentReviewers *int `json:"max_concurrent_reviewers"`
MaxCoverageIterations *int `json:"max_coverage_iterations"`
MaxReviewDepth int `json:"max_review_depth"` // 1=flat, 2=one sub-level, 3=max
// Output.
OutputFormat string `json:"output_format"` // github | json | sarif | markdown
DryRun bool `json:"dry_run"` // Don't post to GitHub, just return findings
PostPRNumber *int `json:"post_pr_number"`
// Comment formatting.
SuggestionMode string `json:"suggestion_mode"` // comment | code
}
ReviewInput is the top-level input to the PR-AF pipeline.
Divergence from schemas/input.py, deliberate (design §C.1): the pydantic ReviewInput types max_cost_usd / max_duration_seconds as non-nullable float / int with concrete defaults (2.0 / 3600). The Go struct instead mirrors the actual node entry point — app.py review()'s signature, where both are `... | None = None` — so they are *float64 / *int and stay nil until config.ResolveBudgetCaps / config.ReviewConfig.FromInput resolve the explicit-arg > env > default (2.0 / 3600) cascade. This keeps the "was a cap explicitly supplied?" signal that Python recovers from the review() defaults.
func (*ReviewInput) UnmarshalJSON ¶
func (r *ReviewInput) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds ReviewInput's non-zero pydantic defaults. The budget-cap pointers (MaxCostUSD / MaxDurationSeconds) stay nil — they are resolved later by config.ResolveBudgetCaps / ReviewConfig.FromInput.
type ReviewMetadata ¶
type ReviewMetadata struct {
Intake map[string]any `json:"intake"`
Anatomy map[string]any `json:"anatomy"`
Plan map[string]any `json:"plan"`
Budget map[string]any `json:"budget"`
AgentInvocations int `json:"agent_invocations"`
PhasesCompleted []string `json:"phases_completed"`
DegradedDimensions int `json:"degraded_dimensions"`
}
ReviewMetadata holds pipeline metadata for debugging and observability. The intake/anatomy/plan/budget dicts and phases_completed list are collection defaults in Python — construct them non-nil upstream to marshal as {} / [].
type ReviewPlan ¶
type ReviewPlan struct {
Dimensions []ReviewDimension `json:"dimensions"`
CrossRefHints []string `json:"cross_ref_hints"` // Suspected interactions (string for LLM)
AIAdjusted bool `json:"ai_adjusted"` // Whether plan was adjusted for AI-generated code
TotalBudget BudgetAllocation `json:"total_budget"`
}
ReviewPlan is Phase 3 output: the planner's complete review strategy.
type ReviewResult ¶
type ReviewResult struct {
ReviewID string `json:"review_id"`
PrURL string `json:"pr_url"`
Review GitHubReview `json:"review"` // The GitHub review payload
Findings []ScoredFinding `json:"findings"` // All scored findings
Summary ReviewSummary `json:"summary"`
Metadata ReviewMetadata `json:"metadata"`
}
ReviewResult is the complete output of the PR-AF pipeline.
type ReviewSummary ¶
type ReviewSummary struct {
TotalFindings int `json:"total_findings"`
BySeverity map[string]int `json:"by_severity"`
BlockingCount int `json:"blocking_count"`
AdvisoryCount int `json:"advisory_count"`
DimensionsRun int `json:"dimensions_run"`
// Backward-compatible field name; value now represents synthesized compound
// findings.
CrossRefInteractions int `json:"cross_ref_interactions"`
AdversaryChallenged int `json:"adversary_challenged"`
AdversaryConfirmed int `json:"adversary_confirmed"`
CoverageIterations int `json:"coverage_iterations"`
AIGeneratedConfidence float64 `json:"ai_generated_confidence"`
CostUSD float64 `json:"cost_usd"`
DurationSeconds float64 `json:"duration_seconds"`
BudgetExhausted bool `json:"budget_exhausted"`
}
ReviewSummary holds aggregate statistics about the review. by_severity is a dict default in Python — construct it non-nil upstream to marshal as {}.
type ScoredFinding ¶
type ScoredFinding struct {
ID string `json:"id"`
DimensionID string `json:"dimension_id"`
DimensionName string `json:"dimension_name"`
FilePath string `json:"file_path"`
LineStart int `json:"line_start"`
LineEnd int `json:"line_end"`
DiffLine *int `json:"diff_line"` // Line number in the diff (GitHub API)
DiffSide string `json:"diff_side"` // LEFT (deletion) | RIGHT (addition)
Severity Severity `json:"severity"`
Title string `json:"title"`
Body string `json:"body"`
Suggestion *string `json:"suggestion"`
Evidence string `json:"evidence"`
Confidence float64 `json:"confidence"`
Tags []string `json:"tags"`
Score float64 `json:"score"`
ActiveMultipliers []string `json:"active_multipliers"`
// Orthogonal release-blocker axis. Severity = "how bad", blocking = "must
// fix before merge". Default false so unreviewed findings never falsely
// block merge.
Blocking bool `json:"blocking"`
BlockingReason string `json:"blocking_reason"`
}
ScoredFinding is a finding after scoring, dedup, and line mapping. Seeded (defaults.go): diff_side="RIGHT", confidence=0.5, severity="suggestion", tags=[], active_multipliers=[]. DiffLine and Suggestion are Optional (nil -> null).
func (*ScoredFinding) UnmarshalJSON ¶
func (s *ScoredFinding) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds ScoredFinding.DiffSide="RIGHT", Confidence=0.5, Severity="suggestion".
func (ScoredFinding) ValidateConsistency ¶
func (f ScoredFinding) ValidateConsistency() error
type Severity ¶
type Severity string
Severity is the canonical finding-severity vocabulary — always one of critical | important | suggestion | nitpick. It ports schemas/severity.py's Annotated Literal + BeforeValidator: the type advertises the enum, and its UnmarshalJSON coerces stray labels (e.g. "high" -> "important") through NormalizeSeverity instead of failing, so a model-emitted synonym can never break decoding (the incident that silently swallowed a real review).
const DefaultSeverity Severity = "suggestion"
DefaultSeverity is where unknown / empty / non-string labels land. It is the mid-low rung: keeps a finding visible without inflating it to a blocker.
func NormalizeSeverity ¶
NormalizeSeverity coerces an arbitrary severity label to the canonical vocabulary (schemas/severity.py normalize_severity). It is case-insensitive and whitespace-tolerant; empty, non-string, or unrecognized input falls back to def. Accepts a plain string or a Severity (mirroring Python's isinstance(value, str) which also accepts str subclasses).
func (*Severity) UnmarshalJSON ¶
UnmarshalJSON coerces any JSON scalar (string synonym, null, number, …) to the canonical vocabulary via NormalizeSeverity — the Go equivalent of the pydantic BeforeValidator. A null or non-string value yields DefaultSeverity.
type SubReviewRequest ¶
type SubReviewRequest struct {
Reason string `json:"reason"`
ReviewPrompt string `json:"review_prompt"`
TargetFiles []string `json:"target_files"`
ContextFiles []string `json:"context_files"`
Priority int `json:"priority"`
}
SubReviewRequest is a reviewer's request to spawn a deeper sub-review. Seeded (defaults.go): priority=1, context_files=[].
func (*SubReviewRequest) UnmarshalJSON ¶
func (s *SubReviewRequest) UnmarshalJSON(b []byte) error
UnmarshalJSON seeds SubReviewRequest.Priority=1.