arcature 2026.1.0

Arcature application framework: a high-level Application facade over the certified Arcature subsystems, with the low-level Axum/Tower escape hatch preserved.
Documentation
//! Typed jobs — the runtime contract for the A12 job DX layer.
//!
//! Jobs are typed application data: `#[derive(Job)] pub struct
//! SendVerificationEmail { pub user_id: Uuid }`. The application enqueues a
//! job explicitly via `jobs.enqueue(&JobRequest::new(&model, &payload)?)`
//! — there is **no hidden dispatch** (PROGRAM.md: "job dispatch" is forbidden
//! hidden behavior in macros). The `#[job_handler]` macro annotates a
//! function that the worker calls when the job is dequeued, but does NOT
//! register or enqueue anything at compile time.
//!
//! This module owns only the DX trait. The real queue, registry, worker,
//! and lifecycle live in `arcature-jobs`; this layer is the compile-time
//! DX glue that the macros generate against. The metadata binding
//! ([`JobBinding`]) lives in [`crate::dx::graph`] alongside the other
//! module-graph bindings.
//!
//! # Type erasure
//!
//! The `arcature-jobs` `Registry` type-erases handlers behind
//! `serde_json::Value`, exactly like the A11 `Dispatcher`. There is no
//! `TypeId`/`Any` container (AGENTS.md §17). The `Job` trait is a plain
//! marker that ties a typed job struct to its static `NAME` — the metadata
//! the `JobRequest` constructor needs.

use crate::dx::DxComponent;

/// The marker trait for typed Arcature jobs (A12).
///
/// A job is a plain data struct that carries the arguments for a unit of
/// background work. The `#[derive(Job)]` macro generates `impl DxComponent`
/// (with the static `NAME`), `impl Job` (empty — it is a marker), and a
/// `pub const JOB_MODEL: ::arcature::jobs::JobModel<Self>` for enqueue.
///
/// The trait extends `DxComponent` so the job has a static `NAME` used for
/// handler registration lookup and `arc check` inspection.
///
/// # Example
///
/// ```ignore
/// #[derive(Job, serde::Serialize, serde::Deserialize)]
/// #[job(attempts = 5)]
/// pub struct SendVerificationEmail {
///     pub user_id: Uuid,
/// }
/// ```
///
/// The struct should also derive `Serialize` and `Deserialize` (the
/// `arcature-jobs` registry type-erases payloads via `serde_json::Value`).
/// `#[derive(Job)]` does NOT add serde derives — the application brings
/// its own `serde` derives so the job struct stays a plain data type.
pub trait Job: DxComponent + serde::Serialize + serde::de::DeserializeOwned {}