semver-analyzer-core
Language-agnostic foundation for the semver-analyzer workspace. Defines shared data types, trait abstractions, the structural diff engine, and concurrent shared state for the TD/BU analysis pipelines.
No language-specific logic lives here. Language crates (e.g., semver-analyzer-ts) depend on this crate and implement its traits.
Key Traits
Language
The primary extension point. Language crates implement this to plug into the analysis pipeline. Composes LanguageSemantics + MessageFormatter + Send + Sync + 'static.
LanguageSemantics
Encodes language-specific breaking-change rules consumed by the diff engine.
| Method | Purpose |
|---|---|
is_member_addition_breaking |
Whether adding a member to a container is breaking |
same_family |
Whether two symbols belong to the same logical group |
same_identity |
Whether two symbols represent the same concept at different paths |
visibility_rank |
Numeric visibility rank (higher = more visible) |
parse_union_values |
Parse union/constrained type values for fine-grained diffing |
post_process |
Language-specific post-processing of the change list |
BehaviorAnalyzer
Language-agnostic LLM-based behavioral analysis interface.
| Method | Purpose |
|---|---|
infer_spec |
Infer a function's behavioral spec from its body |
infer_spec_with_test_context |
Infer a spec grounded by test assertion diffs |
specs_are_breaking |
Two-tier comparison (structural then LLM fallback) |
check_propagation |
Check if a caller propagates a behavioral break |
Optional Capability Traits
HierarchySemantics-- Component hierarchy inference (React, Vue, etc.)RenameSemantics-- LLM-based rename pattern detectionBodyAnalysisSemantics-- Deterministic body-level behavioral change detection
Diff Engine
The structural diff engine compares two ApiSurface snapshots and produces StructuralChange entries using language-specific semantic rules.
// With language-specific semantics
let changes = diff_surfaces_with_semantics;
// With minimal (language-agnostic) semantics
let changes = diff_surfaces;
The engine runs a 6-phase pipeline:
- Relocation detection (moved to deprecated/next)
- Rename detection (fingerprint + LCS matching)
- Unmatched symbol collection (added/removed)
- Matched symbol comparison (signatures, types, visibility, members)
- Structural migration detection (interface absorption/decomposition)
- Language-specific post-processing
Shared State
SharedFindings<L> provides concurrent coordination between the TD and BU pipelines:
- DashMap for structural/behavioral breaks
- Broadcast channel for real-time TD-to-BU notifications
- OnceCell for API surfaces (BU blocks until TD sets them)
let shared = new;
// TD pipeline sets surfaces and broadcasts breaking changes
shared.set_old_surface;
shared.insert_structural_breaks;
// BU pipeline checks before analyzing each function
if should_skip_for_bu
Core Types
API Surface
ApiSurface-- Collection of exported symbols at a git refSymbol-- A single exported symbol (name, kind, visibility, signature, members, etc.)SymbolKind-- Function, Class, Interface, TypeAlias, Enum, Property, etc.Visibility-- Exported, Public, Protected, Internal, PrivateSignature-- Parameters, return type, type parameters, async flagParameter-- Name, type, optional/default/variadic flags
Changes
StructuralChange-- Internal diff engine output with full detailStructuralChangeType-- Added, Removed, Changed, Renamed, RelocatedChangeSubject-- What aspect changed (Symbol, Member, Parameter, ReturnType, etc.)BehavioralBreak<L>-- A detected behavioral breaking change with evidence
Reports
AnalysisReport<L>-- Full language-specific analysis reportReportEnvelope-- Self-describing, language-dispatched report containerAnalysisResult<L>-- Raw pipeline output (input tobuild_report)
CLI
Shared clap argument structs: CommonAnalyzeArgs, CommonExtractArgs, DiffArgs, CommonKonveyorArgs.
License
Apache-2.0