arcature 2026.2.1

Arcature application framework: a high-level Application facade over the certified Arcature subsystems, with the low-level Axum/Tower escape hatch preserved.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
//! Arcature — one full-stack web framework over the certified Rust ecosystem.
//!
//! Arcature is a high-level application framework that composes the certified
//! Arcature subsystem crates (Inertia, database, auth, cache, storage, mail,
//! jobs, pages, observability, API) behind a single facade, while preserving a
//! guaranteed escape hatch down to the raw Axum/Tower/Tokio ecosystem
//! underneath.
//!
//! # Getting started
//!
//! A normal application depends on the `arcature` crate with the capabilities
//! it needs, and drives the framework through [`Application`]. The simplest
//! stateless app — compiles with no features beyond the kernel:
//!
//! ```no_run
//! use arcature::prelude::*;
//!
//! async fn hello() -> &'static str {
//!     "hello"
//! }
//!
//! # // `serve` is generic over `axum::serve::Listener`; an expert user brings
//! # // their own runtime. The `macros` feature's `run()` helper binds a
//! # // TcpListener for the common case (shown in the ignore block below).
//! ```
//!
//! With the `macros` feature, `#[arcature::main]` and `Application::run()`
//! remove the need for a direct `tokio` dependency:
//!
//! ```ignore
//! use arcature::prelude::*;
//!
//! async fn hello() -> &'static str {
//!     "hello"
//! }
//!
//! #[arcature::main]
//! async fn main() -> Result<()> {
//!     Application::new()
//!         .routes(Routes::new().route("/", get(hello)))
//!         .run()
//!         .await
//! }
//! ```
//!
//! `Application` is the high-level composition root: it owns framework
//! lifecycle, request-pipeline assembly, and subsystem coordination. It sits
//! *above* the low-level [`App`] kernel, which remains the raw Axum-compatible
//! seam for expert use.
//!
//! # The two layers
//!
//! ```text
//! Application   — high-level framework facade (lifecycle, composition)
//!     |
//! App<S>        — low-level HTTP kernel (raw Axum/Tower interop)
//!     |
//! Axum / Tower  — the upstream ecosystem
//! ```
//!
//! - **[`Application`]** — the normal user entry point. Owns routing
//!   assembly, the request pipeline (pre-routing proxy, post-routing
//!   middleware, fallback pages), and — when subsystem features are enabled —
//!   deterministic startup and graceful shutdown of database, cache, storage,
//!   mail, jobs, and observability.
//! - **[`App`]** — the low-level HTTP kernel. A thin wrapper over
//!   [`axum::Router`] that forwards to `axum::serve`. Use it directly when you
//!   want raw Axum/Tower with no framework opinions.
//!
//! # Features
//!
//! The facade re-exports each certified subsystem behind a Cargo feature, so a
//! minimal application pulls no heavyweight runtime:
//!
//! ```toml
//! [dependencies]
//! arcature = { version = "2026.1.0", features = ["inertia", "db", "pages", "observe"] }
//! ```
//!
//! `default = []` keeps the bare HTTP kernel. `fullstack` enables every runtime
//! subsystem (but never auto-connects to a service — features are compile-time
//! capabilities, not runtime permission). See the crate `Cargo.toml` for the
//! full feature graph.
//!
//! # Advanced: the raw escape hatch
//!
//! Arcature hides complexity without hiding capability. Expert code can still
//! reach Axum, Tower, and every subsystem crate directly:
//!
//! ```no_run
//! use arcature::App;
//! use arcature::axum::routing::get;
//! use arcature::axum::Router;
//!
//! async fn hello() -> &'static str { "hello" }
//!
//! // Build a raw Axum router, wrap it in the kernel, serve it.
//! # #[tokio::main] async fn main() -> std::io::Result<()> {
//! let router: Router = Router::new().route("/", get(hello));
//! # let _ = router;
//! # Ok(()) }
//! ```
//!
//! [`axum::Router`] is re-exported as [`axum`] so downstream code targets the
//! certified version through Arcature. Use [`App::into_router`] /
//! [`App::from_router`] to move between the kernel and a raw router.
//!
//! [Axum]: https://docs.rs/axum

#![forbid(unsafe_code)]
#![doc(html_root_url = "https://docs.rs/arcature")]

// Re-export the certified `axum` crate so downstream code uses the escape
// hatch through Arcature's pinned dependency (e.g. `arcature::axum::routing`).
pub use axum;

