Stable Public API Contract

Version: 0.2.0 Last Updated: 2026-05-30 Epic: Milestone 8, Epic 5 - Document Facade Crate Role and Finalize Status: Active

Breaking Changes in v0.2.0: This release includes two categories of breaking changes:

  1. Removed short-path aliases (Epics 2 & 3): Zero-consumer pub use short-path aliases have been removed from src/lib.rs. Port traits, memory adapters, builder types, and base types that previously had paladin::<Type> short aliases now require crate-level import paths.

  2. Module rename (Epic 4): The application::use_cases module path has been renamed to application::services. Any import path containing ::use_cases:: must be updated to ::services::.

See CHANGELOG.md for the complete migration tables.


Table of Contents


Introduction

This document defines the stable public API contract for the Paladin framework—a Rust-based enterprise multi-agent orchestration framework built with Hexagonal Architecture and Domain-Driven Design principles.

Purpose

The stable API contract serves as:

  • Backwards Compatibility Promise: Types listed here follow strict semantic versioning
  • Integration Guide: Clear catalog of public types for framework users
  • Evolution Policy: Transparent process for API changes and deprecations
  • Architectural Boundary: Distinction between public API and internal implementation

Scope

This contract covers:

  • Port Traits: Primary extension points (LlmPort, GarrisonPort, etc.)
  • Domain Entities: Core business types (Paladin, Battalion, etc.)
  • Builders: Fluent construction patterns
  • Configuration: Application settings types
  • Errors: All public error enums
  • Base Types: Generic framework primitives

This contract excludes:

  • Adapter Implementations: Concrete LLM, storage, queue adapters (internal)
  • Repositories: Database access implementations (internal)
  • CLI: Command-line interface modules (binary-only)
  • Web Server: HTTP server implementation (binary-only)
  • Managers: Internal service coordinators (internal)

Target Audience

  • Library Users: Building applications with Paladin as a dependency
  • Adapter Developers: Implementing custom port trait adapters
  • Maintainers: Managing API evolution and compatibility

API Stability Guarantee

The types and traits listed in this document follow these rules:

  1. Backwards Compatibility: Breaking changes will only occur in major version bumps (0.x.0 → 1.0.0, 1.x.0 → 2.0.0)
  2. Deprecation Process: Types/methods being removed will be deprecated for at least one minor version before removal
  3. Addition Safety: New methods can be added to traits only if they have default implementations
  4. Documentation: All public API items must have comprehensive rustdoc with examples
  5. Semver Compliance: Version numbers follow Semantic Versioning 2.0.0
  6. MSRV Policy: Minimum Supported Rust Version (MSRV) changes require minor version bump

Versioning Policy

Semantic Versioning Interpretation

Paladin follows Semantic Versioning 2.0.0 with the following interpretation:

Major Version (X.0.0)

Breaking changes that require code changes in dependent crates:

  • Removing public types, traits, or functions
  • Removing trait methods (even with default implementations)
  • Changing trait method signatures
  • Changing public struct field types
  • Changing error enum variants
  • Renaming public items
  • Changing function parameter types or return types
  • Making previously public items private

Minor Version (0.X.0)

