//! # obsigil
//!
//! A mandate-token format and shared-secret **JWT alternative**: a
//! token split into a public **manifest** and an encrypted
//! **mandate**. Each half is an
//! authenticated, deterministically-encrypted ciphertext — AES-SIV
//! (RFC 5297, code `0`) or AES-GCM-SIV (RFC 8452, code `1`) — joined by a
//! separator that names the text encoding (`.` b64, `~` hex), with a
//! per-half algorithm code in the clear:
//!
//! ```text
//! token = [ manifest ALG ] SEP [ ALG mandate ]
//! ```
//!
//! This crate is the **backend** side: an [`Issuer`] mints mandates under
//! a secret [`MandateKey`], and [`Verifier::clauses`] checks them against the
//! reserved fields (the Reserved fields section, §8). The manifest is keyless and advisory; read
//! its [`claims`] with no secret. Verification is symmetric — the same
//! [`MandateKey`] both mints and verifies — so obsigil fits shared-secret
//! (HS256-style) JWT and JWE use cases, not public-key verification.
//!
//! Built directly on RustCrypto (`aes-siv`, `aes-gcm-siv`, `hkdf`). Only
//! authenticated AEADs are ever compiled in, so an unauthenticated mandate
//! is structurally unrepresentable (the mandate-must-be-authenticated rule of the Security Considerations, §16.2).
//!
//! The normative format is the obsigil specification; section references in
//! this source (e.g. the manifest construction, §5.2) point there.
//!
//! # Example
//!
//! ```rust
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use obsigil::{claims, generate_key, Claims, Clauses, Issuer, MandateKey, Verifier};
//! use serde::{Deserialize, Serialize};
//!
//! #[derive(Serialize, Deserialize)]
//! struct Access { role: String }
//! #[derive(Serialize, Deserialize)]
//! struct Ui { theme: String }
//!
//! // One 64-byte secret, provisioned to both sides (use
//! // `generate_key()` in production).
//! # let _ = generate_key;
//! let issuer_key = MandateKey::from_bytes([42u8; 64])?;
//!
//! // Issuer: mint a token. The mandate carries the authoritative clauses;
//! // the optional manifest carries advisory claims.
//! let token = Issuer::new(issuer_key)
//!     .clauses(&Access { role: "admin".into() })
//!     .exp(4_000_000_000)
//!     .audience(["api"])
//!     .manifest("auth.example", &Ui { theme: "dark".into() })
//!     .mint()?;
//!
//! // Front end: read the manifest's claims with no secret (advisory only).
//! let advisory: Claims<Ui> = claims(&token).expect("present");
//! assert_eq!(advisory.issuer(), "auth.example");
//!
//! // Backend: verify the mandate's clauses (authoritative). `now` is pinned
//! // here for a deterministic example; omit it to read the system clock.
//! let verify_key = MandateKey::from_bytes([42u8; 64])?;
//! let clauses: Clauses<Access> = Verifier::new()
//!     .key(&verify_key)
//!     .audience("api")
//!     .now(1_000_000_000)
//!     .clauses(&token)?;
//! assert_eq!(clauses.app().role, "admin");
//! # Ok(()) }
//! ```

mod aead;
mod encoding;
mod error;
mod key;
mod mint;
mod reserved;
mod serial;
mod token;
mod types;
mod verify;

#[cfg(feature = "conformance")]
pub mod lowlevel;

pub use error::{Error, KeyError, MintError, Reason};
pub use key::{generate_key, MandateKey};
pub use mint::{Issuer, MintBuilder};
pub use reserved::{Claims, Clauses, NoApp};
pub use types::{tid_issued_at, Alg, Encoding, NumericDate, MANIFEST_KEY};
pub use verify::{authorization_header, claims, mandate, manifest, manifest_plaintext, Verifier};

// Re-exported for callers handling `tid` (the `tid` field, §8.2).
pub use uuid::Uuid;