/// The Arcature engine (facade) crate version in YBF form (`YEAR.BREAK.FIX`).
///
/// Recorded into the Unified Application Graph manifest by `arcature-build`
/// so frontend tooling and the `@arcature/client` package can negotiate
/// cross-stack compatibility (ADR-0006 §2). This is the version of the
/// engine facade the application was compiled against — the platform
/// coordinate consumers compare against, distinct from any individual
/// subsystem crate version. Always available (a compile-time string; no
/// feature dependency).
pub const FRAMEWORK_VERSION: &str = env!("CARGO_PKG_VERSION");

// Low-level HTTP kernel (Phase 1) — the raw Axum/Tower seam.
mod app;
mod server;

// High-level Application engine (engine phase) — the composition root.
mod application;
mod facade;
// AP2.1-10: the production health endpoints (`/up/live`, `/up/ready`). A
// public module so an expert user can mount the router on a raw Axum app
// (standalone-first, §16); the orchestrated paths
// (`Application::serve_with_health` / `run_with_health`) merge it into the
// application routes. The handlers read the `Lifecycle` from an Axum
// `Extension`, so the health router composes with any application state.
pub mod health;

// AP2.1-10: the application binary-subcommand dispatch library. A public
// module so a generated app's `main` calls `arcature::cli::run(operations)`
// (the macros-gated runtime wrapper) — the templates (AP2.1-S) wire this in.
// The `Subcommand` enum, `parse`, `Operations` trait, and `dispatch` are
// pure `std` (no feature flags); `run` is `macros`-gated (certified Tokio
// runtime). See `docs/ap2-1/PROGRAM.md` AP2.1-10.
pub mod cli;
mod pipeline;
pub mod proxy;
mod routing;

// AP2.1-3: the one-TCP-port development proxy. Behind the `dev-proxy`
// feature — engine plumbing, not an application API (AGENTS.md §22). The
// module is `pub(crate)`; its layer is installed by the pipeline assembler
// when `ARCATURE_VITE_IPC` is set. See `dev_proxy::service` for the
// forwarding contract and the AP2.1-3 security review.
#[cfg(feature = "dev-proxy")]
mod dev_proxy;

// AP2.1-8: realtime WebSocket + SSE wrappers (PROGRAM.md §AP2.1-8,
// ADR-0006 §36). Behind the `realtime` feature — a typed safety core over
// `axum::extract::ws` and `axum::response::sse` (the `ws` axum feature is
// enabled at the workspace line). Raw `axum::extract::ws` / `axum::sse`
// remain first-class escape hatches (AGENTS.md §16). The module is public
// so applications reach it as `arcature::realtime`; the crate root
// re-exports the primary surface below.
#[cfg(feature = "realtime")]
pub mod realtime;

// A1: the DX layer runtime contracts (DxComponent trait) and the
// `arcature-dx` proc-macro re-exports. Gated behind the `dx` feature so
// applications opt in to the application programming model. The module is
// private; its public items are re-exported at the crate root below.
#[cfg(feature = "dx")]
mod dx;

// AP2.1-7: the system-check framework (Django-inspired self-diagnostics).
// A public module so the application and the framework contribute `&'static`
// `SystemCheck` slices and `arc doctor --checks` (and the MCP `system_checks`
// tool, later) aggregate them via `system_check::run`. The trait and the
// non-serializable shapes are always available; the JSON views are behind
// `serde`. No global mutable state, no `inventory`/`linkme` (AGENTS.md §20).
pub mod system_check;

// AP2.1-7: request-owned typed memoization (per-request `RequestCache`).
// A public module behind the `request-cache` feature so applications opt in.
// Request-owned (NOT a thread/task-local/global — AGENTS.md §20): the Axum
// extractor lazily constructs one cache per request and shares it across
// extractions via request extensions. Composes with `Current<User>` etc. with
// no macro-hardcoded type list (ADR-0004).
#[cfg(feature = "request-cache")]
pub mod request_cache;

// The curated prelude is a public module so applications write
// `use arcature::prelude::*;` (engine spec §19).
pub mod prelude;

