schemas

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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"`
	UnrelatedChanges []string `json:"unrelated_changes"`
	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

func NormalizeSeverity(v any, def Severity) Severity

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

func (s *Severity) UnmarshalJSON(b []byte) error

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL