Resilient Stability and Compatibility Policy
Overview
This document defines stability promises, compatibility guarantees, deprecation rules, and the expectations users can rely on as Resilient evolves. It answers: “When will my code break?”
Core Principle
Stability commitment: Once a feature reaches the Stable tier, it will not break in minor or patch releases.
Breaking changes are announced at least one major version in advance and supported for at least three minor releases before removal.
Semantic Versioning
Resilient follows semantic versioning (MAJOR.MINOR.PATCH):
Patch Release (1.0.x → 1.0.y)
When: Bugfixes only, no new features
Guarantee: No breaking changes to any public API
Example: 1.0.5 → 1.0.6 is always safe to update
Minor Release (1.x.0 → 1.y.0)
When: New features, incremental improvements
Guarantee: All Stable features from 1.x.0 remain compatible
What may change:
- New Stable features added
- Performance improvements
- Better error messages
- New warnings (not errors)
Example: 1.2.0 → 1.3.0 is safe for production code using 1.2.0
Major Release (1.0.0 → 2.0.0)
When: Design improvements, architectural changes, removal of deprecated features
Guarantee: May contain breaking changes
Required action: Users must review changelog and update their code
Example: 1.9.9 → 2.0.0 requires testing and potential code updates
Feature Tier System
Stable
Definition: Fully specified, tested, documented, and ready for long-term production use.
Stability guarantee:
- Will not change in incompatible ways in minor versions
- Will be supported indefinitely (until explicitly deprecated)
- Breaking changes only in major versions
Migration guarantee: If removed, users get:
- At least 3 minor releases warning
- Clear deprecation message
- Migration guide
- Compiler support for old syntax (with warning)
Example Stable features:
- Basic types (int, float, bool, string, arrays)
- Function definitions and calls
- Control flow (if, while, for, match)
- Memory model (stack, static allocation)
- Pattern matching
Backend-Limited
Definition: Fully implemented on some backends, not all.
Stability guarantee:
- Will not change on supported backends without notice
- Support status may change in minor versions
Migration guarantee: If support is dropped, users get:
- Compiler error on unsupported backends
- Clear diagnostic
- Documentation of migration path
Example Backend-Limited features:
- JIT-specific optimizations
- RISC-V interrupt handling
- Cortex-M MMIO annotations
Experimental
Definition: Under design or implementation, may change frequently.
Stability guarantee: None. Breaking changes without notice.
No migration guarantee: May be removed or significantly changed at any time.
Example Experimental features:
- Async/await (future)
- Generic constraints (future)
- Effects system (future)
Backward Compatibility Rules
What’s NOT a breaking change
The following are safe in minor releases:
✅ Adding new functions or methods
✅ Adding new public types (as long as existing code doesn’t break)
✅ Making type checking stricter (previously accepted code may now error)
✅ Adding compiler warnings (not errors)
✅ Improving error messages
✅ Performance improvements (as long as semantics unchanged)
✅ Adding new compiler options/flags
✅ Optimizing stdlib functions
What IS a breaking change
The following require a major version bump:
❌ Removing a public function, type, or constant
❌ Changing function signature (parameter types, return type)
❌ Changing type definition (adding non-optional fields, removing fields)
❌ Changing behavior of a stable function
❌ Changing error codes or diagnostic format (in a non-backward-compatible way)
❌ Removing support for a stable backend
❌ Changing memory layout of public types
Deprecation Process
Step 1: Announce (Minor Release N)
Add deprecation warning to the feature:
/// Deprecated since 1.5.0; use `new_function` instead.
#[deprecated(since = "1.5.0", note = "use new_function")]
pub fn old_function() {
// ...
}
Action:
- Release notes mention deprecation
- Compiler warns when code uses feature
- Error message suggests alternative
Step 2: Support Period (Minor Releases N, N+1, N+2)
The old feature continues to work with warnings:
- 1.5.0: Warning introduced
- 1.6.0: Still works, still warns
- 1.7.0: Still works, still warns
- 1.8.0: Last chance! Final warning
Step 3: Hard Error (Minor Release N+3)
Feature becomes hard error:
- 1.9.0: Compiler rejects the feature
- Users must update their code
Step 4: Removal (Later Major Release)
In version 2.0+, implementation code may be removed entirely.
Language Reference Stability
Stable Language Features
These will remain compatible:
- Core syntax (functions, variables, types)
- Arithmetic and logic operators
- Control flow (if, for, while, match)
- Memory safety rules
- Type system basics
- Pattern matching
- Error handling (Result, try)
Subject to Change (with notice)
- Compiler error messages (format, codes)
- Exact diagnostics and their positions
- Stdlib API organization (re-exports may move)
- Optimization behavior (as long as semantics preserved)
- Backend implementation details
Not Guaranteed
- Internal compiler structure
- Exact performance characteristics
- Timing of compilation passes
- Specific optimization order
- Internals of stdlib functions
Stdlib Stability
Tier 0 (Core): Stable
All Tier 0 (Core) functions are Stable:
pub fn add(int x, int y) -> int { ... } // Stable
pub fn reverse<T>(array<T>) -> array<T> { ...} // Stable
Guarantee: Never changes, never removed
Tier 1 (Alloc): Stable (feature-gated)
Tier 1 functions are Stable when the alloc feature is enabled:
#[cfg(feature = "alloc")]
pub fn allocate_vector(capacity: int) -> Vec<int> { ... } // Stable (when alloc enabled)
Guarantee: Doesn’t change when feature is enabled
Tier 2 (Std): Stable (host-only)
Tier 2 functions are Stable on host platforms:
#[cfg(feature = "std")]
pub fn read_file(path: string) -> Result<string, string> { ... } // Stable
Guarantee: Doesn’t change on supported platforms
Tier 3 (Platform): Backend-Limited
Platform-specific APIs may change:
#[cfg(target = "thumbv7em-none-eabihf")]
pub fn cortex_m_specific() { ... } // Backend-Limited
API Evolution Patterns
Pattern 1: Rename with Deprecation
// v1.4.0
#[deprecated(since = "1.4.0", note = "use compute_result")]
pub fn compute(x: int) -> int {
return compute_result(x); // delegate to new name
}
pub fn compute_result(x: int) -> int {
// actual implementation
}
// v1.8.0+: remove old function entirely
Pattern 2: Add Optional Parameter with Feature Gate
// v1.5.0: old signature
pub fn process(data: string) -> string {
return process_internal(data, false);
}
// v1.6.0: new optional param (feature-gated)
#[cfg(feature = "strict_mode")]
pub fn process(data: string, strict: bool) -> string {
return process_internal(data, strict);
}
Pattern 3: Move Function to Module
// v1.4.0
pub fn old_location_compute() { ... }
// v1.5.0
pub mod computing {
pub fn compute() { ... }
}
#[deprecated(since = "1.5.0", note = "use computing::compute")]
pub fn old_location_compute() {
return computing::compute();
}
// v1.9.0: remove old location
Tooling Stability
Compiler (rz)
Stable:
- Exit codes (0 = success, 1+ = errors)
- Diagnostic format (file:line:col: level: message)
- Command-line options listed in
--help
Subject to change:
- Exact error messages
- Internal compiler optimizations
- Specific diagnostic colors/formatting
Package Manager (rz package)
Stable:
- Resilient.toml format
- Dependency resolution algorithm
- Lock file format
- Package naming conventions
Subject to change:
- CLI subcommand names (with deprecation)
- Config file locations
- Registry protocol details (with migration path)
LSP Server
Stable:
- Basic completion support
- Hover information
- Go to definition
Subject to change:
- Exact ordering of completions
- Performance characteristics
- Internal diagnostic codes
Security and Safety
Security Policy
Vulnerability reporting: security@resilient-lang.org
Supported versions:
- Latest major version: all patches
- Previous major version: security patches only
- Older: no support
Notification: Security fixes announced in release notes
Memory Safety
The memory safety guarantees (no use-after-free, no data races, etc.) are not subject to change except to become stricter.
If a bug is found in the safety checker, it will be:
- Fixed immediately
- May cause previously valid code to become invalid
- Announced in release notes
- Not considered a breaking change (safety is paramount)
Breaking Change Examples
Example 1: Function Removal
v1.5.0: fn read_sync() [deprecated, use read_async]
v1.6.0: fn read_sync() [still there, warns]
v1.7.0: fn read_sync() [still there, warns]
v1.8.0: fn read_sync() [still there, warns]
v1.9.0: Compilation error [fn read_sync() removed]
v2.0.0: Function gone forever
Example 2: Type Change
// v1.5.0
pub fn get_value() -> Result<int, string> { ... }
// v1.8.0 [planned for 2.0]
// [deprecation period]
// v2.0.0 [breaking change]
pub fn get_value() -> Result<int, Error> { ... } // Changed error type
Example 3: Feature Removal
# v1.5.0
[features]
legacy_api = [] # Experimental API
# v1.8.0
# [removed without warning - was Experimental]
# v1.9.0
# Users must remove feature from Resilient.toml
Upgrade Guidance
From 1.x to 1.y (Same Major)
Action: Safe to upgrade automatically (or in CI)
rz update # Safe: no breaking changes
From 1.x to 2.0 (Major)
Action: Review changelog and test thoroughly
- Read breaking changes section in release notes
- Update code to use new APIs
- Run full test suite
- Deploy with confidence
Version Pinning Strategy
For Applications
Pin major version, allow minor/patch:
[dependencies]
mylib = "1.5" # Allows 1.5.0, 1.6.0, but not 2.0.0
For Libraries
Pin major version, be conservative with minor:
[dependencies]
foundation = "1.0" # Stability critical
utils = "2" # Less critical
For Research/Experimental
Can use experimental features with understanding of risk:
[features]
experimental_async = [] # Will break in future
Feedback and Discussions
Proposing Changes
- Open GitHub discussion for feedback
- Collect community input
- Document design decision
- Implement with proper deprecation if breaking
Reporting Incompatibilities
If you believe something breaks the stability policy:
- Check release notes (might be intentional)
- Open GitHub issue with details
- Include version information
- Provide minimal reproduction
Timeline
v0.x Series (Development)
- Breaking changes allowed
- Features may move between tiers
- No strict compatibility guarantees
v1.0 (Stability Release)
- Feature set stabilized
- Compatibility policy kicks in fully
- Semver strictly followed
v1.x Series (Stable)
- Compatibility guaranteed
- Breaking changes only in v2.0+
- Long-term production use recommended
v2.0+ (Future)
- May include breaking changes
- Clear migration path provided
- Multiple deprecation cycle approach
Summary
| Action | Patch | Minor | Major |
|---|---|---|---|
| New features | ❌ | ✅ | ✅ |
| Bug fixes | ✅ | ✅ | ✅ |
| Breaking changes | ❌ | ❌ | ✅ |
| Deprecate features | ❌ | ✅ | ✅ |
| Remove deprecated | ❌ | ❌ | ✅ |
References
- RES-3510: Publish a stability and compatibility policy
- RES-3501: Stabilize language reference and feature-tier policy
- LANGUAGE.md: Feature tier definitions
- MODULE_SYSTEM.md: Package versioning