pub use app::App;
pub use application::Application;
pub use application::ApplicationBuilder;
pub use application::EngineError;
pub use application::ProxyFn;
pub use application::Result;
// AP2.1-10: the production lifecycle handle and state machine. Always
// available (pure `std`); `termination_signal` and the orchestrated
// `serve_with_health` / `run_with_health` paths are `macros`-gated (they
// need the certified Tokio runtime + signal sub-feature).
pub use application::lifecycle::{
    DrainError, DrainHook, Lifecycle, LifecycleState, ReadinessCheck,
};
// `arcature::run()` — the zero-plumbing bootstrap factory (AP2.1-2).
// Returns a fresh `ApplicationBuilder<()>` with the default bind address
// and the `ARCATURE_BACKEND_PORT` env override applied; the application
// then adds its routes/subsystems/state closure and calls
// `.build().run_with_lifecycle(state_fn).await`. Additive: callers may
// still use `Application::new()` for full control.
#[cfg(feature = "macros")]
pub use application::run;
// `Resources` is the typed handle bundle passed to the `state_fn` closure of
// `run_with_lifecycle` / `serve_with_lifecycle`. It is re-exported at the
// crate root so application code can name the type (e.g. in helper function
// signatures). Only available when the `macros` feature + at least one
// lifecycle subsystem is enabled.
#[cfg(all(
    feature = "macros",
    any(
        feature = "db",
        feature = "cache",
        feature = "storage",
        feature = "mail",
        feature = "jobs"
    )
))]
#[allow(unused_imports)]
pub use application::Resources;
pub use routing::Routes;
// Re-export the Axum method-routing constructors at the crate root so the
// `routes!` macro expansion can reference them via `::arcature::get`, etc.
// This is the same certified upstream function, forwarded verbatim.
pub use routing::{any, delete, get, head, options, patch, post, put};
// Re-export `from_fn` at the crate root so the `routes!` macro's middleware
// expansion (`::arcature::from_fn(mw)`) resolves. Also useful for
// applications that wire `from_fn` middleware directly.
pub use routing::from_fn;
// Re-export axum's `Redirect` response type at the crate root so the
// `redirect!` macro expansion can reference it via `::arcature::Redirect`.
pub use axum::response::Redirect;

// Facade modules — namespaced re-exports of the certified subsystem crates.
// `facade` is private; its `pub mod` children are re-exported at the crate
// root so a normal application reaches them as `arcature::inertia`,
// `arcature::db`, etc. Each re-export is feature-gated so only enabled
// subsystems appear on the public surface, and no `pub use` fires under
// `--no-default-features` (engine spec §18/§34/§55). Explicit per-feature
// re-exports (rather than a glob) keep the public surface auditable.
#[cfg(feature = "api")]
pub use facade::api;
#[cfg(feature = "auth")]
pub use facade::auth;
#[cfg(feature = "cache")]
pub use facade::cache;
#[cfg(feature = "db")]
pub use facade::db;
#[cfg(feature = "inertia")]
pub use facade::inertia;
#[cfg(feature = "jobs")]
pub use facade::jobs;
#[cfg(feature = "mail")]
pub use facade::mail;
#[cfg(feature = "observe")]
pub use facade::observe;
#[cfg(feature = "pages")]
pub use facade::pages;
#[cfg(feature = "storage")]
pub use facade::storage;

// AP2.1-8: the realtime WebSocket + SSE surface. Behind the `realtime`
// feature. Re-exported at the crate root so applications reach the primary
// types as `arcature::Broadcast`, `arcature::WebSocketEndpoint`, etc., and
// the deeper API as `arcature::realtime::*` (the submodule paths remain
// canonical — one-file-one-responsibility, AGENTS.md §1).
#[cfg(feature = "realtime")]
pub use realtime::{
    AllowAll, Authorizer, Broadcast, ChannelError, ChannelPayload, ConnectionGuard, OriginDecision,
    OriginPolicy, ProtocolHint, RealtimeError, Registry, ShutdownConfig, SseEndpoint, SseLimits,
    Subscription, VerifiedOrigin, WebSocketEndpoint, WsLimits,
};
// The realtime drain entry point is exposed at the crate root as
// `arcature::drain_realtime` so the application's shutdown hook can call it
// without naming the submodule. It delegates to [`realtime::drain`]. Kept as
// a free function (not a method on `Application`) because the realtime
// registry is app-owned, not engine-owned, this wave. See
// `realtime::drain` for the integration-seam note the master wires into the
// global drain after the Production lane lands.
#[cfg(feature = "realtime")]
pub use realtime::drain as drain_realtime;

