Documentation
¶
Overview ¶
Package reasoners ports the 16 router reasoners in src/pr_af/reasoners/harnesses.py (intake_phase … coverage_gate) to Go.
Each reasoner is a plain function
func XxxPhase(ctx context.Context, deps Deps, in XxxInput) (map[string]any, error)
that builds its prompt with the byte-verbatim builders in internal/prompts, invokes the harness through the harnessx.Run choke point (or the AI seam for the two .ai() gates: IntakePhase and CoverageGate), and returns the exact snake_case key set Python's model_dump() emits (design §B.2). The orchestrator (T4.1) calls these in-process; node/register.go (T4.2) wraps them in afx.Bind adapters for control-plane registration.
Parse-failure behavior mirrors Python per reasoner: when the harness could not produce a schema-valid result (Result.Parsed == nil), each reasoner applies the same deterministic fallback its Python counterpart does — a seeded default struct, an empty key set, or a keep-everything index list — never an error (design §C.3 step 4). Harness transport errors and fatal (non-retryable) API errors propagate as Go errors, exactly as Python lets the exception escape the reasoner.
Index ¶
- Constants
- Variables
- func AdversaryPhase(ctx context.Context, deps Deps, in AdversaryInput) (map[string]any, error)
- func AnatomyPhase(ctx context.Context, deps Deps, in AnatomyInput) (map[string]any, error)
- func CompoundDedupPhase(ctx context.Context, deps Deps, in CompoundDedupInput) (map[string]any, error)
- func CompoundFinderPhase(ctx context.Context, deps Deps, in CompoundFinderInput) (map[string]any, error)
- func CoverageGate(ctx context.Context, deps Deps, in CoverageGateInput) (map[string]any, error)
- func DeepenFindings(ctx context.Context, deps Deps, in DeepenInput) (map[string]any, error)
- func EvidenceVerifier(ctx context.Context, deps Deps, in EvidenceVerifierInput) (map[string]any, error)
- func ExtractObligations(ctx context.Context, deps Deps, in ExtractObligationsInput) (map[string]any, error)
- func IntakePhase(ctx context.Context, deps Deps, in IntakeInput) (map[string]any, error)
- func MetaMechanical(ctx context.Context, deps Deps, in MetaInput) (map[string]any, error)
- func MetaSemantic(ctx context.Context, deps Deps, in MetaInput) (map[string]any, error)
- func MetaSystemic(ctx context.Context, deps Deps, in MetaInput) (map[string]any, error)
- func PlanningPhase(ctx context.Context, deps Deps, in PlanningInput) (map[string]any, error)
- func PostWorthinessGate(ctx context.Context, deps Deps, in PostWorthinessInput) (map[string]any, error)
- func ReviewDimension(ctx context.Context, deps Deps, in ReviewDimensionInput) (map[string]any, error)
- func VerifyObligation(ctx context.Context, deps Deps, in VerifyObligationInput) (map[string]any, error)
- type AICaller
- type AdversaryInput
- type AnatomyInput
- type CompoundDedupInput
- type CompoundFinderInput
- type CoverageGateInput
- type DeepenInput
- type Deps
- type EvidenceVerifierInput
- type ExtractObligationsInput
- type IntakeInput
- type MetaInput
- type OrderedPatches
- type PlanningInput
- type PostWorthinessInput
- type ReviewDimensionInput
- type VerifyObligationInput
Constants ¶
const ( LabelAnatomy = "anatomy" LabelChallenge = "challenge" LabelCoverage = "coverage" LabelCrossRef = "cross-ref" LabelDeepen = "deepen" LabelEvidence = "evidence" LabelIntake = "intake" LabelLens = "lens" LabelObligations = "obligations" LabelPlan = "plan" LabelPostWorthiness = "post worthiness" LabelReviewer = "reviewer" )
The labels a reasoner's agent session carries (appx.HarnessOptions.Label): what the session is for, in a word. codeaf names the session's thread by it and keys each agent's turn and time limits on it (internal/praf's limits.go), so each is a constant here and written nowhere else.
const ( NameIntakePhase = "intake_phase" NameAnatomyPhase = "anatomy_phase" NamePlanningPhase = "planning_phase" NameMetaSemantic = "meta_semantic" NameMetaMechanical = "meta_mechanical" NameMetaSystemic = "meta_systemic" NameReviewDimension = "review_dimension" NameCompoundFinderPhase = "compound_finder_phase" NamePostWorthinessGate = "post_worthiness_gate" NameCompoundDedupPhase = "compound_dedup_phase" NameEvidenceVerifier = "evidence_verifier" NameAdversaryPhase = "adversary_phase" NameDeepenFindings = "deepen_findings" NameExtractObligations = "extract_obligations" NameVerifyObligation = "verify_obligation" NameCoverageGate = "coverage_gate" )
Control-plane registration names of the 16 router reasoners (design §B.1). node/register.go registers each handler under these names, and the orchestrator's CallLocal-routed seams (orch.callLocalSeams) invoke them by the same constants — a single source of truth so the DAG's phase names can never drift from the registered surface.
Variables ¶
var Labels = []string{ LabelAnatomy, LabelChallenge, LabelCoverage, LabelCrossRef, LabelDeepen, LabelEvidence, LabelIntake, LabelLens, LabelObligations, LabelPlan, LabelPostWorthiness, LabelReviewer, }
Labels is every label a reasoner's session carries.
Functions ¶
func AdversaryPhase ¶
AdversaryPhase ports adversary_phase: the skeptical challenger that confirms, challenges, or escalates each finding against ground-truth evidence. Skepticism escalates to "high" when the AI-generated confidence exceeds 0.5 (handled inside the prompt builder).
Output keys (§B.2): results. Parse failure degrades to an empty list.
func AnatomyPhase ¶
AnatomyPhase ports anatomy_phase: deterministic diff decomposition (parse, stats, clusters, blast radius) plus one .harness() call for the semantic narrative fields, merged into an AnatomyResult.
Output keys (§B.2): files, clusters, blast_radius, dependency_graph, stats, pr_narrative, risk_surfaces, unrelated_changes, intent_gaps, context_notes. A harness parse failure degrades to empty semantic fields (Python falls back to a default _AnatomySemanticResult), never an error.
func CompoundDedupPhase ¶
func CompoundDedupPhase(ctx context.Context, deps Deps, in CompoundDedupInput) (map[string]any, error)
CompoundDedupPhase ports compound_dedup_phase: one harness call that decides which compound findings are genuinely distinct insights.
Output keys (§B.2): keep_indices, reasoning. One-or-fewer findings short-circuits to keep-everything; an empty/invalid index list (including the parse-failure fallback) also degrades to keep-everything.
func CompoundFinderPhase ¶
func CompoundFinderPhase(ctx context.Context, deps Deps, in CompoundFinderInput) (map[string]any, error)
CompoundFinderPhase ports compound_finder_phase: given a small cluster of findings that might interact, synthesize NEW compound findings when the combined risk is real.
Output keys (§B.2): findings. Fewer than two findings short-circuits to an empty list without a harness call; parse failure degrades to an empty list.
func CoverageGate ¶
CoverageGate ports coverage_gate: one .ai() call that decides whether the review dimensions covered every change cluster, with a .harness() retry of the same prompt when the AI seam is unavailable or refuses the structured request (harnesses.py coverage_gate wraps its .ai() call the same way).
Output keys (§B.2): fully_covered, gap_descriptions, confident. Absent response keys land on the pydantic defaults through CoverageGate's seeded UnmarshalJSON (confident=true, gap_descriptions=[]); a harness fallback that fails to parse returns {} (Python returns a literal empty dict).
func DeepenFindings ¶
DeepenFindings ports deepen_findings (registered but DEAD on the live path): the literal ground-truth verification pass over the changed code.
Output keys (§B.2): findings. No non-empty patches short-circuits to an empty list without a harness call; parse failure degrades to an empty list.
func EvidenceVerifier ¶
func EvidenceVerifier(ctx context.Context, deps Deps, in EvidenceVerifierInput) (map[string]any, error)
EvidenceVerifier ports evidence_verifier: independent verification of critical/important findings against programmatically extracted ground-truth code, before the adversarial phase.
Output keys (§B.2): verified_findings. Parse failure degrades to an empty list.
func ExtractObligations ¶
func ExtractObligations(ctx context.Context, deps Deps, in ExtractObligationsInput) (map[string]any, error)
ExtractObligations ports extract_obligations: enumerate the cross-location consistency obligations the changed code creates (breadth pass; judged one at a time by VerifyObligation).
Output keys (§B.2): obligations (each: id, where, relies_on, property). No non-empty patches short-circuits to an empty list without a harness call; parse failure degrades to an empty list.
func IntakePhase ¶
IntakePhase ports intake_phase: a fast .ai() metadata classification gate that, when confident, combines with the deterministic extractors into an IntakeResult; otherwise it escalates to a full .harness() classification.
Output keys (§B.2): pr_type, complexity, languages, areas_touched, risk_signals, ai_generated, review_depth, pr_summary — or {} when the harness fallback fails to parse (Python returns a literal empty dict).
func MetaMechanical ¶
MetaMechanical ports meta_mechanical.
func MetaSemantic ¶
MetaSemantic ports meta_semantic.
func MetaSystemic ¶
MetaSystemic ports meta_systemic.
func PlanningPhase ¶
PlanningPhase ports planning_phase (registered but DEAD on the live path — the meta-selectors replaced it; kept for surface parity).
Output keys (§B.2): dimensions, cross_ref_hints, ai_adjusted, total_budget — or the literal {"dimensions": [], "cross_ref_hints": []} on parse failure.
func PostWorthinessGate ¶
func PostWorthinessGate(ctx context.Context, deps Deps, in PostWorthinessInput) (map[string]any, error)
PostWorthinessGate ports post_worthiness_gate: an experienced-reviewer judgment over which findings are genuinely worth posting (recall-preserving: unsure -> keep).
Output keys (§B.2): keep_indices, reasoning — EXCEPT the <=1-finding short-circuit, which Python returns as {"keep_indices": [...]} with no reasoning key. Empty/invalid harness indices (including parse failure) degrade to keep-everything, never silencing all findings.
func ReviewDimension ¶
func ReviewDimension(ctx context.Context, deps Deps, in ReviewDimensionInput) (map[string]any, error)
ReviewDimension ports review_dimension: one focused reviewer over an assigned dimension, with optional sub-review spawning below max depth.
Output keys (§B.2): findings, sub_reviews, current_depth. A schema parse failure logs loudly (indistinguishable from a clean review otherwise) and reports zero findings — Python prints and substitutes an empty _ReviewFindingsResult.
func VerifyObligation ¶
func VerifyObligation(ctx context.Context, deps Deps, in VerifyObligationInput) (map[string]any, error)
VerifyObligation ports verify_obligation: read BOTH ends of one consistency obligation and decide whether the property holds.
Output keys (§B.2): holds, title, severity, file_path, line_start, line_end, body, evidence, suggestion, confidence. Parse failure degrades to the seeded verdict (holds=true, severity="important", confidence=0.7) — Python's `_ObligationVerdict(holds=True)`.
Types ¶
type AICaller ¶
type AICaller interface {
AI(ctx context.Context, prompt string, opts ...ai.Option) (*ai.Response, error)
}
AICaller is the seam for the SDK's LLM chat entry point (Agent.AI), used by the two .ai() reasoners (intake_phase's gate and coverage_gate). Declaring the one-method interface here lets tests script structured responses without a live model; the review's appx.App satisfies it.
type AdversaryInput ¶
type AdversaryInput struct {
Findings []schemas.ReviewFinding `json:"findings"`
AIGeneratedConfidence float64 `json:"ai_generated_confidence"`
PrContext string `json:"pr_context"`
RepoPath string `json:"repo_path"`
EvidencePackages map[string]map[string]any `json:"evidence_packages"`
}
AdversaryInput mirrors adversary_phase(findings, ai_generated_confidence=0.0, pr_context="", repo_path="", evidence_packages=None).
type AnatomyInput ¶
type AnatomyInput struct {
PRData schemas.GitHubPRData `json:"pr_data"`
Intake schemas.IntakeResult `json:"intake"`
RepoPath string `json:"repo_path"`
}
AnatomyInput mirrors anatomy_phase(pr_data, intake, repo_path="").
type CompoundDedupInput ¶
type CompoundDedupInput struct {
CompoundFindings []schemas.ReviewFinding `json:"compound_findings"`
IndividualFindingsSummary string `json:"individual_findings_summary"`
}
CompoundDedupInput mirrors compound_dedup_phase(compound_findings, individual_findings_summary="").
type CompoundFinderInput ¶
type CompoundFinderInput struct {
ClusterFindings []schemas.ReviewFinding `json:"cluster_findings"`
RepoPath string `json:"repo_path"`
EvidenceMap map[string]map[string]any `json:"evidence_map"`
}
CompoundFinderInput mirrors compound_finder_phase(cluster_findings, repo_path="", evidence_map=None). EvidenceMap values are EvidencePackage.model_dump()-shaped dicts keyed by finding title.
type CoverageGateInput ¶
type CoverageGateInput struct {
Anatomy schemas.AnatomyResult `json:"anatomy"`
ReviewedClusters []string `json:"reviewed_clusters"`
DimensionNamesReviewed []string `json:"dimension_names_reviewed"`
}
CoverageGateInput mirrors coverage_gate(anatomy, reviewed_clusters, dimension_names_reviewed=None).
type DeepenInput ¶
type DeepenInput struct {
DiffPatches OrderedPatches `json:"diff_patches"`
ExistingTitles []string `json:"existing_titles"`
RepoPath string `json:"repo_path"`
PrContext string `json:"pr_context"`
}
DeepenInput mirrors deepen_findings(diff_patches=None, existing_titles=None, repo_path="", pr_context="").
type Deps ¶
type Deps struct {
Harness harnessx.HarnessCaller
AI AICaller
}
Deps carries the two injectable capabilities a reasoner may use. Harness is required by every reasoner except CoverageGate; AI is required only by IntakePhase and CoverageGate (Python's router.app.ai calls).
type EvidenceVerifierInput ¶
type EvidenceVerifierInput struct {
Findings []schemas.ReviewFinding `json:"findings"`
EvidencePackages map[string]map[string]any `json:"evidence_packages"`
PrContext string `json:"pr_context"`
RepoPath string `json:"repo_path"`
}
EvidenceVerifierInput mirrors evidence_verifier(findings, evidence_packages=None, pr_context="", repo_path="").
type ExtractObligationsInput ¶
type ExtractObligationsInput struct {
DiffPatches OrderedPatches `json:"diff_patches"`
RepoPath string `json:"repo_path"`
PrContext string `json:"pr_context"`
}
ExtractObligationsInput mirrors extract_obligations(diff_patches=None, repo_path="", pr_context="").
type IntakeInput ¶
type IntakeInput struct {
PRData schemas.GitHubPRData `json:"pr_data"`
Depth string `json:"depth"`
}
IntakeInput mirrors intake_phase(pr_data, depth="standard").
func (*IntakeInput) UnmarshalJSON ¶
func (i *IntakeInput) UnmarshalJSON(b []byte) error
type MetaInput ¶
type MetaInput struct {
Intake schemas.IntakeResult `json:"intake"`
Anatomy schemas.AnatomyResult `json:"anatomy"`
Depth string `json:"depth"`
RepoPath string `json:"repo_path"`
DiffPatches OrderedPatches `json:"diff_patches"`
ReviewerFeedback string `json:"reviewer_feedback"`
}
MetaInput mirrors the shared signature of meta_semantic / meta_mechanical / meta_systemic(intake, anatomy, depth="standard", repo_path="", diff_patches=None, reviewer_feedback="").
func (*MetaInput) UnmarshalJSON ¶
type OrderedPatches ¶
OrderedPatches is a diff_patches dict with preserved insertion order — Python's dict[str, str] whose ordering the meta/deepen/obligation prompts render. It JSON-round-trips as an object, decoding in document order.
func (OrderedPatches) MarshalJSON ¶
func (p OrderedPatches) MarshalJSON() ([]byte, error)
MarshalJSON renders the pairs as a JSON object in slice order.
func (*OrderedPatches) UnmarshalJSON ¶
func (p *OrderedPatches) UnmarshalJSON(b []byte) error
UnmarshalJSON decodes a JSON object into ordered pairs, preserving the document's key order (duplicate keys: last value wins, first position kept — matching Python's dict literal semantics). null decodes to nil.
type PlanningInput ¶
type PlanningInput struct {
Intake schemas.IntakeResult `json:"intake"`
Anatomy schemas.AnatomyResult `json:"anatomy"`
Depth string `json:"depth"`
Hints []string `json:"hints"`
}
PlanningInput mirrors planning_phase(intake, anatomy, depth="standard", hints=None).
func (*PlanningInput) UnmarshalJSON ¶
func (p *PlanningInput) UnmarshalJSON(b []byte) error
type PostWorthinessInput ¶
type PostWorthinessInput struct {
Findings []schemas.ReviewFinding `json:"findings"`
}
PostWorthinessInput mirrors post_worthiness_gate(findings). The live path passes ReviewFinding dumps.
type ReviewDimensionInput ¶
type ReviewDimensionInput struct {
ReviewPrompt string `json:"review_prompt"`
TargetFiles []string `json:"target_files"`
ContextFiles []string `json:"context_files"`
RepoPath string `json:"repo_path"`
CurrentDepth int `json:"current_depth"`
MaxDepth int `json:"max_depth"`
PrNarrative string `json:"pr_narrative"`
RiskSurfaces []string `json:"risk_surfaces"`
IntakeSummary string `json:"intake_summary"`
PrDescription string `json:"pr_description"`
DiffPatches map[string]string `json:"diff_patches"`
AllDimensionNames []string `json:"all_dimension_names"`
ReviewerFeedback string `json:"reviewer_feedback"`
PrimedCode string `json:"primed_code"`
}
ReviewDimensionInput mirrors review_dimension's long keyword signature. DiffPatches is a plain map — the prompt renders patches in TargetFiles order, so dict ordering is immaterial here.
func (*ReviewDimensionInput) UnmarshalJSON ¶
func (r *ReviewDimensionInput) UnmarshalJSON(b []byte) error
type VerifyObligationInput ¶
type VerifyObligationInput struct {
Obligation map[string]any `json:"obligation"`
RepoPath string `json:"repo_path"`
}
VerifyObligationInput mirrors verify_obligation(obligation, repo_path=""). Obligation is the raw dict (an ExtractObligations output element); the reasoner validates it into the private obligation struct exactly as Python runs _Obligation.model_validate.