Skip to content

Commit efbbdfc

Browse files
authored
Merge pull request #265 from control-toolbox/feature/enriched-exceptions-migration
feat: enriched exception system with user-friendly error messages
2 parents b508249 + 10686c2 commit efbbdfc

323 files changed

Lines changed: 6386 additions & 753 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agent/rules/docstrings.md

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
---
2+
trigger: always_on
3+
---
4+
5+
# Julia Documentation Standards
6+
7+
This document defines the documentation standards for the Control Toolbox project. All Julia code (functions, structs, macros, modules) must be documented following these guidelines.
8+
9+
## Core Principles
10+
11+
1. **Completeness**: Every exported symbol and significant internal component must have a docstring
12+
2. **Accuracy**: Documentation must reflect actual behavior, not aspirational or outdated information
13+
3. **Clarity**: Write for users who understand Julia but may be unfamiliar with the specific domain
14+
4. **Consistency**: Follow the templates and conventions defined here
15+
16+
## Docstring Placement
17+
18+
- Docstrings go **immediately above** the declaration they document
19+
- No blank lines between docstring and declaration
20+
- For multi-method functions, document the most general signature or provide method-specific docstrings
21+
22+
## Required Docstring Structure
23+
24+
Every docstring should contain:
25+
26+
1. **Signature line** (for functions): Use `$(TYPEDSIGNATURES)` from DocStringExtensions
27+
2. **One-sentence summary**: Clear, concise description of purpose
28+
3. **Detailed description** (if needed): Explain behavior, constraints, invariants, edge cases
29+
4. **Structured sections** (as applicable):
30+
- `# Arguments`: For functions/macros
31+
- `# Fields`: For structs/types
32+
- `# Returns`: For functions that return values
33+
- `# Throws`: For functions that may throw exceptions
34+
- `# Example` or `# Examples`: Demonstrate usage
35+
- `# Notes`: Performance considerations, stability warnings, implementation details
36+
- `# References`: Citations to papers, algorithms, or external documentation
37+
- `See also:`: Related functions/types with `[@ref]` links
38+
39+
## Templates
40+
41+
### Function Template
42+
43+
```julia
44+
"""
45+
$(TYPEDSIGNATURES)
46+
47+
One-sentence description of what the function does.
48+
49+
Optional detailed explanation covering:
50+
- Behavior and semantics
51+
- Constraints and preconditions
52+
- Common use cases or patterns
53+
54+
# Arguments
55+
- `arg1::Type1`: Description of first argument
56+
- `arg2::Type2`: Description of second argument
57+
58+
# Returns
59+
- `ReturnType`: Description of return value
60+
61+
# Throws
62+
- `ExceptionType`: When and why this exception is thrown
63+
64+
# Example
65+
\`\`\`julia-repl
66+
julia> using CTModels.ModuleName
67+
68+
julia> result = function_name(arg1, arg2)
69+
expected_output
70+
\`\`\`
71+
72+
# Notes
73+
- Performance characteristics (if relevant)
74+
- Thread safety (if relevant)
75+
- Stability guarantees
76+
77+
See also: [`related_function`](@ref), [`RelatedType`](@ref)
78+
"""
79+
function function_name(arg1::Type1, arg2::Type2)::ReturnType
80+
# implementation
81+
end
82+
```
83+
84+
### Struct Template
85+
86+
```julia
87+
"""
88+
$(TYPEDEF)
89+
90+
One-sentence description of what this type represents.
91+
92+
Optional detailed explanation covering:
93+
- Purpose and design intent
94+
- Invariants that must be maintained
95+
- Relationship to other types
96+
97+
# Fields
98+
- `field1::Type1`: Description and constraints
99+
- `field2::Type2`: Description and constraints
100+
101+
# Constructor Validation
102+
103+
Describe any validation performed by constructors (if applicable).
104+
105+
# Example
106+
\`\`\`julia-repl
107+
julia> using CTModels.ModuleName
108+
109+
julia> obj = StructName(value1, value2)
110+
StructName(...)
111+
112+
julia> obj.field1
113+
value1
114+
\`\`\`
115+
116+
# Notes
117+
- Mutability status (if not obvious from declaration)
118+
- Performance considerations
119+
120+
See also: [`related_type`](@ref), [`constructor_function`](@ref)
121+
"""
122+
struct StructName{T}
123+
field1::Type1
124+
field2::Type2
125+
end
126+
```
127+
128+
### Abstract Type Template
129+
130+
```julia
131+
"""
132+
$(TYPEDEF)
133+
134+
One-sentence description of the abstraction.
135+
136+
Detailed explanation of:
137+
- What types should subtype this
138+
- Contract/interface requirements for subtypes
139+
- Common behavior across all subtypes
140+
141+
# Interface Requirements
142+
143+
List methods that subtypes must implement:
144+
- `required_method(::SubType)`: Description
145+
146+
# Example
147+
\`\`\`julia-repl
148+
julia> using CTModels.ModuleName
149+
150+
julia> MyType <: AbstractTypeName
151+
true
152+
\`\`\`
153+
154+
See also: [`ConcreteSubtype1`](@ref), [`ConcreteSubtype2`](@ref)
155+
"""
156+
abstract type AbstractTypeName end
157+
```
158+
159+
## Example Safety Policy
160+
161+
Examples in docstrings must be **safe and reproducible**:
162+
163+
### ✅ Safe Examples
164+
165+
- Pure computations with deterministic results
166+
- Constructors with simple, valid inputs
167+
- Queries on created objects
168+
- Examples that start with `using CTModels.ModuleName`
169+
170+
### ❌ Unsafe Examples
171+
172+
- File system operations (reading/writing files)
173+
- Network requests
174+
- Database operations
175+
- Git operations
176+
- Non-deterministic behavior (random numbers without seed, timing-dependent code)
177+
- Long-running computations (>1 second)
178+
- Dependencies on external state or global variables
179+
180+
### Fallback for Complex Cases
181+
182+
If a safe, runnable example cannot be provided:
183+
- Use a plain code block (\`\`\`julia) instead of REPL block (\`\`\`julia-repl)
184+
- Show usage patterns without claiming specific output
185+
- Provide a conceptual sketch of how to use the API
186+
187+
Example:
188+
```julia
189+
# Example
190+
\`\`\`julia
191+
# Conceptual usage pattern
192+
ocp = Model(...)
193+
constraint!(ocp, :state, 0.0, :initial)
194+
sol = solve(ocp, strategy=MyStrategy())
195+
\`\`\`
196+
```
197+
198+
## Module Prefix Convention
199+
200+
- **Exported symbols**: Use directly without module prefix
201+
```julia-repl
202+
julia> using CTModels.Options
203+
julia> opt = OptionValue(100, :user) # OptionValue is exported
204+
```
205+
206+
- **Internal symbols**: Use module prefix
207+
```julia-repl
208+
julia> using CTModels.Options
209+
julia> Options.internal_function(...) # Not exported
210+
```
211+
212+
## DocStringExtensions Macros
213+
214+
This project uses [DocStringExtensions.jl](https://github.com/JuliaDocs/DocStringExtensions.jl):
215+
216+
- `$(TYPEDEF)`: Auto-generates type signature for structs/abstract types
217+
- `$(TYPEDSIGNATURES)`: Auto-generates function signature with types
218+
- Use these instead of manually writing signatures
219+
220+
## Quality Checklist
221+
222+
Before finalizing a docstring, verify:
223+
224+
- [ ] Docstring is directly above the declaration (no blank lines)
225+
- [ ] Uses `$(TYPEDEF)` or `$(TYPEDSIGNATURES)` where applicable
226+
- [ ] One-sentence summary is clear and accurate
227+
- [ ] All arguments/fields are documented with types and descriptions
228+
- [ ] Return value is documented (if applicable)
229+
- [ ] Exceptions are documented (if thrown)
230+
- [ ] Example is safe, runnable, and demonstrates typical usage
231+
- [ ] Cross-references use `[@ref]` syntax for related items
232+
- [ ] No invented behavior or aspirational features
233+
- [ ] Consistent with project style and terminology

0 commit comments

Comments
 (0)