// A1: the Arcature DX layer (ADR-0003). Behind the `dx` feature:
//   - `DxComponent` (type namespace) — the runtime trait that
//     `#[derive(DxComponent)]` generates an impl for.
//   - `DxComponent` (macro namespace) — the derive macro re-exported from
//     `arcature-dx` so applications write `#[derive(arcature::DxComponent)]`
//     without importing `arcature_dx` directly.
// The trait and derive macro share the name `DxComponent` because they
// live in different namespaces (the same pattern as `serde::Serialize` the
// trait and `serde::Serialize` the derive). The `arcature_dx` crate itself
// is also re-exported so attribute macros (when added in later A-phases)
// are reachable as `arcature::arcature_dx::<MacroName>`.
#[cfg(feature = "dx")]
pub use arcature_dx;
#[cfg(feature = "dx")]
pub use arcature_dx::DxComponent;
#[cfg(feature = "dx")]
pub use dx::ApplicationGraph;
#[cfg(feature = "dx")]
pub use dx::ControllerMetadata;
#[cfg(feature = "dx")]
pub use dx::ControllerMethod;
#[cfg(feature = "dx")]
pub use dx::DxComponent;
#[cfg(feature = "dx")]
pub use dx::Empty;
#[cfg(feature = "dx")]
pub use dx::FieldShape;
#[cfg(feature = "dx")]
pub use dx::GraphError;
#[cfg(all(feature = "dx", feature = "serde"))]
pub use dx::Json;
#[cfg(feature = "dx")]
pub use dx::ModuleDescriptor;
#[cfg(feature = "dx")]
pub use dx::ModuleNode;
#[cfg(all(feature = "dx", feature = "serde"))]
pub use dx::Page;
#[cfg(feature = "dx")]
pub use dx::RequestCacheDescriptor;
#[cfg(feature = "dx")]
pub use dx::RequestMetadata;
#[cfg(feature = "dx")]
pub use dx::ResourceMetadata;
// The `page()` golden-path constructor is brought into scope via the prelude
// (`pub use crate::dx::page;`), not re-exported as `crate::page` at the crate
// root: the crate-root `crate::page` name is reserved for the `#[page]`
// attribute macro (see the A6 block below), which shares the name in the
// macro namespace. Re-exporting the value here would shadow the macro path.
#[cfg(feature = "dx")]
pub use dx::RouteDescriptor;
#[cfg(feature = "dx")]
pub use dx::RouteMethod;
#[cfg(all(feature = "dx", feature = "api"))]
pub use dx::Validated;

// A7: the route model binding contract and Bound<T> extractor. Behind
// `dx` + `db` (for the RouteModel trait, which references Db) and `api`
// (for Bound<T>, which produces Problem responses on 404/400/500).
#[cfg(all(feature = "dx", feature = "db", feature = "api"))]
pub use dx::Bound;
#[cfg(all(feature = "dx", feature = "db"))]
pub use dx::DbFromState;
#[cfg(all(feature = "dx", feature = "db"))]
pub use dx::RouteModel;

// A9: the auth/policies/session/flash DX layer (ADR-0004). Behind `dx` +
// `auth` (auth extractors need `tower_sessions::Session` from
// `arcature-auth`). The `#[policy]` macro generates `impl DxComponent`
// only — the developer writes `impl Policy<M>` by hand (the authorization
// logic is business behavior the macro must not guess or hide).
//
// `AuthUser` / `UserLoader` are the application identity contracts — the
// application implements them for its user type. `Auth<U>`,
// `OptionalAuth<U>`, and `AuthManager<U>` are genuine Axum
// `FromRequestParts` extractors. `Session` and `Flash` are ergonomic
// wrappers over `tower_sessions::Session`. `Policy<M>` is the explicit
// authorization trait. `AuthzError` is the typed 403 error.
#[cfg(all(feature = "dx", feature = "auth"))]
pub use arcature_dx::policy;
#[cfg(all(feature = "dx", feature = "auth"))]
pub use dx::{
    Auth, AuthError, AuthManager, AuthUser, AuthzError, Current, LoginBuilder, OptionalAuth,
    OptionalCurrent,
};
#[cfg(all(feature = "dx", feature = "auth"))]
pub use dx::{Flash, FlashError, FlashLevel, FlashMessage};
#[cfg(all(feature = "dx", feature = "auth"))]
pub use dx::{Policy, Session, SessionError, UserLoader};

