ppoppo-token 0.1.0

JWT (RFC 9068, EdDSA) issuance + verification engine for the Ppoppo ecosystem. Single deep module with a small interface (issue, verify) hiding RFC 8725 mitigations M01-M45, JWKS handling, and substrate ports (epoch, session, replay).
Documentation
// JWT engine (RFC_2026-05-04_jwt-full-adoption Phase 1+).
//
// All JWT verification flows through `engine::verify`. The
// `engine/check_*.rs` submodules are `pub(crate)` — consumers reach them
// only through the re-exports below. Direct calls to `jsonwebtoken::*`
// outside `engine/` are forbidden (M51/M52, lint rule lands Phase 7).
mod claims;
mod engine;
mod epoch_revocation;
mod error;
mod issue_config;
mod issue_error;
mod issue_request;
mod jwks;
mod key_set;
mod replay_defense;
mod session_revocation;
mod signing_key;
mod verify_config;

pub use crate::claims::Claims;
pub use crate::engine::{issue, verify};
pub use crate::epoch_revocation::{EpochRevocation, EpochRevocationError};
pub use crate::error::AuthError;
pub use crate::issue_config::IssueConfig;
pub use crate::issue_error::IssueError;
pub use crate::issue_request::IssueRequest;
pub use crate::jwks::{Jwk, Jwks, JwksError};
pub use crate::key_set::KeySet;
pub use crate::replay_defense::{ReplayDefense, ReplayDefenseError};
pub use crate::session_revocation::{SessionRevocation, SessionRevocationError};
pub use crate::signing_key::{ed25519_public_from_pem, SigningKey};
pub use crate::verify_config::{Algorithm, VerifyConfig};

pub const DEFAULT_ISSUER: &str = "accounts.ppoppo.com";

/// TTL for the `sv:{ppnum_id}` cache entry shared between PAS (writer) and
/// PCS / external SDK consumers (readers). Bounds the post-break-glass
/// staleness window when the writer cannot preemptively invalidate.
///
/// Value contract: 60 s. See STANDARDS_SHARED_CACHE §3.1 (Reader / Writer
/// table) and STANDARDS_AUTH_PPOPPO §17.7 (wiring status).
pub const SV_CACHE_TTL: std::time::Duration = std::time::Duration::from_secs(60);

/// Build the shared cache key for a given Human ppnum's `session_version`.
///
/// Returned shape: `sv:{ppnum_id}`. Encapsulates the prefix so callers
/// cannot accidentally mis-format the key (forgetting the colon, double
/// prefixing, etc.). PAS writes this key on break-glass commit; PCS
/// chat-auth and the pas-external SDK validator read it.
///
/// SSOT: STANDARDS_SHARED_CACHE §3.1 (`sv:` shared contract).
#[must_use]
pub fn sv_cache_key(ppnum_id: &str) -> String {
    format!("sv:{ppnum_id}")
}