ryo_suggest/lib.rs
1//! RYO Suggest - Continuous refactoring suggestion engine
2//!
3//! This crate provides code improvement suggestions through pattern detection
4//! and generates MutationSpecs for execution via ryo-executor.
5//!
6//! # Architecture
7//!
8//! ```text
9//! ┌─────────────────────────────────────────────────────────────────┐
10//! │ Suggest Domain Layer │
11//! │ ─────────────────── │
12//! │ SuggestRegistry SuggestStore SuggestService │
13//! │ ├─ register() ├─ insert() ├─ query() │
14//! │ ├─ get() ├─ get() ├─ detect() │
15//! │ └─ by_category() └─ gc() └─ to_specs() │
16//! │ ↓ ↓ ↓ │
17//! │ Suggest.detect() → SuggestOpportunity → MutationSpec │
18//! └─────────────────────────────────────────────────────────────────┘
19//! ```
20//!
21//! # Usage
22//!
23//! ```ignore
24//! use ryo_suggest::{
25//! SuggestService, SuggestRegistry, SuggestQuery,
26//! Suggest, SuggestCategory, SafetyLevel,
27//! };
28//!
29//! // Create registry and register patterns
30//! let mut registry = SuggestRegistry::new();
31//! registry.register(MyPattern::new());
32//!
33//! // Create service
34//! let service = SuggestService::new(registry);
35//!
36//! // Detect suggestions
37//! let count = service.detect(&ctx, &symbols);
38//!
39//! // Query suggestions
40//! let auto_safe = service.query(
41//! &SuggestQuery::all().with_max_safety(SafetyLevel::Auto)
42//! );
43//!
44//! // Generate mutation specs
45//! for (id, _, _) in auto_safe {
46//! if let Some(specs) = service.to_mutation_specs(id, &ctx) {
47//! // Execute specs via ryo-executor...
48//! }
49//! }
50//! ```
51//!
52//! # Key Components
53//!
54//! - [`Suggest`] - Trait for implementing detection patterns
55//! - [`SuggestRegistry`] - Registration and lookup for Suggest implementations
56//! - [`SuggestStore`] - Lifecycle management with generation-based invalidation
57//! - [`SuggestService`] - Thread-safe service with RwLock for concurrent access
58//! - [`SuggestStrategy`] - Control re-evaluation timing (PerGoal/PerWave/Manual)
59//! - [`IntentLockQuery`] / [`IntentLockOps`] - Dirty read prevention traits
60//!
61//! # Spec Suggests
62//!
63//! ## Implemented (Problem Detection)
64//!
65//! | Code | Name | Category | Safety | Description |
66//! |------|------|----------|--------|-------------|
67//! | RS001 | `MissingSpecForDomainType` | Lint | Confirm | Detect domain types without Spec TypeAlias |
68//! | RS002 | `OrphanSpec` | Refactor | Confirm | Detect unused Spec TypeAliases |
69//! | RS003 | `InvalidSpecRelation` | Lint | Manual | Detect SpecRelation targets that don't exist |
70//! | RS004 | `SpecGroupInconsistency` | Lint | Manual | Detect mixed Groups in same module |
71//! | RS005 | `SpecRelationCycle` | Lint | Manual | Detect circular dependencies in SpecRelations |
72//! | RS006 | `MissingRelation` | Pattern | Confirm | Suggest Relations based on struct field types |
73//!
74//! ## Implemented (Spec-Driven)
75//!
76//! | Code | Name | Category | Safety | Description |
77//! |------|------|----------|--------|-------------|
78//! | RS007 | `SpecRelationToField` | Pattern | Confirm | Spec relation → struct field suggestion |
79//! | RS008 | `BidirectionalRelation` | Pattern | Confirm | Ensure bidirectional Spec relations |
80//!
81//! ## Future Candidates (Spec-Driven)
82//!
83//! | Code | Name | Category | Description |
84//! |------|------|----------|-------------|
85//! | RS009 | `SpecDrivenMethod` | Pattern | Spec relation → accessor method suggestion |
86//! | RS010 | `SpecGroupTrait` | Pattern | Group → common trait implementation |
87//! | RS011 | `SpecDrivenRepository` | Pattern | Spec → Repository trait generation |
88//!
89//! # Performance Suggestions
90//!
91//! | Code | Name | Category | Safety | Description |
92//! |------|------|----------|--------|-------------|
93//! | RP001 | `UnnecessaryClone` | Performance | Confirm | Detect clone() where ownership is not needed |
94//!
95//! # Safety Suggestions
96//!
97//! | Code | Name | Category | Safety | Description |
98//! |------|------|----------|--------|-------------|
99//! | RS101 | `UnwrapToExpect` | Safety | Confirm | Convert unwrap() to expect() with descriptive message |
100//! | RS102 | `StringErrorType` | Safety | Manual | Detect string-based error types, suggest thiserror |
101//!
102//! ## Spec-First Generation (Planned)
103//!
104//! For greenfield development, a different approach is needed:
105//!
106//! ```text
107//! ┌─────────────────────────────────────────────────────────────────┐
108//! │ Spec-First Generation (vs Problem Detection) │
109//! │ ───────────────────────────────────────────── │
110//! │ │
111//! │ Problem Detection (current): │
112//! │ Code → detect() → Problems → MutationSpec │
113//! │ │
114//! │ Spec-First Generation (planned): │
115//! │ Spec Definition → generate() → New Code │
116//! │ │
117//! │ Use Cases: │
118//! │ - New domain model from Spec │
119//! │ - Scaffold struct/fields/methods from Spec relations │
120//! │ - Generate Repository/Service patterns from Spec Group │
121//! └─────────────────────────────────────────────────────────────────┘
122//! ```
123
124mod allow;
125pub mod design_choice;
126pub mod enhanced;
127pub mod generator;
128mod id;
129pub mod intent_lock;
130pub mod lint;
131pub mod pattern;
132pub mod performance;
133pub mod safety;
134mod service;
135pub mod spec;
136mod store;
137mod suggest;
138mod suggest_registry;
139mod trigger;
140
141// ========== Core Exports ==========
142pub use allow::AllowStore;
143pub use id::{ParseSuggestIdError, SuggestId, SuggestIdGenerator};
144pub use intent_lock::{IntentId, IntentLockOps, IntentLockQuery, LockError, NoOpIntentLock};
145pub use service::{
146 DetectWithPrecheckResult, ParameterizedSuggestInfo, SuggestQuery, SuggestService, SuggestStats,
147 SuggestView,
148};
149pub use store::{GcConfig, PrecheckStatus, StoredSuggestion, SuggestIndex, SuggestStore};
150pub use suggest::{
151 compute_priority, EnumToTraitStrategy, LintSeverity, MatchHandling, MutationSpec,
152 OpportunityContext, OpportunityId, ParamDef, SafetyLevel, Suggest, SuggestBox, SuggestCategory,
153 SuggestError, SuggestLocation, SuggestOpportunity, SuggestParams, SuggestResult, SymbolScope,
154};
155pub use suggest_registry::SuggestRegistry;
156pub use trigger::{
157 AcChanges, EvalGranularity, GoalId, PendingChanges, SuggestStrategy, SuggestTrigger,
158 TriggerKind, WaveId,
159};
160
161// Pattern integration
162pub use pattern::{PatternBasedSuggest, RuleScope, RuleStore, RuleStoreError};
163
164// ========== Enhanced Suggestions ==========
165pub use design_choice::{ChoiceId, DesignChoice, DesignChoiceSet, Rating, TradeOffs};
166pub use enhanced::{ApplyCommands, EnhancedSuggestion, VerificationStatus, VerifiedCandidate};
167
168// ========== Spec Suggestions ==========
169pub use spec::{
170 BidirectionalRelation, InvalidSpecRelation, MissingRelation, MissingSpecForDomainType,
171 OrphanSpec, SpecGroupInconsistency, SpecRelationCycle, SpecRelationToField,
172};
173
174// ========== Parameterized Suggestions (Code Generation) ==========
175pub use spec::{ApiPatternSuggest, DomainStructSuggest};
176
177// ========== Spec Generators ==========
178pub use spec::{DomainSpecGenerator, GeneratorOptions, SpecGenerator, SpecGeneratorRegistry};
179
180// ========== Generator Templates (User-defined) ==========
181pub use generator::{
182 GeneratorEntry, GeneratorLoadError, GeneratorLoader, GeneratorMeta, GeneratorScope,
183 GeneratorStore, GeneratorStoreError, GeneratorTemplate, InsertPosition, ParamSpec, RenderError,
184 TemplateSpec,
185};
186
187// ========== Performance Suggestions ==========
188pub use performance::{PerformanceSuggest, UnnecessaryClone};
189
190// ========== Safety Suggestions ==========
191pub use safety::{SafetySuggest, StringErrorType, UnwrapToExpect};