// A10: the middleware attribute macro and error-mapping layer. `#[middleware]`
// validates a function signature (`pub`, `async`, return type present) and
// passes it through unchanged so it remains a genuine Axum `from_fn`
// middleware. `ErrorMapFn` is the type-erased response-mapping function
// installed via `Application::error_mapping(...)`. Behind `dx`.
#[cfg(feature = "dx")]
pub use arcature_dx::middleware;
#[cfg(feature = "dx")]
pub use pipeline::error_mapping::ErrorMapFn;

// A11: the event/listener DX layer. `#[derive(Event)]` generates
// `impl DxComponent` + `impl Event` for typed application events. `#[listener(
// Event)]` validates a function signature and generates a `ListenerBinding`
// const for `arc check` inspection. `Dispatcher` is the type-erased in-process
// event dispatcher — listeners run sequentially in registration order. Behind
// `dx` + `serde` (events are type-erased via `serde_json::Value`).
#[cfg(all(feature = "dx", feature = "serde"))]
pub use arcature_dx::Event;
#[cfg(all(feature = "dx", feature = "serde"))]
pub use arcature_dx::listener;
#[cfg(all(feature = "dx", feature = "serde"))]
pub use dx::{DispatchError, Dispatcher, Event, ListenerBinding};

// A12 binding descriptors — pure compile-time metadata (defined in
// `dx::graph`, behind `dx` only, exactly like `ListenerBinding`). Re-exported
// UNGATED by `jobs` so the UAG / `arcature-build` can serialize them without
// pulling the `jobs` runtime subsystem (which drags in `db`/`arcature-jobs`/
// `chrono`/`tokio-util` — AGENTS.md §2: small apps remain small). The runtime
// types (`Command`, `Scheduler`, …) stay behind `jobs` in their own submodules.
// Previously these four were mis-gated behind `jobs`; the gate was a bug, not
// an architectural boundary.
#[cfg(feature = "dx")]
pub use dx::{CommandBinding, JobBinding, ScheduleBinding, ScheduleCadence};

// A12: the jobs/scheduler/commands DX layer. `#[derive(Job)]` generates
// `impl DxComponent` + `impl Job` + a `JobModel` const for typed enqueue.
// `#[job_handler]` validates a function signature and generates a
// `JobBinding` const for `arc check` inspection. `#[command("name")]`
// generates a `CommandBinding` const. `Scheduler` is the managed
// recurring-job enqueuer with `CancellationToken` lifecycle. `CommandRegistry`
// is the type-erased command dispatcher for `arc run`. Behind `dx` + `jobs`
// (and `serde` for the `Job` derive — payloads are type-erased via
// `serde_json::Value`, matching the A11 `Dispatcher` and the `arcature-jobs`
// `Registry` patterns).
#[cfg(all(feature = "dx", feature = "jobs", feature = "serde"))]
pub use arcature_dx::Job;
#[cfg(all(feature = "dx", feature = "jobs"))]
pub use arcature_dx::command;
#[cfg(all(feature = "dx", feature = "jobs"))]
pub use arcature_dx::job_handler;
#[cfg(all(feature = "dx", feature = "jobs", feature = "serde"))]
pub use dx::Job;
#[cfg(all(feature = "dx", feature = "jobs"))]
pub use dx::{Command, CommandError, CommandRegistry, Scheduler, SchedulerError};

// A14: the testing DX layer. `#[test(app = <expr>)]` wraps an
// `async fn(app: TestApp)` into a `#[tokio::test]` that builds a `TestApp`
// from the caller's router expression — removing the `TestApp::new(...)`
// boilerplate while keeping the test honest (a real socket, a real HTTP
// client). Behind `dx` (the proc-macro re-export). The macro expansion
// references `::arcature_test::` paths that resolve in the downstream crate,
// so the caller must depend on `arcature-test`; `arcature` itself does not
// depend on `arcature-test` (the dependency direction is
// arcature-test → axum, not arcature-test → arcature → axum; §16).
#[cfg(feature = "dx")]
pub use arcature_dx::test;

// return `Json<T>` / `Page<T>` can derive `Serialize` without a direct
// `serde` dependency. This mirrors the prelude re-export (engine spec §44).
#[cfg(feature = "serde")]
pub use serde::{Deserialize, Serialize};

// A5: the certified validator surface at the crate root so `#[request]`
// can generate `#[derive(::validator::Validate)]` and controllers can
// bound on `T: Validate`. The `derive` feature is on, so both the trait
// and the derive macro are accessible through `::arcature::Validate`.
#[cfg(feature = "validation")]
pub use validator::Validate;

