Skip to main content

cortex_ledger/
lib.rs

1//! Append-only ledger: events, hash chaining, traces. No semantic interpretation.
2//!
3//! This crate is the **substrate-layer ledger** (BUILD_SPEC §8): it owns the
4//! append-only event log, the BLAKE3 hash chain that makes events immutable,
5//! the JSONL mirror used for inspectability and disaster recovery
6//! (BUILD_SPEC §7), trace assembly (event ordinals, open / attach / close),
7//! and the audit-verify pass.
8//!
9//! It performs **no semantic interpretation** — that lives in `cortex-memory`
10//! and `cortex-reflect`. It performs **no SQL** — that lives in `cortex-store`
11//! (the JSONL log here is a separate, equal-priority mirror, not a SQL
12//! abstraction).
13//!
14//! Module map:
15//! - [`hash`] — BLAKE3 framing, payload + event hash computation, sealing.
16//! - [`trace`] — `TraceAssembler`: open / attach / close, dense ordinals.
17//! - [`jsonl`] — `JsonlLog`: append-only with fsync per write, iter, verify.
18//! - [`audit`] — `verify_chain(path) -> Report` with per-row reasons,
19//!   plus [`audit::verify_signed_chain`] enforcing the Ed25519 signature
20//!   chain (Lane 3.D.6, ADR 0010 §1-§2).
21//! - [`signed_row`] — On-disk envelope carrying the per-row Ed25519
22//!   signature ([`signed_row::SignedRow`] + [`signed_row::RowSignature`]).
23//! - [`anchor_chain`] — Bridge between an [`cortex_core::Event`] and the
24//!   canonical [`cortex_core::canonical::AttestationPreimage`] that gets
25//!   signed; also defines the `identity.rotate` payload shape.
26//! - [`anchor`] — ADR 0013 position-bound external anchor parse / format /
27//!   verify primitive.
28//! - [`external_sink`] — ADR 0013 Mechanism C foundation: typed
29//!   [`external_sink::ExternalSink`] selector, v1 receipt sidecar parser,
30//!   and the [`external_sink::ots`] quarantine boundary around the
31//!   `opentimestamps` crate (operator decisions #3 + #4 — see the
32//!   module-level doctrine notes).
33
34#![deny(unsafe_code, missing_debug_implementations)]
35#![warn(missing_docs)]
36
37pub mod anchor;
38pub mod anchor_chain;
39pub mod audit;
40pub mod external_sink;
41pub mod hash;
42pub mod jsonl;
43pub mod sha256;
44pub mod signed_row;
45pub mod trace;
46
47pub use anchor::{
48    current_anchor, parse_anchor, verify_anchor, AnchorParseError, AnchorVerification,
49    AnchorVerifyError, LedgerAnchor, ANCHOR_FORMAT_HEADER_V1,
50};
51pub use anchor_chain::{
52    extract_rotation_payload, is_identity_rotate, row_preimage, RotationPayload,
53    GENESIS_PREV_SIGNATURE, IDENTITY_ROTATE_PAYLOAD_KIND,
54};
55pub use audit::{
56    verify_chain, verify_signed_chain, FailureReason, HashKind, Report, RowFailure,
57    SignedChainOutcome,
58};
59pub use external_sink::ots::adapter::{
60    calendar_operator, enforce_disjoint_authority_quorum, submit as submit_ots,
61    verify_receipt as verify_ots_receipt,
62    verify_receipt_with_defaults as verify_ots_receipt_with_defaults, BitcoinHeaderSource,
63    CalendarClient, HttpsHeadersBitcoinHeaderSource, NoopCalendarClient, OtsBrokenEdge,
64    OtsVerificationOutcome, OtsWitness, StaticBitcoinHeaderSource, UreqCalendarClient,
65    DEFAULT_HTTPS_HEADER_PROVIDERS, DEFAULT_HTTPS_HEADER_QUORUM_N, DEFAULT_OTS_CALENDAR_URL,
66    DEFAULT_OTS_CALENDAR_URLS, OTS_CALENDAR_OPERATORS, OTS_DISJOINT_AUTHORITY_MIN_OPERATORS,
67};
68pub use external_sink::ots::{
69    DefaultOtsParser, OtsError, OtsParser, TypedOtsProof, BITCOIN_ATTESTATION_TAG,
70    OTS_BITCOIN_CONFIRMED_BLOCK_HEADER_MISMATCH_INVARIANT,
71    OTS_BITCOIN_CONFIRMED_MERKLE_PATH_INVALID_INVARIANT, OTS_BITCOIN_HEADER_POW_INVALID_INVARIANT,
72    OTS_BITCOIN_HEADER_QUORUM_PROVIDERS_DISAGREE_INVARIANT,
73    OTS_BITCOIN_HEADER_QUORUM_UNREACHABLE_INVARIANT,
74    OTS_DISJOINT_AUTHORITY_QUORUM_NOT_MET_INVARIANT,
75    OTS_PENDING_NO_BITCOIN_ATTESTATION_YET_INVARIANT, OTS_TAG_WHITELIST_UNKNOWN_TAG_INVARIANT,
76    PENDING_ATTESTATION_TAG,
77};
78pub use external_sink::rekor::{
79    rekor_canonical_set_body, submit as rekor_submit, verify_receipt as rekor_verify_receipt,
80    InclusionProof as RekorInclusionProof, RekorError, RekorReceiptBody, RekorVerification,
81    REKOR_DEFAULT_ENDPOINT, REKOR_EXTERNAL_AUTHORITY_STATUS,
82    REKOR_INCLUSION_PROOF_INVALID_INVARIANT, REKOR_KIND_HASHEDREKORD_V0_0_1,
83    REKOR_SET_SIGNATURE_INVALID_INVARIANT, REKOR_SUBMIT_FAILED_INVARIANT,
84    REKOR_TRUSTED_ROOT_STALE_INVARIANT, REKOR_VERIFY_FAILED_INVARIANT,
85    REKOR_VERIFY_SIGNATURE_MISMATCH_INVARIANT,
86};
87pub use external_sink::trusted_root::{
88    active_trusted_root, ActiveTrustedRoot, TransparencyLogInstance, TransparencyLogPublicKey,
89    TrustRootStalenessAnchor, TrustRootStalenessError, TrustedRoot, TrustedRootIoError,
90    TrustedRootKeyError, TrustedRootParseError, ValidityPeriod, CACHED_ROOT_STATUS,
91    DEFAULT_MAX_TRUST_ROOT_AGE, EMBEDDED_ROOT_STATUS, EMBEDDED_TRUSTED_ROOT_SNAPSHOT_DATE,
92    REKOR_TRUSTED_ROOT_TLOG_LOGID_NO_MATCH_INVARIANT,
93    STABLE_INVARIANT_TRUSTED_ROOT_CACHE_FUTURE_DATED, TRUSTED_ROOT_CACHE_FUTURE_MTIME_TOLERANCE,
94    TRUSTED_ROOT_CACHE_STALE_INVARIANT, TRUSTED_ROOT_JSON, TRUSTED_ROOT_PARSE_INVARIANT,
95    TRUSTED_ROOT_SNAPSHOT_STALE_INVARIANT, TRUSTED_ROOT_STALE_INVARIANT,
96};
97pub use external_sink::{
98    anchor_text_sha256, parse_external_receipt, parse_external_receipt_history,
99    read_external_receipt_history, verify_external_receipts, ExternalReceipt,
100    ExternalReceiptHistoryIoError, ExternalReceiptParseError, ExternalReceiptVerification,
101    ExternalReceiptVerifyError, ExternalSink, ANCHOR_TEXT_HASH_MISMATCH_INVARIANT,
102    EXTERNAL_RECEIPT_FORMAT_HEADER_V1, PARSED_ONLY_VERIFICATION_STATUS,
103};
104pub use hash::{canonical_payload_bytes, event_hash, payload_hash, seal, DOMAIN_TAG_EVENT_HASH};
105pub use jsonl::{
106    append_policy_decision_test_allow, append_signed_policy_decision_test_allow,
107    schema_migration_v1_to_v2_policy_decision_test_allow, JsonlError, JsonlLog,
108    APPEND_ATTESTATION_REQUIRED_RULE_ID, APPEND_EVENT_SOURCE_TIER_GATE_RULE_ID,
109    APPEND_RUNTIME_MODE_RULE_ID, APPEND_SIGNED_KEY_STATE_CURRENT_USE_RULE_ID,
110    APPEND_SIGNED_TRUST_TIER_MINIMUM_RULE_ID, SCHEMA_MIGRATION_ATTESTATION_REQUIRED_RULE_ID,
111    SCHEMA_MIGRATION_AUTHORITY_CLASS_RULE_ID,
112    SCHEMA_MIGRATION_CURRENT_USE_TEMPORAL_AUTHORITY_RULE_ID,
113};
114pub use signed_row::{RowSignature, SignedRow};
115pub use trace::{TraceAssembler, TraceError};
116
117/// Back-compat shim: retained so `cortex-cli`'s `audit verify` subcommand
118/// keeps compiling against the pre-Lane-1.B API surface. New callers MUST
119/// use [`verify_chain`] (which takes a path and returns a typed [`Report`])
120/// instead.
121///
122/// This is a deliberate no-op: the CLI's verify path will be wired to the
123/// real audit walker in a follow-up lane that touches `cortex-cli`. The
124/// shim returns `Ok(())` so the existing "stub" semantics are preserved.
125///
126/// **Do not** call this from new code in this crate or downstream — it
127/// will be removed when the CLI is migrated.
128pub fn verify_hash_chain_stub() -> cortex_core::CortexResult<()> {
129    Ok(())
130}