Adding Calor to Existing Projects
This guide takes an existing C# project from Calor setup to a small mixed Calor/C# pilot. You will convert one well-tested file, review what could not be translated, build it with the rest of the project, and inspect its impact.
Overview
Adding Calor to an existing project is a gradual process:
- Enable Calor - Add MSBuild integration
- Analyze the codebase - Find useful pilot candidates
- Add a Calor file - Confirm the mixed project builds
- Build and verify - Exercise the normal project workflow
- Convert one C# file - Validate and review the result
- Inspect project impact - Query a converted method and its callers
You don't need to convert everything at once. Calor and C# coexist seamlessly.
Step 1: Enable Calor in Your Project
Enable Calor with MSBuild integration:
# Initialize Calor in your project
calor init
# Or specify a specific project file
calor init --project MyApp.csproj
Your .csproj is updated with MSBuild targets that compile .calr files automatically during dotnet build.
Step 2: Analyze Your Codebase
Use calor assess to find C# files that would benefit most from Calor:
# Analyze your source directory
calor assess ./src
# Show top 10 candidates with detailed scores
calor assess ./src --top 10 --verbose
Understanding the Output
=== Calor Migration Analysis ===
Analyzed: 42 files
Average Score: 34.2/100
Top 10 Files for Migration:
--------------------------------------------------------------------------------
82/100 [Critical] src/Services/PaymentProcessor.cs
78/100 [Critical] src/Services/OrderService.cs
65/100 [High] src/Repositories/UserRepository.cs
| Priority | Score | Recommendation |
|---|---|---|
| Critical | 76-100 | Convert to Calor - high benefit |
| High | 51-75 | Good conversion candidate |
| Medium | 26-50 | Optional - some benefit |
| Low | 0-25 | Keep in C# - minimal benefit |
Step 3: Add Your First Calor File
Create a new .calr file alongside your existing code:
§M{m001:Calculator}
§F{f001:Add:pub}
§I{i32:a}
§I{i32:b}
§O{i32}
§R (+ a b)
Step 4: Build and Verify
# Build your project - Calor compiles automatically
dotnet build
The build process:
- Finds all
.calrfiles in your project - Compiles each to
.g.csin theobj/calor/directory - Includes generated C# in the normal compilation
Step 5: Convert High-Scoring C# Files
Based on your analysis results, convert files that score High or Critical:
# Convert, parse-check, and return the structured loss report
calor convert src/Services/PaymentProcessor.cs --validate --format json
# With benchmark comparison
calor convert src/Services/PaymentProcessor.cs --validate --benchmark
For bulk conversion:
calor migrate ./src --dry-run # Preview first
calor migrate ./src # Execute
Review the Conversion Result
Conversion is not an all-or-nothing claim. The command above returns JSON;
without --format json, inspect the equivalent text loss report. Review:
losses[]in JSON output or the text loss report,- every
§CSHARPblock that preserves source the converter could not express natively, - validation diagnostics,
- the generated C# and existing tests.
When a member cannot be converted safely, calor convert can preserve the
original C# inside §CSHARP rather than discarding the whole file. That is a
useful migration boundary, not completed conversion. --passthrough widens the
set of members eligible for preservation; --no-fallback asks the command to
fail instead.
The converter is continuously exercised against MediatR, Serilog, and FluentValidation. All 364 converted modules currently parse, but parse success does not mean every member is native Calor or that every call binds. The loss report and interop blocks remain the source of truth for each file.
Use a Migration Waiver Deliberately
Converted code often calls APIs the compiler cannot resolve yet. Prefer the project-file permissive setting over switching effect checking off:
<PropertyGroup>
<CalorPermissiveEffects>true</CalorPermissiveEffects>
</PropertyGroup>
This suppresses the two “cannot tell” diagnostics (Calor0411 and
Calor0425) and demotes Calor0410 to a warning. It never waives a known
callback mismatch (Calor0424) or an override/interface violation
(Calor0420, Calor0421). Because unknown calls are assumed harmless, this
waives the full effect guarantee. Record the setting in the pull request, and
pass --permissive-effects to calor review-packet so the waiver prints on
the packet's first line.
Step 6: Build and Inspect Project Impact
After the converted file builds, create or refresh the project index:
dotnet build
calor index build .
calor query effects ProcessPayment --in-file src/Services/PaymentProcessor.calr
calor query callers ProcessPayment --in-file src/Services/PaymentProcessor.calr
calor query impact ProcessPayment --in-file src/Services/PaymentProcessor.calr
Replace ProcessPayment with a converted method. Effect queries apply to
functions, methods, constructors, and accessors, not to the containing class.
Read any PARTIAL residual before relying on a caller count. For an
agent-driven workflow, use the equivalent calor_query MCP tool and compile
with options.crossModule: true so effects are checked across files.
See Project Intelligence for Agents for the complete pre-edit and post-edit loop.
Optional: Enable Claude Code Integration
For AI-assisted Calor development:
calor init --ai claude
This adds:
/calorand/calor-convertskillsCLAUDE.mdwith guidelines instructing Claude to write new code in Calor and analyze C# files before modifying them
Using Claude Code
Write new Calor code:
/calor
Write a function that validates email addresses with:
- Precondition: input is not null or empty
- Postcondition: returns true only for valid emails
Convert existing C# to Calor:
/calor-convert src/Services/PaymentProcessor.cs
Best Practices
What to Convert First
- Small, well-tested files with a clear owner and rollback path
- Contract-dense code where preconditions and postconditions add value
- Pure or first-order effect-checked code with few dynamic boundaries
- High-scoring files from
calor assess, after the first three checks
What to Keep in C#
- Simple DTOs and record types
- Auto-generated code (EF migrations, gRPC stubs)
- Code using features Calor doesn't support yet
- Reflection-heavy, dynamic, or delegate-heavy service layers for the first pilot
Next Steps
- Syntax Reference - Complete Calor language reference
- Contracts - Writing preconditions and postconditions
- Effects - Declaring side effects
- calor assess - Understanding migration scores
- calor convert - Conversion losses, validation, and interop rescue
- Project Intelligence for Agents - Query callers and impact