// A6: the page and resource DX macros. `#[page("name")]` generates
// `impl ClientData`, `Serialize` derive, and a `PageContract` const.
// `#[resource]` generates `impl ClientData` and `Serialize` derive. Both
// require the `inertia` feature (for `ClientData` / `PropsSchema` /
// `ContractType` / `PageContract`) and the `dx` feature (for the proc-macro
// re-export). `page!` constructs a `Page<T>` with a compile-time
// `ClientData` assertion.
#[cfg(all(feature = "dx", feature = "inertia"))]
pub use arcature_dx::page;
#[cfg(all(feature = "dx", feature = "inertia"))]
pub use arcature_dx::page_macro;
#[cfg(all(feature = "dx", feature = "inertia"))]
pub use arcature_dx::resource;

// A7: the #[route_model] attribute macro. Behind `dx` + `db` (the macro
// generates an `impl RouteModel` that references `::arcature::db::Db` and
// `::arcature::db::sea_orm`).
#[cfg(all(feature = "dx", feature = "db"))]
pub use arcature_dx::route_model;

// A8: the typed services/providers DX layer (ADR-0004). Behind the `dx`
// feature — services and providers are pure composition over application
// state, not tied to any specific subsystem. The `#[service]` macro
// generates `impl DxComponent`, `impl Service`, and `impl Resolve<S>`. The
// `#[provider]` macro generates `impl DxComponent` (the developer writes
// `impl Provider` by hand — the init logic is business behavior).
//
// `Resolve<S>` is the typed resolution trait (no runtime container). `Db`
// gets a `Resolve<S>` impl behind `dx` + `db` (via the existing
// `DbFromState<S>`). Other resources get manual one-line impls from the
// application. `Inject<T>` is the Axum extractor that calls `T::resolve`.
#[cfg(feature = "dx")]
pub use arcature_dx::provider;
#[cfg(feature = "dx")]
pub use arcature_dx::service;
#[cfg(feature = "dx")]
pub use dx::Inject;
#[cfg(feature = "dx")]
pub use dx::Provider;
#[cfg(feature = "dx")]
pub use dx::Resolve;
#[cfg(feature = "dx")]
pub use dx::Service;

// `#[arcature::main]` re-exports the certified Tokio multi-thread runtime macro
// so a normal application needs no direct `tokio` dependency merely for
// `#[tokio::main]` (engine spec §23). Expert users may still bring their own
// runtime and call the async `Application::serve` / `App::serve` APIs without
// this feature.
#[cfg(feature = "macros")]
pub use tokio::main;

// AP2.1-7: the system-check framework's public surface, re-exported at the
// crate root so `arc doctor --checks` (and the MCP `system_checks` tool,
// later) and the application reach the trait + types as `arcature::SystemCheck`
// etc. without qualifying the module path. The trait and the
// non-serializable shapes are always available; the JSON views are behind
// `serde`. `FRAMEWORK_CHECKS` is the framework's own `&'static` slice the
// CLI wires into the registry alongside the application's slices.
//
// The registry function is re-exported as `run_checks` (not `run`) because
// `arcature::run` is already the application runtime entrypoint
// (`application::run`, re-exported above). A distinct, descriptive name
// avoids the value-namespace collision and is greppable to the system-check
// registry.
pub use system_check::CheckCategory;
pub use system_check::CheckId;
pub use system_check::CheckIdError;
pub use system_check::CheckResult;
pub use system_check::CheckSeverity;
pub use system_check::CheckStatus;
pub use system_check::FRAMEWORK_CHECKS;
pub use system_check::SystemCheck;
pub use system_check::SystemCheckReport;
pub use system_check::run as run_checks;
#[cfg(feature = "serde")]
pub use system_check::{CheckResultJson, SystemCheckReportJson};

// AP2.1-7: the request-owned memoization surface. Re-exported at the crate
// root so a handler takes `arcature::RequestCache` and calls
// `cache.get_or_compute(...)` directly. `RequestCache` is `Clone` (its slot
// map lives behind an inner `Arc<Mutex<…>>`, so a clone shares the slots);
// the Axum extractor self-inserts into request extensions so multiple
// extractions in one request share one cache. `RequestCacheFactory` is the
// optional application-state hook (the extractor self-inserts, so the
// factory is only needed for the explicit `from_state` path). Behind
// `request-cache`.
#[cfg(feature = "request-cache")]
pub use request_cache::{MAX_KEY_BYTES, RequestCache, RequestCacheError, RequestCacheFactory};