Philosophy / Boundary Map

Know Where to Be Rigid, Know Where to Be Flexible

Understanding the boundary between "core" (opinionated) and "edges" (flexible) is crucial for effective Ranvier usage.

Core Territory (Opinionated — Must Use Ranvier Paradigm)

These must use Transition/Outcome/Bus/Schematic:

Business logic: Use `#[transition]` for visualization, composition, testability
Data flow: Return `Outcome<T, E>` for type-safe error propagation
State sharing: Store in `Bus` for explicit dependencies
Pipeline composition: Use `Axon::pipe()`, `.parallel()` for Schematic graph generation
Domain errors: Define custom error enums for clear failure modes

Edge Territory (Flexible — Use Any Rust Tool)

These can use any Rust library or pattern:

HTTP server: Hyper, Tower, Axum, actix-web, warp
Database: sqlx, diesel, sea-orm, mongodb, postgres
Caching: redis, memcached, moka, dashmap
Serialization: serde_json, bincode, msgpack, protobuf
Metrics: prometheus, opentelemetry, statsd
Tracing: tracing, log, slog, env_logger
Async runtime: tokio, async-std, smol (Ranvier is runtime-agnostic)

Gray Zones (Context-Dependent)

Some domains can go either way. Choose based on your needs:

Middleware / Guards

Transition-based: Schematic visualization, testable, composable → New projects
Tower middleware: Ecosystem reuse, team knowledge → Existing Tower apps

Error Handling

Inside Transitions: Always `Outcome` (required by #[transition])
Outside Transitions: `Result` is fine, convert at boundary

State Management

Request-scoped data (auth, tenant): Bus (visualized in Schematic)
Global shared resources (DB pool, config): Framework state or Arc
Rule of thumb:
• Core (business logic, data flow, composition) → Ranvier paradigm
• Edges (infrastructure, I/O, deployment) → Any Rust tool
• Gray zones → Choose based on: visualization needs, team knowledge, migration path
For detailed boundary rules and anti-patterns, see PHILOSOPHY.md — Boundary Map