Backwards-compatible additions:

  • Adding new public types, traits, or functions
  • Adding new trait methods with default implementations
  • Adding new struct fields (with defaults or using builder pattern)
  • Adding new error enum variants (when using #[non_exhaustive])
  • Adding new modules
  • Deprecating APIs (without removing)
  • MSRV (Minimum Supported Rust Version) increases

Patch Version (0.0.X)

Backwards-compatible bug fixes:

  • Bug fixes that don't change public API
  • Documentation improvements
  • Performance optimizations
  • Internal refactoring
  • Dependency updates (when not affecting public API)

Pre-1.0 Versioning

During pre-1.0 development (0.x.y):

  • 0.x.0 (minor bump): May include breaking changes
  • 0.0.x (patch bump): Backwards-compatible changes only
  • Breaking changes will be clearly documented in CHANGELOG.md

Minimum Supported Rust Version (MSRV)

  • Current MSRV: Rust 1.93.1 (stable)
  • MSRV Policy: Increasing MSRV requires a minor version bump
  • Support Window: We support the latest stable Rust release and the previous 2 minor releases

Stability Tiers

All public API items are classified into one of four stability tiers:

🟢 Stable

Definition: Production-ready API with strong backwards compatibility guarantees.

Guarantees:

  • Will not be removed without deprecation period
  • Breaking changes only in major versions
  • Comprehensive documentation with examples
  • Well-tested with >80% coverage

Applies to: All port traits, core domain entities, error types

🟡 Unstable

Definition: API under active development, subject to change.

Warnings:

  • May have breaking changes in minor versions
  • Documentation may be incomplete
  • Not recommended for production use
  • Will eventually move to Stable or be removed

Marked with: #[doc(unstable)] or documented as "Unstable" in rustdoc

🔵 Experimental

Definition: Early-stage API for testing new features.

Warnings:

  • May be removed without deprecation
  • API design may change significantly
  • Requires explicit opt-in via feature flags
  • Not suitable for production

Marked with: Feature-gated (e.g., #[cfg(feature = "experimental")])

🔴 Deprecated

Definition: API scheduled for removal in a future version.

Process:

  • Marked with #[deprecated(since = "x.y.z", note = "use X instead")]
  • Will be removed in next major version
  • Migration path documented in MIGRATION.md
  • Alternative APIs provided

Marked with: #[deprecated] attribute with migration guidance

Tier Progression

Experimental → Unstable → Stable → Deprecated → Removed
                   ↓          ↓
                Removed   (Maintained)

Per-Crate API Surface and Stability

This section documents the public API contract per crate, aligned with the workspace decomposition completed in Milestone 7.

Stability Legend

  • Stable: Backward-compatible under normal semver rules.
  • Unstable: Public but expected to evolve; avoid strict coupling.
  • Experimental: Feature-gated or early-stage APIs, not guaranteed stable.

paladin-core

  • Stable: Domain entities, value objects, and core container/base types.
  • Unstable: None declared.
  • Experimental: Feature-gated additions, if introduced later.

paladin-ports

  • Stable: Input and output port traits used as architectural contracts.
  • Unstable: Traits explicitly documented as in-progress, if any.
  • Experimental: Feature-gated ports only.

paladin-battalion

  • Stable: Battalion orchestration surface (Formation, Phalanx, Campaign, Chain of Command, Conclave, Council, Grove, Maneuver, Commander).
  • Unstable: New orchestration APIs marked as in-progress.
  • Experimental: Feature-gated orchestration behaviors.

paladin-llm

  • Stable: Provider-agnostic request/response contracts and adapter entrypoints.
  • Unstable: Provider-specific extensions pending stabilization.
  • Experimental: Feature-gated or preview provider capabilities.

paladin-memory

  • Stable: Garrison and Sanctum public service/adapter contracts.
  • Unstable: New retrieval and extraction options under evaluation.
  • Experimental: Feature-gated memory backends or indexing variants.

paladin-web

  • Stable: Public web adapter integration surface used by the facade/composition root.
  • Unstable: Handler contracts in active iteration.
  • Experimental: Feature-gated web extensions.

paladin-notifications

  • Stable: Notification adapter contracts and channel abstractions.
  • Unstable: Provider-specific channel enhancements.
  • Experimental: New feature-gated notification channels.

paladin-content

  • Stable: Content adapter and use-case service entrypoints.
  • Unstable: Rapidly iterating analysis and ingestion specializations.
  • Experimental: Feature-gated parsing and enrichment capabilities.

paladin-storage

  • Stable: Repository adapter contracts and storage entrypoints.
  • Unstable: Backend-specific tuning hooks and migration internals.
  • Experimental: Feature-gated storage backends.

paladin (facade crate)

The facade crate is the application assembly point and composition root. It wires leaf crates together into a runnable application via ServiceRunner. It does not contain business logic, port trait definitions, or infrastructure adapter implementations — those live exclusively in the leaf crates.

Module layout (post-Milestone 8):

  • application/services/ — Application coordination services (11 sub-modules)
  • application/cli/ — CLI command implementations (feature-gated: cli)
  • config/ — Multi-source configuration loading and settings types
  • infrastructure/ — Infrastructure adapter implementations not yet extracted to a leaf crate
  • core/ — Minimal re-export bridge to paladin-core
  • bin/paladin-cli.rs — CLI binary entry point (feature-gated: cli)
  • main.rs — Default binary entry point

Stability tiers:

  • Stable: Curated top-level re-exports and extension points listed in this stable API document.
  • Unstable: Convenience exports marked as transitional.
  • Experimental: Feature-gated facade exports.

Cross-Crate Dependency Contract

The public dependency chain is intentionally layered:

  1. paladin-core (domain foundation)
  2. paladin-ports (contracts on top of core)
  3. leaf crates (paladin-battalion, paladin-llm, paladin-memory, paladin-web, paladin-notifications, paladin-content, paladin-storage)
  4. paladin facade (curated re-exports)

Breaking changes to lower layers can cascade upward. Therefore, compatibility reviews must start at paladin-core and paladin-ports before assessing leaf crate or facade impacts.


Stable Public API Catalog

Tracking API Changes

Automated Tracking with cargo-public-api

We use cargo-public-api to track changes to the public API surface:

Generate Current API Surface

./scripts/extract-public-api.sh project/current-exports.txt

This creates a baseline snapshot of all public items (16,471+ items as of v0.1.0).

Check for API Changes (CI)

./scripts/check-api-surface.sh project/current-exports.txt

Compares current API against baseline. Fails CI if changes detected without baseline update.

Check Deprecation Warnings

./scripts/check-deprecations.sh

Verifies that deprecated items compile with warnings.

CI Integration

API surface changes are automatically detected in CI (.github/workflows/ci.yml):

- name: Check API Surface
  run: ./scripts/check-api-surface.sh project/current-exports.txt

If the API changes:

  1. CI build will fail with diff showing changes
  2. Review changes carefully for breaking changes
  3. Update CHANGELOG.md with details
  4. Update baseline: ./scripts/extract-public-api.sh project/current-exports.txt
  5. Increment version per semver

Manual API Verification

# View current public API
cargo public-api --simplified | less

# Compare against previous version
cargo public-api --diff-git-checkouts v0.1.0 v0.2.0

# Generate HTML diff
cargo public-api --diff-git-checkouts v0.1.0 v0.2.0 --output-format markdown

Frequently Asked Questions

General

Q: What is considered a "breaking change"?

A: Any change that would cause existing code to fail compilation or change behavior:

  • Removing public types, traits, or functions
  • Removing trait methods
  • Changing method signatures (parameters, return types)
  • Renaming public items
  • Changing struct field types
  • Making previously public items private
  • Removing error enum variants (without #[non_exhaustive])

See Versioning Policy for complete list.

Q: Can I depend on adapter implementations (e.g., OpenAIAdapter)?

A: Not recommended for library code. Adapters are internal implementation details that may change in minor versions. Use port traits (LlmPort, etc.) instead. Adapters are fine in application code and examples.

Q: How long are deprecated APIs supported?

A: Deprecated APIs remain functional for at least one minor version (e.g., deprecated in 0.2.0, removed in 0.3.0 or 1.0.0). We aim to provide at least 3 months of deprecation period for major APIs.

Q: What's the timeline for 1.0.0?

A: We'll release 1.0.0 when:

  1. All major features are implemented and stable
  2. API design has proven stable in production use
  3. Documentation is comprehensive
  4. At least 6 months of pre-1.0 usage in real projects

Expected: Q3-Q4 2026.

Port Traits

Q: Can I add methods to existing port traits?

A: Yes, if the method has a default implementation. This is backwards-compatible. Methods without defaults are breaking changes.

Q: Can I implement port traits for my own types?

A: Yes! Port traits are designed for user implementation. Implement LlmPort for your custom LLM provider, GarrisonPort for your storage system, etc.

Q: Do port traits require specific async runtimes?

A: Port traits are runtime-agnostic. The default implementations use Tokio, but you can implement ports for any async runtime.

Error Handling

Q: Can I add new variants to error enums?

A: Yes, all error enums are marked #[non_exhaustive], allowing new variants in minor versions. Always use a wildcard match:

#![allow(unused)]
fn main() {
match error {
    PaladinError::ConfigurationError(_) => { /* ... */ },
    PaladinError::Timeout(_) => { /* ... */ },
    _ => { /* catch-all for future variants */ },
}
}

Q: Are error messages part of the stable API?

A: No. Error messages may change in any version. Don't parse error strings—use enum variants instead.

Versioning

Q: What does "0.x.0" mean before 1.0?

A: During pre-1.0:

  • 0.x.0 (minor bump): May include breaking changes
  • 0.0.x (patch bump): Backwards-compatible changes only

Breaking changes in 0.x versions will be clearly documented.

Q: When will you increase MSRV (Minimum Supported Rust Version)?

A: MSRV increases require a minor version bump. We target the latest stable Rust and the previous 2 minor releases. Current MSRV: Rust 1.93.1.

Migration

Q: Where do I find migration guides?

A:

  • CHANGELOG.md: List of all breaking changes by version
  • docs/MIGRATION.md: Step-by-step upgrade guides
  • GitHub Releases: Migration highlights in release notes
  • Rustdoc: Deprecated item documentation includes alternatives

Q: Can I use both old and new APIs during migration?

A: Yes. During the deprecation period, both old and new APIs coexist. This allows gradual migration.

Contributing

Q: How do I propose an API change?

A: See API Change Process above. Start by opening a GitHub issue with the api-change label.

Q: Can I contribute new port traits?

A: Yes! Propose new ports via GitHub issue. New stable ports require:

  • Clear use case and motivation
  • Comprehensive rustdoc with examples
  • At least one concrete implementation
  • Tests and doc tests

Stable Public API Surface

Port Traits (Output Ports)

Port traits are the primary stable API and define extension points for integrating external systems. All output ports are located in src/application/ports/output/.

TypeFully Qualified PathTierDescriptionDocumentation
LlmPortpaladin_ports::output::llm_port::LlmPort🟢 StableLLM provider abstraction (OpenAI, DeepSeek, Anthropic)Docs
GarrisonPortpaladin_ports::output::garrison_port::GarrisonPort🟢 StableShort-term conversation memory storageDocs
LongTermGarrisonPortpaladin_ports::output::garrison_port::LongTermGarrisonPort🟢 StableLong-term memory with semantic searchDocs
SanctumPortpaladin_ports::output::sanctum_port::SanctumPort🟢 StableVector storage and similarity searchDocs
EmbeddingPortpaladin_ports::output::embedding_port::EmbeddingPort🟢 StableText-to-vector embedding generationDocs
ArsenalPortpaladin_ports::output::arsenal_port::ArsenalPort🟢 StableExternal tool execution via MCPDocs
ArsenalRegistrypaladin_ports::output::arsenal_port::ArsenalRegistry🟢 StableTool discovery and registrationDocs
CitadelPortpaladin_ports::output::citadel_port::CitadelPort🟢 StableState persistence and recoveryDocs
QueuePortpaladin_ports::output::queue_port::QueuePort🟢 StableAsync task queue and job processingDocs
NotificationDeliveryPortpaladin_ports::output::notification_port::NotificationDeliveryPort🟢 StableMulti-channel notification deliveryDocs
NotificationTemplatePortpaladin_ports::output::notification_port::NotificationTemplatePort🟢 StableNotification template managementDocs
FileStoragePortpaladin_ports::output::file_storage_port::FileStoragePort🟢 StableCloud and local file storageDocs
PaladinPortpaladin_ports::output::paladin_port::PaladinPort🟢 StableAI agent execution abstractionDocs
BattalionPortpaladin_ports::output::battalion_port::BattalionPort🟢 StableMulti-agent orchestrationDocs

Port Traits (Input Ports)

Input ports define use case interfaces for application entry points. Located in src/application/ports/input/.

TypeFully Qualified PathTierDescriptionDocumentation
ContentIngestionPortpaladin_ports::input::content_input_port::ContentIngestionPort🟡 UnstableContent ingestion use casesDocs
DocumentPortpaladin_ports::input::document_port::DocumentPort🟢 StableDocument processing use casesDocs
MlPortpaladin_ports::input::ml_port::MlPort🟡 UnstableMachine learning use casesDocs

Domain Entities

Core business domain types that represent the framework's entities. Located in src/core/platform/container/.

Paladin (Agent) Types

TypeFully Qualified PathTierDescriptionDocumentation
Paladinpaladin::core::platform::container::paladin::Paladin🟢 StableAutonomous AI agent entity (Node)Docs
PaladinDatapaladin::core::platform::container::paladin::PaladinData🟢 StablePaladin configuration and state dataDocs
PaladinConfigpaladin::core::platform::container::paladin::PaladinConfig🟢 StableRuntime execution configurationDocs
PaladinStatuspaladin::core::platform::container::paladin::PaladinStatus🟢 StableAgent execution status enumDocs
PaladinResultpaladin_ports::output::paladin_port::PaladinResult🟢 StableAgent execution result with metadataDocs
StopReasonpaladin_ports::output::paladin_port::StopReason🟢 StableWhy agent execution terminatedDocs

Battalion (Multi-Agent) Types

TypeFully Qualified PathTierDescriptionDocumentation
Battalionpaladin::core::platform::container::battalion::Battalion🟢 StableMulti-agent coordination entityDocs
BattalionDatapaladin::core::platform::container::battalion::BattalionData🟢 StableBattalion configuration and stateDocs
BattalionResultpaladin::core::platform::container::battalion::BattalionResult🟢 StableOrchestration execution resultDocs
BattalionStatuspaladin::core::platform::container::battalion::BattalionStatus🟢 StableOrchestration status enumDocs
Formationpaladin::core::platform::container::battalion::formation::Formation🟢 StableSequential execution patternDocs
Phalanxpaladin::core::platform::container::battalion::phalanx::Phalanx🟢 StableParallel execution patternDocs
Campaignpaladin::core::platform::container::battalion::campaign::Campaign🟢 StableGraph/DAG execution patternDocs
ChainOfCommandpaladin::core::platform::container::battalion::chain_of_command::ChainOfCommand🟢 StableHierarchical delegation patternDocs

Memory (Garrison) Types

TypeFully Qualified PathTierDescriptionDocumentation
Garrisonpaladin::core::platform::container::garrison::Garrison🟢 StableMemory storage entityDocs
Memorypaladin::core::platform::container::garrison::Memory🟢 StableIndividual memory recordDocs
GarrisonStatspaladin_ports::output::garrison_port::GarrisonStats🟢 StableMemory storage statisticsDocs

Tool (Arsenal) Types

TypeFully Qualified PathTierDescriptionDocumentation
Arsenalpaladin::core::platform::container::arsenal::Arsenal🟢 StableTool registry entityDocs
Armamentpaladin::core::platform::container::arsenal::Armament🟢 StableIndividual tool/capability metadataDocs
ArmamentCallpaladin::core::platform::container::arsenal::ArmamentCall🟢 StableTool invocation requestDocs
ArmamentResultpaladin::core::platform::container::arsenal::ArmamentResult🟢 StableTool execution resultDocs

Builder Types

Fluent builder patterns for complex object construction. Located in src/application/services/.

TypeFully Qualified PathTierDescriptionDocumentation
PaladinBuilderpaladin::application::services::paladin::PaladinBuilder🟢 StableFluent builder for Paladin agentsDocs
CommanderBuilderpaladin::application::services::commander::CommanderBuilder🟢 StableFluent builder for Commander routersDocs
CouncilBuilderpaladin::application::services::council::CouncilBuilder🟢 StableFluent builder for Council discussionsDocs
GroveBuilderpaladin::application::services::grove::GroveBuilder🟢 StableFluent builder for Grove routingDocs

Configuration Types

Application and service configuration types. Located in src/config/.

TypeFully Qualified PathTierDescriptionDocumentation
ApplicationSettingspaladin::config::application_settings::ApplicationSettings🟢 StableApplication-wide configurationDocs
LlmConfigpaladin::config::application_settings::LlmConfig🟢 StableLLM provider configurationDocs
ServerConfigpaladin::config::application_settings::ServerConfig🟢 StableHTTP server configurationDocs
DatabaseConfigpaladin::config::application_settings::DatabaseConfig🟢 StableDatabase connection configurationDocs

Error Types

All error enums follow thiserror patterns for consistent error handling. Located throughout the codebase.

TypeFully Qualified PathTierDescriptionDocumentation
PaladinErrorpaladin::application::services::paladin::error::PaladinError🟢 StablePaladin execution errorsDocs
BattalionErrorpaladin::core::platform::container::battalion::BattalionError🟢 StableBattalion orchestration errorsDocs
GarrisonErrorpaladin_ports::output::garrison_port::GarrisonError🟢 StableMemory storage errorsDocs
ArsenalErrorpaladin::core::platform::container::arsenal::ArsenalError🟢 StableTool execution errorsDocs
CitadelErrorpaladin::application::errors::citadel_error::CitadelError🟢 StableState persistence errorsDocs
LlmErrorpaladin_ports::output::llm_port::LlmError🟢 StableLLM provider errorsDocs
EmbeddingErrorpaladin_ports::output::embedding_port::EmbeddingError🟢 StableEmbedding generation errorsDocs
SanctumErrorpaladin_ports::output::sanctum_port::SanctumError🟢 StableVector storage errorsDocs
FileStorageErrorpaladin_ports::output::file_storage_port::FileStorageError🟢 StableFile storage errorsDocs
NotificationPortErrorpaladin_ports::output::notification_port::NotificationPortError🟢 StableNotification delivery errorsDocs
ConfigErrorpaladin::config::error::ConfigError🟢 StableConfiguration loading errorsDocs

Base Types

Generic framework primitives and patterns. Located in src/core/base/.

TypeFully Qualified PathTierDescriptionDocumentation
Node<T>paladin::core::base::entity::node::Node🟢 StableGeneric entity wrapper with UUID and metadataDocs
Collection<T>paladin::core::base::entity::collection::Collection🟢 StableGeneric collection type with metadataDocs
Fieldpaladin::core::base::entity::field::Field🟢 StableField definition with type informationDocs
Message<T>paladin::core::base::entity::message::Message🟢 StableGeneric message wrapper for eventsDocs

Resilience Types

Fault-tolerance primitives for hardening agent execution. Located in src/infrastructure/resilience/.

Canonical path change (Milestone 6, Epic 4): CircuitBreaker and CircuitState were relocated from paladin::application::services::paladin::circuit_breaker to paladin::infrastructure::resilience::circuit_breaker. The old path is retired and no longer resolves.

TypeFully Qualified PathTierDescriptionDocumentation
CircuitBreakerpaladin::infrastructure::resilience::circuit_breaker::CircuitBreaker🟢 StableThread-safe circuit breaker for fault toleranceDocs
CircuitStatepaladin::infrastructure::resilience::circuit_breaker::CircuitState🟢 StableCircuit breaker state (Closed, Open, HalfOpen)Docs

Internal Implementation Details (Not Stable)

The following are internal implementation details and NOT part of the stable public API. These may change without notice in minor versions.

Adapters (Infrastructure Layer)

All concrete adapter implementations in src/infrastructure/adapters/ are internal:

LLM Adapters:

  • OpenAIAdapter, DeepSeekAdapter, AnthropicAdapter → Use LlmPort trait instead
  • OpenAIEmbeddingAdapter → Use EmbeddingPort trait instead

Storage Adapters:

  • InMemoryGarrison, SqliteGarrison → Use GarrisonPort trait instead
  • QdrantSanctum, InMemorySanctum → Use SanctumPort trait instead
  • FileCitadel → Use CitadelPort trait instead

Queue Adapters:

  • RedisQueue, InMemoryQueue → Use QueuePort trait instead

File Storage Adapters:

  • MinIOAdapter, LocalFileAdapter → Use FileStoragePort trait instead

Arsenal Adapters:

  • MCPStdioAdapter, MCPSseAdapter → Use ArsenalPort trait instead

Why Internal? Adapter implementations are infrastructure concerns. Library users should depend on port traits to remain decoupled from specific technologies.

Migration Path: Replace direct adapter usage with port traits in library code. Adapters are acceptable in application code and examples.

Repositories (Data Access Layer)

All repository implementations in src/infrastructure/repositories/ are internal:

  • MySQL repositories (src/infrastructure/repositories/mysql/)
  • SQLite repositories (src/infrastructure/repositories/sqlite/)

Why Internal? Repositories are data access implementation details hidden behind port traits or use case services.

Managers (Service Coordinators)

Internal service managers in src/core/manager/ are not public API:

  • Scheduler - Task scheduling coordinator
  • QueueService - Queue management service
  • EventManager - Event distribution service

Why Internal? Managers are internal service coordinators. Use port traits or use case services instead.

CLI (Binary Interface)

All CLI-related modules in src/application/cli/ are internal to the binary and not exposed as library API.

Why Internal? CLI is a binary-specific interface, not meant for library consumption.

Web Server (HTTP Interface)

All web server modules in src/infrastructure/web/ are internal to the binary.

Why Internal? Web server is a binary-specific deployment concern.


API Change Process

This section defines the process for proposing, reviewing, and implementing changes to the stable public API.

Step 1: Proposal

  1. Open GitHub Issue with the api-change label
  2. Template Required (use .github/ISSUE_TEMPLATE/api-change.md)
  3. Include:
    • Type: Addition / Breaking Change / Deprecation / Clarification
    • Motivation: Why is this change needed?
    • Impact: What code will break?
    • Alternatives: What other approaches were considered?
    • Migration: How will users migrate?

Step 2: Discussion

  1. Community Review Period: Minimum 7 days for breaking changes
  2. Maintainer Approval: At least one maintainer must approve
  3. RFC Process: Major breaking changes may require an RFC document

Step 3: Implementation

  1. Branch Creation: Create feature branch from main
  2. Code Changes:
    • Implement the proposed change
    • Update rustdoc for all affected items
    • Add examples demonstrating new usage
  3. API Baseline Update:
    ./scripts/extract-public-api.sh project/current-exports.txt
    git add project/current-exports.txt
    
  4. Documentation Updates:
    • Update STABLE_API.md (this file)
    • Update CHANGELOG.md with entry
    • Update MIGRATION.md if breaking change
  5. Tests:
    • All existing tests must pass
    • Add tests for new functionality
    • Doc tests must compile and pass

Step 4: Review

  1. Pull Request with completed checklist
  2. CI Verification: All checks must pass
  3. Code Review: At least one approval from maintainer
  4. API Diff Review: Carefully review cargo-public-api diff

Step 5: Merge and Release

  1. Merge to main after approval
  2. Version Bump according to semver
  3. Publish to crates.io
  4. Release Notes on GitHub

API Change Checklist

  • GitHub issue created with api-change label
  • Community discussion period completed (7+ days for breaking)
  • Maintainer approval obtained
  • Implementation complete with rustdoc
  • Examples added/updated
  • API baseline regenerated (extract-public-api.sh)
  • STABLE_API.md updated (this file)
  • CHANGELOG.md entry added
  • MIGRATION.md updated (if breaking)
  • All tests passing (unit, integration, doc)
  • CI checks passing (including API surface verification)
  • Pull request reviewed and approved
  • Version bumped per semver
  • Published to crates.io
  • Release notes created on GitHub

Migration Guide for Breaking Changes

When we make breaking changes in a major version bump, we will:

Deprecation Lifecycle

  1. Announcement (Version N):

    • Add #[deprecated(since = "N", note = "use X instead")] attribute
    • Update rustdoc with migration guidance
    • Add entry to CHANGELOG.md
    • Update MIGRATION.md with examples
  2. Support Period (Version N through N+1):

    • Deprecated API remains functional
    • Compiler warnings guide users to alternatives
    • Documentation shows both old and new approaches
  3. Removal (Version N+2):

    • Deprecated API removed in next major version
    • CHANGELOG.md documents removal
    • MIGRATION.md provides upgrade path

Deprecation Example

#![allow(unused)]
fn main() {
// Version 0.1.0 - Original API
pub fn execute_paladin(paladin: &Paladin) -> Result<String, Error> {
    // ...
}

// Version 0.2.0 - Add new API, deprecate old
#[deprecated(since = "0.2.0", note = "use `PaladinPort::execute()` instead")]
pub fn execute_paladin(paladin: &Paladin) -> Result<String, Error> {
    // Old implementation still works
}

pub trait PaladinPort {
    fn execute(&self, paladin: &Paladin) -> Result<PaladinResult, PaladinError>;
}

// Version 1.0.0 - Remove deprecated API
// execute_paladin() function no longer exists
// Users must use PaladinPort::execute()
}

Migration Resources

  • MIGRATION.md: Step-by-step upgrade guides for each major version
  • CHANGELOG.md: Detailed list of breaking changes
  • Release Notes: Migration highlights on GitHub releases
  • Examples: Updated examples in examples/ directory
  • Documentation: Rustdoc updated with new patterns

Compatibility Shims

When possible, we provide compatibility shims during the deprecation period:

#![allow(unused)]
fn main() {
// Compatibility shim example
#[deprecated(since = "0.2.0", note = "use PaladinBuilder instead")]
pub fn create_paladin(name: &str, model: &str) -> Paladin {
    PaladinBuilder::new()
        .name(name)
        .model(model)
        .build()
        .expect("Failed to build Paladin")
}
}

Version Upgrade Paths

  • 0.1.x → 0.2.x: TBD (no breaking changes yet)
  • 0.x.y → 1.0.0: Will be documented before 1.0.0 release

Questions and Support

For questions about API stability:

GitHub Issues

  • API Questions: Open issue with question label
  • API Change Proposals: Use api-change label
  • Bug Reports: Use bug label
  • Feature Requests: Use enhancement label

Discussion Forums

Maintainers

  • Primary Maintainer: @DF3NDR
  • Response Time: Typically within 48 hours for critical issues

Last Updated: 2026-04-16 Document Version: 1.1 Paladin Version: 0.1.0 Maintainers: @DF3NDR


Versioning Policy

Purpose

This document defines how Paladin versions its workspace crates and what constitutes a breaking change.

Initial Versioning Strategy

Paladin uses lockstep versioning for the initial release line.

  • Scope: all public crates in this workspace.
  • Current baseline: 0.1.0.
  • Milestone 7 target: 0.2.0 lockstep for publishable crates.
  • Rule: a single release version is applied to all public crates in the same release cycle.

Public crates:

  • paladin
  • paladin-core
  • paladin-ports
  • paladin-battalion
  • paladin-llm
  • paladin-memory
  • paladin-web
  • paladin-notifications
  • paladin-content
  • paladin-storage

Breaking Change Policy

Breaking changes require a coordinated lockstep release increment.

Examples of breaking changes:

  • Removing or renaming a public type, trait, function, enum variant, or module path.
  • Changing function signatures in a way that breaks callers.
  • Changing trait method signatures or required methods.
  • Changing feature flag semantics in a way that breaks existing consumers.
  • Tightening configuration requirements without backward-compatible defaults.

Non-breaking changes:

  • Additive APIs (new types, functions, optional feature flags).
  • Internal refactoring that preserves public API behavior and signatures.
  • Documentation-only improvements.

Crate-Family Guidance

  • paladin-core: domain model compatibility is high impact; treat model shape changes as potentially breaking.
  • paladin-ports: trait contracts are compatibility-critical; changes are usually breaking.
  • paladin-battalion: orchestration runtime APIs and strategy entrypoints should remain stable.
  • paladin-llm: provider additions are additive; request/response contract changes may be breaking.
  • paladin-memory: storage adapter behavior and query API changes may be breaking.
  • paladin-web: externally consumed handler/middleware APIs should preserve compatibility.
  • paladin-notifications: adapter trait behavior and config contracts should remain stable.
  • paladin-content: use-case and adapter public APIs should preserve call signatures.
  • paladin-storage: repository and migration public APIs should preserve compatibility.
  • paladin facade: re-export paths and top-level developer ergonomics are compatibility-critical.

Transition Criteria for Independent Versioning

Paladin may transition from lockstep to independent crate versioning after all criteria below are met:

  • Stable dependency graph with low cross-crate churn across at least 2-3 release cycles.
  • Per-crate changelog discipline is consistently maintained.
  • Public API stability tiers are fully documented and regularly reviewed.
  • CI pipeline supports dependency-aware, per-crate release automation.
  • Release owners agree that independent cadence adds value without excessive coordination cost.

Until then, lockstep versioning remains the default policy.

Dependency-Aware Publish Order

Use dependency-first publishing in this order:

  1. paladin-core
  2. paladin-ports
  3. Leaf crates (paladin-battalion, paladin-llm, paladin-memory, paladin-web, paladin-notifications, paladin-content, paladin-storage)
  4. paladin facade crate

This order is required because dry-run and publish validation for dependent crates requires published upstream dependencies.