[package]
name = "kryphocron"
version = "0.1.1"
edition = "2024"
rust-version = "1.85"
license = "MPL-2.0"
description = "Privacy-first ATProto substrate primitives: type architecture, audit vocabulary, inter-service auth, and encryption hook surfaces"
keywords = ["atproto", "substrate", "privacy", "bluesky", "federation"]
categories = ["authentication", "cryptography", "data-structures"]
authors = ["skydeval <skydeval@mail.nearhorizon.app>"]
repository = "https://github.com/skydeval/kryphocron"
homepage = "https://github.com/skydeval/kryphocron"
readme = "README.md"

# License: MPL-2.0 (file-level copyleft) per §9.8. Per-file
# headers point at the LICENSE file at the crate root.
# Downstream crates (PDS, AppView, etc.) are encouraged to ship
# permissive (MIT OR Apache-2.0).

[lib]
name = "kryphocron"
path = "src/lib.rs"

[dependencies]
# §9.5 trait-async dependency. Used by the §7 resolver and §8
# encryption-hook trait surfaces. v0.1 ships trait shapes only;
# concrete resolver / encryption impls are operator-supplied.
async-trait = "0.1"

# §9.5 small-vector optimization. Used in capability sets,
# attribution chains, scope vectors, JWT scope vectors, and the
# §4.2 AttributionChain entries (replacing the spec's ArrayVec
# reference; bounded depth is runtime-enforced by the crate's
# constructors).
smallvec = "1.13"

# §9.5 structured error derivation. Used across §4 error enums.
thiserror = "2"

# §9.5 / §7.2 Ed25519 signature verification. Wired into the
# JWT verification chain; the v1 algorithm allowlist defaults
# to Ed25519-only per §7.2's conservative-default discipline.
# ECDSA variants (ES256/ES256K) are operator opt-in and
# currently stub with `UnsupportedAlgorithm` (v0.2+ feature
# gate).
#
# v0.1 polish: tilde-pinned at the current resolved minor
# (`~2.2`, patch-updates-only). Signature-verification correctness
# is the highest-stakes correctness surface in the crate; minor
# bumps must be explicit Cargo.toml edits, not silent transitive
# resolution drifts.
ed25519-dalek = "~2.2"

# §7.2 / §9.5 base64url decoding for JWT segment parsing.
# Originally pinned to 0.22 to align with proto-blue's lexicon
# parsing (one major version across the dep tree). v0.1 polish:
# tightened to tilde (`~0.22`) for canonical-encoding stability —
# accidental minor bumps in a foundational primitives crate must
# require an explicit Cargo.toml edit. For 0.x crates this is
# functionally equivalent to a bare `0.22` (cargo treats minor as
# breaking), but the tilde marks the pin as discipline-managed.
base64 = "~0.22"

# §7.2 / §9.5 JSON parsing for JWT headers and payloads.
# Unconditional dependency because the verification path needs
# JSON parsing on every authenticated request. The
# `audit-serde-json` feature retains its `dep:serde` activation
# for the optional `Serialize`/`Deserialize` derives on audit
# events.
serde_json = "1"

# §4.8 / §7.6 / §9.5 deterministic CBOR encoding for the
# capability-claim wire format. Uses ciborium's `Value` tree
# as the building block and a project-internal canonicalizer
# (RFC 8949 §4.2.1 length-then-bytewise map-key sort) to produce
# round-trip-stable signatures. Originally pinned to 0.2 to align
# with proto-blue's lexicon parsing transitive tree. v0.1 polish:
# tightened to tilde (`~0.2`) — canonical-CBOR output is the
# wire-format-deciding encoder for signed capability claims; a
# silent minor bump that altered map-key ordering or tag rendering
# would invalidate every signature ever produced under the prior
# encoding.
ciborium = "~0.2"

# §4.4 / §7.5 / §9.5 keyed Blake3 for session-id derivation
# (`SubstrateSessionDerivationKey`-keyed over `nonce || entropy`)
# and session-digest correlation (`CorrelationKey`-keyed over
# the session id, §4.4). Both call sites are wired in v0.1.
#
# v0.1 polish: tilde-pinned at the current resolved minor
# (`~1.8`, patch-updates-only). Session-digest correlation depends
# on stable keyed-hash output across versions; minor bumps require
# explicit Cargo.toml edits.
blake3 = "~1.8"

# §7.5 / §9.5 OS CSPRNG access for
# `SubstrateSessionDerivationKey::generate` and the responder-side
# `responder_entropy` produced fresh per handshake. Already in the
# transitive dep tree (via ed25519-dalek's rand_core); promoted to
# a direct dep so the surface is explicit and pinned at the major
# version we depend on. Originally pinned to 0.2 to align with
# proto-blue's lexicon parsing transitive tree. v0.1 polish:
# tightened to tilde (`~0.2`) — CSPRNG access is correctness-
# critical for unforgeable session derivation; a silent minor bump
# changing the OS entropy contract is the kind of surface a
# foundational primitives crate must not silently inherit.
getrandom = "~0.2"

