README.md (8025B)
1 # radroots_event_codec 2 3 `radroots_event_codec` is the portable, deterministic algorithm layer for 4 Radroots events. It converts between bounded wire representations and native 5 `radroots_event` values, computes canonical NIP-01 identifiers, verifies event 6 identifiers and signatures, validates event contracts, admits typed event 7 profiles, and generates governed contract manifests. 8 9 The crate is pre-release and its Cargo version is frozen at `0.1.0-alpha` 10 until explicitly changed. Serialized contract generations such as registry v7 11 are versioned independently from the Cargo package. 12 13 ## Canonical surface 14 15 New code should enter through these modules: 16 17 | Module | Responsibility | 18 | --- | --- | 19 | `authoring` | Freeze exact registry-authored event plans and distinct HTTP-only Blossom authorization plans with semantic digests. | 20 | `canonical` | Compute canonical NIP-01 preimages and event identifiers without asserting trust. | 21 | `decode` | Parse bounded wire data and domain projections without silently verifying later stages. | 22 | `encode` | Produce deterministic JSON, tags, and unsigned wire parts from validated native inputs. | 23 | `verify` | Advance explicit identifier, signature, and contract-validation typestates. | 24 | `admission` | Apply typed or registry admission to an already verified event; available with `json`. | 25 | `manifest` | Generate and validate registry and knowledge inventories; available with `manifests`. | 26 27 The Release V1 canonical root consists of `Codec`, `DecodeError`, 28 `EncodeError`, and `VerificationError`. Domain algorithms stay beneath the 29 canonical modules so each import states whether it encodes, decodes, verifies, 30 or admits data. Legacy top-level domain routes are not exposed. The canonical 31 surface is recorded in the 32 [public API baseline](../../contracts/api_baselines/radroots_event_codec.txt). 33 34 ## Verification pipeline 35 36 Wire parsing and cryptographic trust are separate operations. A successful 37 decode returns a structurally valid `RawEvent`; it does not make the declared 38 event ID, signature, contract, referenced events, relay hints, or remote media 39 trustworthy. 40 41 ```rust 42 use radroots_event_codec::{admission, decode, verify}; 43 44 const PROFILE_EVENT: &str = r#"{"id":"762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0","pubkey":"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df","created_at":1800000100,"kind":0,"tags":[],"content":"{\"display_name\":\"Moss Street Farm\",\"bot\":false,\"website\":\"https://mossstreet.example\",\"picture\":42}","sig":"4290da0bb6422986647bc8cd5f63bd52d49f41e7b665d3b47105b8109183e8d596f322c531d4061df53e1d2b70fda12d5d1c14f3720d7a56d9d0a03746af5109"}"#; 45 46 let raw = decode::event(PROFILE_EVENT)?; 47 let verified = verify::verify_nip01_event(raw.into_event())?; 48 let admitted = admission::admit_verified_event(verified)?; 49 50 assert_eq!(admitted.event().kind_u32(), 0); 51 # Ok::<(), Box<dyn std::error::Error>>(()) 52 ``` 53 54 A runnable version is available at 55 [`examples/verify_profile.rs`](examples/verify_profile.rs). 56 57 For capability-injected verification, use `verify::id`, then 58 `verify::signature`, then `verify::contract`. Each function consumes its input 59 typestate and returns the next, so callers cannot obtain a later state by 60 accidentally skipping an earlier check. 61 62 ## Features 63 64 | Feature | Default | Effect | 65 | --- | --- | --- | 66 | `std` | yes | Standard-library error integration for the portable surface. | 67 | `serde` | no | Serde support for native values used by codec contracts. | 68 | `json` | yes | Bounded JSON parsing/encoding and JSON-backed typed profiles; enables `serde`. | 69 | `knowledge` | no | Knowledge event codecs and verified decoding; enables `json`. | 70 | `manifests` | no | Typed registry and knowledge manifest generation; enables `knowledge`. | 71 72 `--no-default-features` keeps the portable allocation-backed canonical, 73 encoding, decoding, and verification core. Feature-specific APIs disappear 74 when their feature is disabled rather than installing a fallback with weaker 75 guarantees. 76 77 ## Serialization and canonicalization 78 79 - `decode::event` accepts compact NIP-01 JSON only within the shared bounded 80 wire limits. Unknown extension structure is bounded before it can consume 81 unbounded memory or parser depth. 82 - `encode::event` emits deterministic compact JSON from an existing event 83 envelope. Encoding does not verify or alter the envelope. 84 - `canonical::id_preimage` and `canonical::id` compute canonical bytes and the 85 corresponding identifier. They do not compare the result with the event's 86 declared ID. 87 - Domain encoders accept checked `radroots_event` inputs and emit unsigned 88 wire parts. Signing and publication belong to the owning runtime. 89 - `authoring::BlossomAuthorizationPlan` binds a strict BUD-11 upload claim to 90 an expected author and event ID under a domain-separated digest. Its 91 distinct type cannot be passed to relay push APIs. 92 - Manifest JSON and digests are generated from versioned contract authority; 93 a manifest feature does not grant storage or publication authority. 94 95 Serialized output is stable only where its event profile or manifest 96 generation says it is stable. Rust data layout and the pre-release public API 97 are not serialized contracts. 98 99 ## Security and trust boundaries 100 101 All public parsers treat their inputs as untrusted. They return structured 102 errors for malformed or over-budget data and do not intentionally panic on 103 untrusted input. Verification distinguishes these claims: 104 105 1. structural decoding proves only bounded event shape; 106 2. ID verification proves the declared identifier matches canonical bytes; 107 3. signature verification proves the BIP-340 signature for that event and 108 author; 109 4. contract validation proves the event matches a registered shape; 110 5. typed admission proves the selected Radroots profile. 111 112 No stage proves referenced-event existence, relay availability, media upload 113 or retrievability, actor authorization, business-policy approval, persistence, 114 or publication. Inbound URLs and relay hints remain structural observations 115 unless a higher layer explicitly establishes a stronger state. 116 117 The crate never owns secret keys and does not sign events. Signature 118 verification is deterministic and public-key-only. Callers must not interpret 119 a successfully encoded unsigned event as signed or published. 120 121 ## Side effects, cancellation, and commit points 122 123 This crate performs no network access, filesystem access, database access, 124 background work, executor installation, timer management, signing, or event 125 publication. Its algorithms are synchronous and deterministic for the same 126 inputs. 127 128 There is therefore no asynchronous cancellation or deadline boundary and no 129 durable commit point. Dropping a computation only discards in-memory work. 130 Storage, signing, transport, SDK, and daemon callers own cancellation and must 131 report success only after their own explicit commit boundary succeeds. 132 133 ## Intended consumers 134 135 Direct consumers are `radroots_nostr`, `radroots_storage_sqlite`, 136 `radroots_transport_nostr`, `radroots_sync`, `radroots_sdk`, generated 137 bindings, indexers, and conformance tooling. Applications should normally use 138 the `radroots` or `radroots_sdk` front door and depend on this crate directly 139 only when implementing a deterministic event boundary. 140 141 This package must not acquire live relay clients, persistence, background 142 workers, host configuration, SDK state, or upstream client error types. Those 143 responsibilities belong to adapter and runtime crates. 144 145 ## Package charter 146 147 The authoritative Release V1 responsibility, dependency, feature, module, and 148 forbidden-scope contract is the 149 [Radroots crates Release V1 specification](../../contracts/crates/release_v1/radroots_crates_release_v1.toml). 150 The reviewed surface is the 151 [`radroots_event_codec` API baseline](../../contracts/api_baselines/radroots_event_codec.txt). 152 153 ## Copyright 154 155 Except as otherwise noted, all files in the `radroots_event_codec` 156 distribution are copyright (c) 2025 Tyson Lupul. See `LICENSE` for usage, 157 redistribution, and warranty terms.