import type { ContextPackClaim, ContextPackCoverage, ContextPackExpandableRef, ContextPackTaskContract } from '../contracts/context-pack.js'; import { KnowledgeGraph } from '../contracts/graph.js'; import type { TaskIntentKind } from '../contracts/task-intent.js'; import type { CompactRetrieveMatchedNode, RetrieveCommunityContext, RetrieveMatchedNode, RetrieveRelationship } from './retrieve.js'; import { type SourceLineRange } from '../shared/source-location.js'; import { type RiskMapHotspot, type RiskSeverity } from './risk-map.js'; export interface PrImpactOptions { baseBranch?: string; depth?: number; budget?: number; taskIntent?: TaskIntentKind; } export interface ChangedNode { node_id: string; label: string; source_file: string; node_kind: string; community: number | null; community_label: string | null; line_number: number | null; source_location: string | null; } export interface PrImpactSeedNode extends ChangedNode { match_kind: 'line' | 'file'; } export interface ChangedFileRanges { source_file: string; line_ranges: SourceLineRange[]; } export interface PrReviewBundle { budget: number; token_count: number; nodes: RetrieveMatchedNode[]; relationships: RetrieveRelationship[]; community_context: RetrieveCommunityContext[]; task_contract?: ContextPackTaskContract; claims?: ContextPackClaim[]; expandable?: ContextPackExpandableRef[]; coverage?: ContextPackCoverage; } export interface PrImpactResult { base_branch: string; changed_files: string[]; changed_ranges: ChangedFileRanges[]; changed_nodes: ChangedNode[]; seed_nodes: PrImpactSeedNode[]; per_node_impact: Array<{ node: string; direct_dependents: number; transitive_dependents: number; affected_communities: number; }>; total_blast_radius: number; affected_files: string[]; affected_communities: Array<{ id: number; label: string; node_count: number; }>; review_context: { supporting_paths: string[]; test_paths: string[]; hotspots: RiskMapHotspot[]; }; review_bundle: PrReviewBundle; risk_summary: { high_impact_nodes: string[]; cross_community_changes: number; top_risks: Array<{ label: string; severity: RiskSeverity; reason: string; }>; }; /** * #79 — Coverage score in [0, 1] for the compact review_bundle's coverage * of high-impact nodes. 1.0 = every high-impact node has at least one * representative in the review_bundle. Lower values mean the compact * pack risks silently dropping a hotspot. */ coverage_score: number; /** * #79 — High-impact changed nodes that are NOT represented in the * review_bundle. Surfaced so reviewers and AI agents can audit the * compact pack before trusting it as the basis for review decisions. */ uncovered_hotspots: ChangedNode[]; /** * #79 (v0.16 refinement) — weighted coverage score in [0, 1]. Bridge * and god-node hotspots count 3x more than regular high-impact nodes * because their uncoverage carries asymmetric review risk: missing a * bridge node in the review pack means an entire downstream community * goes unreviewed. The unweighted `coverage_score` field above * remains for back-compat; consumers should prefer `coverage_score_weighted`. */ coverage_score_weighted: number; /** * #79 (v0.16 refinement) — per-hotspot severity tiers. Same labels as * `uncovered_hotspots`, plus a `severity` field of 'critical' (bridge * or god node), 'high' (regular high-impact), or 'medium' (any other * uncovered changed node). */ uncovered_hotspot_severities: Array<{ label: string; severity: 'critical' | 'high' | 'medium'; }>; /** * #79 (v0.16 refinement) — labels among the high-impact set that are * bridge / god nodes. Used by `compactPrImpactResult` so it can * recompute the weighted coverage score against the compacted review * bundle without re-deriving graph centrality. */ critical_labels: string[]; } export interface CompactPrImpactNodeImpact { node: string; total_dependents: number; affected_communities: number; } export interface CompactPrReviewNode extends Omit { node_id?: string; match_score?: number; } export interface CompactPrReviewRelationship extends Omit { } export interface CompactPrReviewBundle extends Omit { token_count: number; nodes: CompactPrReviewNode[]; relationships: CompactPrReviewRelationship[]; shared_file_type?: string; } export interface CompactPrImpactResult extends Pick { per_node_impact: CompactPrImpactNodeImpact[]; review_bundle: CompactPrReviewBundle; } export declare function analyzePrImpact(graph: KnowledgeGraph, projectDir?: string, options?: PrImpactOptions): PrImpactResult; export declare function compactPrImpactResult(result: PrImpactResult): CompactPrImpactResult;