# §5 lexicon strategy: the companion crate ships the v1
# lexicons, the codegen-produced Rust types, and the build-time
# three-way-consistency-checked registry. The kryphocron crate
# consumes it for `Tier`, `Visibility`, `UnknownNsid`, `SemVer`,
# `DeprecationState`, `LexiconRegistryEntry`,
# `KRYPHOCRON_LEXICON_REGISTRY`, and the validated AT-Protocol
# identifier types (`Did`, `Nsid`, `RecordKey`, `AtUri`, `Cid`,
# `Datetime`, `Tid`).
kryphocron-lexicons = { path = "../kryphocron-lexicons", version = "0.1" }

# §4.6 timing-channel equalization sleep primitive
# (`tokio::time::sleep` consumed by `crate::timing::equalize_timing`).
# Tokio is a production dependency rather than dev-only;
# operators on a non-tokio async runtime supply a tokio-
# compatible reactor or shim. A runtime abstraction is a v0.2+
# enrichment.
tokio = { version = "1", features = ["time"] }

[dev-dependencies]
# `trybuild` for "this should not compile" assertions on the
# sealed surfaces.
trybuild = "1"
# §7.2 JWT verification tests are async because `verify_jwt` is
# async (DID resolution may need network I/O). Use the
# `tokio::test` macro with a single-thread runtime — tests
# don't need the multi-thread scheduler.
tokio = { version = "1", features = ["macros", "rt"] }

[features]
default = []

# Integration-test scaffolding. Exposes a minimal set of
# constructors (`AuthContext::new_for_test`,
# `ServiceIdentity::new_for_test`) so out-of-crate tests can
# drive issuance → bind → audit pipelines end-to-end without
# standing up a full verified-evidence path. Off by default.
# Downstream crates testing integrations against kryphocron
# (e.g., the Aurora-Locus federation surface) opt in via
# `kryphocron = { version = "0.1", features = ["test-support"] }`
# in their `[dev-dependencies]`.
test-support = []

# §9.4 / §6.10 `audit-serde-json` feature for operators
# consuming JSON audit streams. v0.1 ships the audit-event
# variant set without the transitive `Serialize` / `Deserialize`
# derive wiring (§6.10's "every reachable type gains the
# derives" goal requires changes across `crate::identity`
# (ServiceIdentity's sealed-token PhantomData; Instant fields
# in `BindOutcomeRepr::Expired`), `kryphocron-lexicons` (SemVer,
# Nsid, Did currently lack derives), and downstream crates; a
# v0.2+ enrichment). Both `cargo build --features
# audit-serde-json` and `cargo build` succeed today — the
# feature flag is structurally wired and the `serde` /
# `serde_json` dependencies are correctly optional.
audit-serde-json = ["dep:serde"]

[dependencies.serde]
version = "1"
optional = true
features = ["derive"]

# `serde_json` lives in the unconditional `[dependencies]`
# block above because the §7.2 JWT verification path needs
# JSON parsing on every authenticated request. The
# `audit-serde-json` feature still activates `serde` for the
# optional Serialize/Deserialize derives on audit-event types.

[lints.rust]
unsafe_code = "forbid"
missing_docs = "warn"
rust_2024_compatibility = { level = "warn", priority = -1 }

[lints.clippy]
# Project-standard lint level: warn `all` (correctness + suspicious
# + style + complexity + perf), allow pedantic.
all = { level = "warn", priority = -1 }
pedantic = { level = "allow", priority = -1 }

# Phase-stub patterns are now disallowed: v0.1 ships whole, with
# no remaining `todo!()` / `unimplemented!()` in production code.
# Denying these lints makes a stray placeholder in a future patch
# a hard build failure rather than a silent compile. Test-fixture
# panics with explicit messages (e.g.
# `panic!("test fixture: should be unreachable")`) remain
# permitted — they describe a structural invariant, not a stub.
todo = "deny"
unimplemented = "deny"

# §4-committed shapes carry large fields (ServiceIdentity holds
# key material + rotation evidence; DenialReason and AuthDenial
# carry the full diagnostic payload per round-5). Boxing them
# would be a wire-format-touching change; v0.1 keeps the spec-
# committed shapes verbatim, leaving any perf-driven boxing for
# v0.2+.
large_enum_variant = "allow"
result_large_err = "allow"

# §4.8 CapabilityClaim::new constructor takes 8 args by spec;
# the alternative (a builder) is a v0.2+ ergonomics decision.
too_many_arguments = "allow"

# The crate's #[must_use] discipline mostly lives on types
# (Proof families, Outcome, etc.). Function-level #[must_use] on
# helpers returning already-must_use types is doubled; clippy
# flags it correctly — fixes are inline.
