commit b282947cc09853534f4b2e6243f9b51cbe1ccd34
parent fd8384aee348034e0c8ea17a868fe7f094770050
Author: triesap <tyson@radroots.org>
Date: Mon, 27 Jul 2026 07:06:32 +0000
docs: add crates release v1 specification
- Install the normative 19-package architecture contract.
- Allocate radroots-sdk and radroots to the standalone SDK repository.
- Encode release dependencies, features, and repository policy.
- Pin synchronized review artifacts with SHA-256 checksums.
Diffstat:
6 files changed, 2054 insertions(+), 0 deletions(-)
diff --git a/docs/specs/README.md b/docs/specs/README.md
@@ -0,0 +1,40 @@
+# Release specification index
+
+This directory carries the coordinated `radroots.crates.release.v1` contract
+for the two existing standalone Rust repositories.
+
+The `radrootslabs/sdk` repository owns packages 18-19, `radroots-sdk` and the
+ordinary-user `radroots` facade. The `radrootslabs/lib` repository owns
+packages 1-17, from `radroots-core` through `radroots-geonames`. No third Rust
+repository is part of this release architecture.
+
+## Files
+
+- `radroots_crates_release_v1.md` is the normative architecture and
+ publication specification.
+- `radroots_crates_release_v1.toml` is the machine-readable package,
+ dependency, feature, and repository-allocation catalog.
+- `radroots_crates_release_v1_inventory.csv` is the reviewable package
+ inventory.
+- `radroots_crates_release_v1.dot` is the reviewable dependency and repository
+ ownership graph.
+- `radroots_crates_release_v1.sha256` pins the synchronized contract artifact
+ contents.
+
+## Precedence and change control
+
+Repository instruction files govern how work is performed. Within this
+release contract, the Markdown specification is normative, the TOML catalog
+is its executable representation, and the CSV and DOT files are review aids.
+Current code and tests are implementation evidence, not authority to silently
+change the package architecture.
+
+The four contract artifacts and their hashes MUST match the copies in
+`radrootslabs/lib`. A change to package identity, ownership, dependency
+direction, or release policy MUST update both repositories together and MUST
+fail validation if the copies diverge.
+
+During migration, package manifests remain non-publishable until their
+package-realistic release gates pass. Cross-repository dependencies use
+registry versions in release candidates; a sibling checkout is never a
+production dependency.
diff --git a/docs/specs/radroots_crates_release_v1.dot b/docs/specs/radroots_crates_release_v1.dot
@@ -0,0 +1,102 @@
+digraph radroots_crates_release_v1 {
+ rankdir="BT";
+ graph [label="Radroots Crates Release V1", labelloc="t", fontsize=20];
+ node [fontname="Helvetica"];
+ "radroots-core" [shape=ellipse];
+ "radroots-identity" [shape=ellipse];
+ "radroots-blossom" [shape=ellipse];
+ "radroots-protocol" [shape=component];
+ "radroots-event" [shape=box];
+ "radroots-event-codec" [shape=box];
+ "radroots-trade" [shape=box];
+ "radroots-signing" [shape=hexagon];
+ "radroots-transport" [shape=hexagon];
+ "radroots-nostr" [shape=component];
+ "radroots-nostr-connect" [shape=component];
+ "radroots-secrets" [shape=hexagon];
+ "radroots-storage" [shape=hexagon];
+ "radroots-storage-sqlite" [shape=cylinder];
+ "radroots-transport-nostr" [shape=component];
+ "radroots-sync" [shape=box3d];
+ "radroots-geonames" [shape=component];
+ "radroots-sdk" [shape=doubleoctagon];
+ "radroots" [shape=doubleoctagon];
+ subgraph cluster_lib {
+ label="radrootslabs/lib (packages 1-17)";
+ "radroots-core"; "radroots-identity"; "radroots-blossom";
+ "radroots-protocol"; "radroots-event"; "radroots-event-codec";
+ "radroots-trade"; "radroots-signing"; "radroots-transport";
+ "radroots-nostr"; "radroots-nostr-connect"; "radroots-secrets";
+ "radroots-storage"; "radroots-storage-sqlite";
+ "radroots-transport-nostr"; "radroots-sync"; "radroots-geonames";
+ }
+ subgraph cluster_sdk {
+ label="radrootslabs/sdk (packages 18-19)";
+ "radroots-sdk"; "radroots";
+ }
+ "radroots-event" -> "radroots-blossom" [style=solid, label="required"];
+ "radroots-event" -> "radroots-core" [style=solid, label="required"];
+ "radroots-event" -> "radroots-identity" [style=solid, label="required"];
+ "radroots-event" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-event-codec" -> "radroots-blossom" [style=solid, label="required"];
+ "radroots-event-codec" -> "radroots-event" [style=solid, label="required"];
+ "radroots-event-codec" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-trade" -> "radroots-core" [style=solid, label="required"];
+ "radroots-trade" -> "radroots-event" [style=solid, label="required"];
+ "radroots-trade" -> "radroots-identity" [style=solid, label="required"];
+ "radroots-signing" -> "radroots-event" [style=solid, label="required"];
+ "radroots-signing" -> "radroots-identity" [style=solid, label="required"];
+ "radroots-signing" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-transport" -> "radroots-event" [style=solid, label="required"];
+ "radroots-transport" -> "radroots-identity" [style=solid, label="required"];
+ "radroots-transport" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-nostr" -> "radroots-blossom" [style=dashed, label="optional"];
+ "radroots-nostr" -> "radroots-signing" [style=dashed, label="optional"];
+ "radroots-nostr" -> "radroots-event" [style=solid, label="required"];
+ "radroots-nostr" -> "radroots-event-codec" [style=solid, label="required"];
+ "radroots-nostr" -> "radroots-identity" [style=solid, label="required"];
+ "radroots-nostr-connect" -> "radroots-event" [style=solid, label="required"];
+ "radroots-nostr-connect" -> "radroots-identity" [style=solid, label="required"];
+ "radroots-nostr-connect" -> "radroots-nostr" [style=solid, label="required"];
+ "radroots-nostr-connect" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-storage" -> "radroots-event" [style=solid, label="required"];
+ "radroots-storage" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-storage" -> "radroots-trade" [style=solid, label="required"];
+ "radroots-storage" -> "radroots-transport" [style=solid, label="required"];
+ "radroots-storage-sqlite" -> "radroots-event-codec" [style=solid, label="required"];
+ "radroots-storage-sqlite" -> "radroots-secrets" [style=solid, label="required"];
+ "radroots-storage-sqlite" -> "radroots-storage" [style=solid, label="required"];
+ "radroots-transport-nostr" -> "radroots-event-codec" [style=solid, label="required"];
+ "radroots-transport-nostr" -> "radroots-nostr" [style=solid, label="required"];
+ "radroots-transport-nostr" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-transport-nostr" -> "radroots-transport" [style=solid, label="required"];
+ "radroots-sync" -> "radroots-event" [style=solid, label="required"];
+ "radroots-sync" -> "radroots-event-codec" [style=solid, label="required"];
+ "radroots-sync" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-sync" -> "radroots-signing" [style=solid, label="required"];
+ "radroots-sync" -> "radroots-storage" [style=solid, label="required"];
+ "radroots-sync" -> "radroots-trade" [style=solid, label="required"];
+ "radroots-sync" -> "radroots-transport" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-geonames" [style=dashed, label="optional"];
+ "radroots-sdk" -> "radroots-nostr" [style=dashed, label="optional"];
+ "radroots-sdk" -> "radroots-nostr-connect" [style=dashed, label="optional"];
+ "radroots-sdk" -> "radroots-secrets" [style=dashed, label="optional"];
+ "radroots-sdk" -> "radroots-storage-sqlite" [style=dashed, label="optional"];
+ "radroots-sdk" -> "radroots-sync" [style=dashed, label="optional"];
+ "radroots-sdk" -> "radroots-transport-nostr" [style=dashed, label="optional"];
+ "radroots-sdk" -> "radroots-core" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-event" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-event-codec" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-identity" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-protocol" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-signing" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-storage" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-trade" [style=solid, label="required"];
+ "radroots-sdk" -> "radroots-transport" [style=solid, label="required"];
+ "radroots" -> "radroots-core" [style=solid, label="required"];
+ "radroots" -> "radroots-event" [style=solid, label="required"];
+ "radroots" -> "radroots-identity" [style=solid, label="required"];
+ "radroots" -> "radroots-sdk" [style=solid, label="required"];
+ "radroots" -> "radroots-trade" [style=solid, label="required"];
+ "radroots" -> "radroots-transport" [style=solid, label="required"];
+}
diff --git a/docs/specs/radroots_crates_release_v1.md b/docs/specs/radroots_crates_release_v1.md
@@ -0,0 +1,1549 @@
+# Radroots Crates Release V1
+
+**Normative identifier:** `radroots.crates.release.v1`
+**Document status:** Final pressure-tested architecture and publication specification
+**Date:** 2026-07-26
+**Source snapshots reviewed:**
+- `radrootslabs/lib@466f3cc36739179bc17edb9db796530729ba5219`
+- `radrootslabs/sdk@fd8384aee348034e0c8ea17a868fe7f094770050`
+
+**Repository allocation:** the existing `radrootslabs/lib` and
+`radrootslabs/sdk` repositories remain independent. The first 17 packages are
+owned by `lib`; `radroots-sdk` and `radroots` are owned by `sdk`. No third Rust
+repository is created for release V1.
+
+**Registry context supplied by the project:** no Radroots crate is currently published on crates.io. Deleted experimental publications create no compatibility, pluralization, deprecation, or version-continuity requirement.
+
+## 1. Normative language and status
+
+The words **MUST**, **MUST NOT**, **SHOULD**, **SHOULD NOT**, and **MAY** are normative.
+
+This specification freezes the **package identities, ownership boundaries, naming model, dependency direction, and release gates** for the first durable Radroots crates.io release.
+
+It does not claim that the current source tree is already publishable. Publication remains blocked until the refactor is implemented and every acceptance gate in this document passes against packaged artifacts.
+
+## 2. Final executive decision
+
+Radroots SHALL publish exactly **19 durable package identities** for release V1:
+
+1. `radroots-core`
+2. `radroots-identity`
+3. `radroots-blossom`
+4. `radroots-protocol`
+5. `radroots-event`
+6. `radroots-event-codec`
+7. `radroots-trade`
+8. `radroots-signing`
+9. `radroots-transport`
+10. `radroots-nostr`
+11. `radroots-nostr-connect`
+12. `radroots-secrets`
+13. `radroots-storage`
+14. `radroots-storage-sqlite`
+15. `radroots-transport-nostr`
+16. `radroots-sync`
+17. `radroots-geonames`
+18. `radroots-sdk`
+19. `radroots`
+
+This is neither the current workspace publication list nor a collapse into `radroots-sdk`.
+
+The package family is implemented across the two existing standalone
+repositories. `radrootslabs/lib` owns packages 1-17, and `radrootslabs/sdk`
+owns packages 18-19. Cross-repository dependencies resolve through registry
+versions; neither repository depends on a sibling checkout.
+
+The architecture is a layered network/protocol stack:
+
+```text
+portable values / identity / protocol contracts
+ ↓
+event model and deterministic domain algorithms
+ ↓
+signing, transport, secrets, and storage SPIs
+ ↓
+concrete native backends and network adapters
+ ↓
+local-first synchronization engine
+ ↓
+advanced SDK
+ ↓
+ordinary-user façade
+```
+
+## 3. Final pressure-test changes from the directionally approved draft
+
+The final review makes the following deliberate changes:
+
+1. **`radroots-contracts` becomes `radroots-protocol`.** The package is a durable, versioned wire/operation protocol boundary rather than a general-purpose “contracts” bucket.
+2. **`radroots-store` and `radroots-store-sqlite` become `radroots-storage` and `radroots-storage-sqlite`.** “Storage” is unambiguous in an agricultural marketplace and describes the package family more accurately than “store.”
+3. **`radroots-nostr-connect` remains independent.** It is a bidirectional security protocol with URIs, permissions, client/server state, and independent SDK/Myc consumers. It is not merely a convenience NIP module.
+4. **Actor ownership is refined.** Public keys/accounts live in identity; event author roles live in the event contract model; actor provenance, authorization, and signer behavior live in signing.
+5. **Trade identity is made singular.** The conflicting `TradeId`/`OrderId` definitions MUST be replaced by one canonical protocol `TradeId` and a separately named business `OrderId`.
+6. **Public codegen features are removed.** `dto-bindgen`, binding generation, WASM wrappers, and fixture switches remain private build/test concerns.
+7. **The workspace moves to Cargo resolver 3.** A virtual Rust 2024 workspace MUST explicitly set `resolver = "3"`.
+8. **Release V1 uses MSRV 1.97.1.** The patch release is selected rather than 1.97.0 because it contains a compiler miscompilation fix.
+9. **Lower crates do not remain permanently lockstep.** All begin at `0.1.0`, but only `radroots` and `radroots-sdk` are an exact lockstep pair; lower packages follow independent SemVer after the first release.
+
+## 4. Non-negotiable architecture invariants
+
+1. Every public package MUST have a durable name and at least one named direct consumer besides `radroots`.
+2. Every dependency edge MUST point downward in the architecture.
+3. Domain and protocol packages MUST NOT depend on storage, networking, process lifecycle, or host UI.
+4. Generic SPIs MUST NOT expose concrete SQLite, Tokio, Reqwest, Nostr SDK, keyring, or OS-specific types.
+5. Adapters and backends MUST implement SPIs; SPIs MUST NOT depend on adapters or backends.
+6. Synchronization MUST orchestrate sources, sinks, signing, and storage without owning an executor or scheduler.
+7. `radroots-sdk` MUST compose lower packages and own client-level commit semantics; it MUST NOT become a dumping ground for code that has an independent durable boundary.
+8. `radroots` MUST provide meaningful curation and documentation; it MUST NOT be `pub use radroots_sdk::*`.
+9. Version generations MUST live in modules and schema IDs, never in package names.
+10. Preview implementation code MAY remain in the monorepo but MUST NOT appear in a published dependency or feature until registry-ready.
+11. No public package may have a normal, optional, build, or target-specific dependency on a private Radroots package.
+12. No first-party consumer may rely on production sibling paths after cutover.
+
+## 5. Final public package inventory
+
+### 5.1 Repository ownership
+
+- `https://github.com/radrootslabs/lib` owns `radroots-core` through
+ `radroots-geonames` (packages 1-17).
+- `https://github.com/radrootslabs/sdk` owns `radroots-sdk` and `radroots`
+ (packages 18-19).
+- Both repositories retain their existing histories and remain independently
+ buildable, testable, packageable, and releasable.
+- The two repositories carry synchronized copies of this release-family
+ contract. A coordinated release MUST reject any content-hash or package
+ allocation mismatch between those copies.
+
+| Order | Package | Rust crate path | Tier | Permanent responsibility |
+|---:|---|---|---|---|
+| 1 | `radroots-core` | `radroots_core` | foundation | Foundational value objects and deterministic invariants: decimal, currency, money, percentage, quantity, units, and pricing. |
+| 2 | `radroots-identity` | `radroots_identity` | foundation | Public identity and account value types: canonical public keys, identity IDs, account IDs, public profiles, and usernames. |
+| 3 | `radroots-blossom` | `radroots_blossom` | protocol primitive | Portable Blossom protocol primitives: canonical blob URLs, hashes, media descriptors, byte-verification typestates, and authorization claims. |
+| 4 | `radroots-protocol` | `radroots_protocol` | versioned wire contract | Versioned cross-process and cross-language schemas, capability catalogs, operation descriptors, stable error reports, schema IDs, and structural validation. |
+| 5 | `radroots-event` | `radroots_event` | domain protocol model | Canonical Radroots event-domain models, validated event identifiers, tags, event contracts, authoring drafts, signed/verified typestates, and NIP-01 wire-neutral representations. |
+| 6 | `radroots-event-codec` | `radroots_event_codec` | deterministic algorithm | Deterministic canonical encoding, decoding, ID/signature verification, contract validation, admission, and manifest generation for Radroots events. |
+| 7 | `radroots-trade` | `radroots_trade` | domain algorithm | Trade validation, evidence models, deterministic reduction, conflict analysis, and side-effect-free workflow plans over the canonical event trade model. |
+| 8 | `radroots-signing` | `radroots_signing` | host SPI | Object-safe author/signing SPI, actor provenance, authorization checks, requests, receipts, progress, capabilities, and normalized signing errors. |
+| 9 | `radroots-transport` | `radroots_transport` | network SPI | Transport-neutral target identities, capability/status models, source and sink SPIs, delivery/fetch policies, bounded requests, provenance, and normalized outcomes. |
+| 10 | `radroots-nostr` | `radroots_nostr` | protocol adapter | Portable conversion between Radroots native event/identity types and Nostr protocol types, typed NIP helpers, and concrete local signing adapters; no live relay client. |
+| 11 | `radroots-nostr-connect` | `radroots_nostr_connect` | security protocol | Nostr Connect/NIP-46 URIs, methods, permissions, requests, responses, client/server state machines, timeout-independent protocol validation, and normalized errors. |
+| 12 | `radroots-secrets` | `radroots_secrets` | security SPI | Secret references, provider and key-wrapping SPIs, versioned encrypted envelopes, zeroization-safe secret handling, and explicit memory/file/keyring adapters. |
+| 13 | `radroots-storage` | `radroots_storage` | storage SPI | Backend-neutral canonical event, operation journal, outbox, transport evidence, projection, private-artifact metadata, backup, status, and atomic commit interfaces, plus an in-memory reference backend. |
+| 14 | `radroots-storage-sqlite` | `radroots_storage_sqlite` | native storage backend | SQLite implementation of the storage SPIs with schema migration, WAL, locking, integrity, backup/restore, crash recovery, and encrypted private storage. |
+| 15 | `radroots-transport-nostr` | `radroots_transport_nostr` | native network adapter | Concrete Nostr EventSource/EventSink implementation: relay URL policy, connection, NIP-42 authentication, bounded fetch pages, delivery, status, and relay-outcome normalization. |
+| 16 | `radroots-sync` | `radroots_sync` | local-first orchestration | Shared pull, verification, canonical admission, duplicate handling, projection refresh, outbox signing/delivery, status, and retry-decision orchestration without owning scheduling. |
+| 17 | `radroots-geonames` | `radroots_geonames` | concrete data provider | GeoNames asset specification, authenticated/integrity-checked acquisition, database lifecycle, and forward/reverse locality lookup using provider-owned types. |
+| 18 | `radroots-sdk` | `radroots_sdk` | advanced front door | Host-neutral asynchronous client engine, product operations, capability reporting, explicit storage/signing/transport composition, diagnostics, backup/restore, and safe commit semantics. |
+| 19 | `radroots` | `radroots` | ordinary-user front door | Canonical Rust onboarding package with curated modules, safe defaults, stable convenience builders, domain aggregation, examples, and primary documentation. |
+
+## 6. Detailed package specifications
+
+ ### 1. `radroots-core`
+
+ **Rust crate path:** `radroots_core`
+ **Tier:** foundation
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc; std feature
+ **Direct intended consumers:** radroots-event, radroots-trade, radroots-sdk, radroots
+
+ **Normative responsibility.** Foundational value objects and deterministic invariants: decimal, currency, money, percentage, quantity, units, and pricing.
+
+ **Required Radroots dependencies:** None
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`
+ **Complete public feature vocabulary:** `std`, `serde`
+
+ **Public modules**
+
+ - `currency`
+- `decimal`
+- `money`
+- `percent`
+- `pricing`
+- `quantity`
+- `unit`
+
+ **Permitted root exports:** `Currency`, `Decimal`, `Money`, `Percent`, `Quantity`, `QuantityPrice`, `Unit`, `Error`
+
+ **Explicitly forbidden.** Identifiers, identities, event kinds, networking, persistence, clocks, filesystem paths, process behavior, or application configuration.
+
+
+ ### 2. `radroots-identity`
+
+ **Rust crate path:** `radroots_identity`
+ **Tier:** foundation
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc; std feature
+ **Direct intended consumers:** radroots-event, radroots-signing, radroots-transport, radroots-nostr, radroots-nostr-connect, radroots-sdk, services
+
+ **Normative responsibility.** Public identity and account value types: canonical public keys, identity IDs, account IDs, public profiles, and usernames.
+
+ **Required Radroots dependencies:** None
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`
+ **Complete public feature vocabulary:** `std`, `serde`
+
+ **Public modules**
+
+ - `account`
+- `key`
+- `profile`
+- `username`
+
+ **Permitted root exports:** `AccountId`, `IdentityId`, `PublicIdentity`, `PublicKey`, `Profile`, `Username`, `Error`
+
+ **Explicitly forbidden.** Secret keys, key generation, NIP-49 encryption, keyrings, files, SQLite, runtime paths, upstream nostr::Event values, signer sessions, or host account selection.
+
+
+ ### 3. `radroots-blossom`
+
+ **Rust crate path:** `radroots_blossom`
+ **Tier:** protocol primitive
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc; std feature
+ **Direct intended consumers:** radroots-event, radroots-event-codec, radroots-nostr, media clients
+
+ **Normative responsibility.** Portable Blossom protocol primitives: canonical blob URLs, hashes, media descriptors, byte-verification typestates, and authorization claims.
+
+ **Required Radroots dependencies:** None
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`
+ **Complete public feature vocabulary:** `std`, `serde`
+
+ **Public modules**
+
+ - `authorization`
+- `descriptor`
+- `hash`
+- `media_type`
+- `url`
+
+ **Permitted root exports:** `BlobUrl`, `Sha256`, `MediaType`, `BlobDescriptor`, `ByteVerifiedDescriptor`, `AuthorizationClaim`, `Error`
+
+ **Explicitly forbidden.** HTTP clients, upload scheduling, cache management, filesystem traversal, application media policy, or global authentication state.
+
+
+ ### 4. `radroots-protocol`
+
+ **Rust crate path:** `radroots_protocol`
+ **Tier:** versioned wire contract
+ **API maturity at first publish:** durable identity; independently versioned contract modules
+ **Platform contract:** no_std + alloc; std feature
+ **Direct intended consumers:** radroots-event, radroots-signing, radroots-transport, radroots-storage, radroots-sync, radroots-sdk, radrootsd, bindings
+
+ **Normative responsibility.** Versioned cross-process and cross-language schemas, capability catalogs, operation descriptors, stable error reports, schema IDs, and structural validation.
+
+ **Required Radroots dependencies:** None
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`
+ **Complete public feature vocabulary:** `std`, `serde`
+
+ **Public modules**
+
+ - `capability::v1`
+- `error::v1`
+- `event::v1`
+- `runtime::v1`
+- `radrootsd::transport_publish::v5`
+- `schema`
+
+ **Permitted root exports:** No broad root exports.
+
+ **Explicitly forbidden.** Native clients, storage, network I/O, executor/runtime ownership, domain reducers, upstream dependency types, unversioned serialized DTOs, or package names containing protocol generations.
+
+
+ ### 5. `radroots-event`
+
+ **Rust crate path:** `radroots_event`
+ **Tier:** domain protocol model
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc; std feature
+ **Direct intended consumers:** radroots-event-codec, radroots-trade, radroots-signing, radroots-transport, radroots-storage, radroots-sync, radroots-nostr, radroots-sdk, indexers
+
+ **Normative responsibility.** Canonical Radroots event-domain models, validated event identifiers, tags, event contracts, authoring drafts, signed/verified typestates, and NIP-01 wire-neutral representations.
+
+ **Required Radroots dependencies:** `radroots-core`, `radroots-identity`, `radroots-blossom`, `radroots-protocol`
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`
+ **Complete public feature vocabulary:** `std`, `serde`, `knowledge`
+
+ **Public modules**
+
+ - `admission`
+- `calendar`
+- `contract`
+- `draft`
+- `envelope`
+- `farm`
+- `food`
+- `id`
+- `knowledge`
+- `listing`
+- `media`
+- `post`
+- `profile`
+- `social`
+- `tag`
+- `trade`
+- `wire`
+
+ **Permitted root exports:** `Event`, `EventDraft`, `SignedEvent`, `VerifiedEvent`, `EventId`, `EventKind`, `EventTag`, `Error`
+
+ **Explicitly forbidden.** Live Nostr clients, relay pools, signing backends, SQLite, outbox claims, retry scheduling, application state, or duplicate trade/order identifier concepts.
+
+
+ ### 6. `radroots-event-codec`
+
+ **Rust crate path:** `radroots_event_codec`
+ **Tier:** deterministic algorithm
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc where selected features permit; std feature
+ **Direct intended consumers:** radroots-nostr, radroots-storage-sqlite, radroots-transport-nostr, radroots-sync, radroots-sdk, bindings
+
+ **Normative responsibility.** Deterministic canonical encoding, decoding, ID/signature verification, contract validation, admission, and manifest generation for Radroots events.
+
+ **Required Radroots dependencies:** `radroots-event`, `radroots-blossom`, `radroots-protocol`
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `json`
+ **Complete public feature vocabulary:** `std`, `serde`, `json`, `knowledge`, `manifests`
+
+ **Public modules**
+
+ - `admission`
+- `canonical`
+- `decode`
+- `encode`
+- `manifest`
+- `verify`
+
+ **Permitted root exports:** `Codec`, `DecodeError`, `EncodeError`, `VerificationError`
+
+ **Explicitly forbidden.** nostr-sdk clients, relay networking, persistence, background work, upstream client errors, or host configuration.
+
+
+ ### 7. `radroots-trade`
+
+ **Rust crate path:** `radroots_trade`
+ **Tier:** domain algorithm
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc for model/reducer; std feature
+ **Direct intended consumers:** radroots-storage, radroots-sync, radroots-sdk, RHI, applications
+
+ **Normative responsibility.** Trade validation, evidence models, deterministic reduction, conflict analysis, and side-effect-free workflow plans over the canonical event trade model.
+
+ **Required Radroots dependencies:** `radroots-core`, `radroots-identity`, `radroots-event`
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`, `json`
+ **Complete public feature vocabulary:** `std`, `serde`, `json`
+
+ **Public modules**
+
+ - `evidence`
+- `model`
+- `reducer`
+- `validation`
+- `workflow`
+
+ **Permitted root exports:** `Projection`, `ReductionInput`, `ReducerIssue`, `WorkflowPlan`, `ValidationError`, `Error`
+
+ **Explicitly forbidden.** A second TradeId definition, actor authorization, signers, event-store access, SQLx, filesystem state, transport delivery, outbox mutation, or process scheduling.
+
+
+ ### 8. `radroots-signing`
+
+ **Rust crate path:** `radroots_signing`
+ **Tier:** host SPI
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc core; std feature
+ **Direct intended consumers:** radroots-nostr, radroots-sync, radroots-sdk, CLI, Studio, FFI hosts
+
+ **Normative responsibility.** Object-safe author/signing SPI, actor provenance, authorization checks, requests, receipts, progress, capabilities, and normalized signing errors.
+
+ **Required Radroots dependencies:** `radroots-identity`, `radroots-event`, `radroots-protocol`
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`
+ **Complete public feature vocabulary:** `std`, `serde`
+
+ **Public modules**
+
+ - `actor`
+- `capability`
+- `error`
+- `request`
+- `receipt`
+- `signer`
+- `status`
+
+ **Permitted root exports:** `Actor`, `Signer`, `SignRequest`, `SignReceipt`, `SignerStatus`, `Error`
+
+ **Explicitly forbidden.** Raw secret-key ownership, keyrings, relay networking, NIP-46 session persistence, SQL, UI prompts, or executor creation.
+
+
+ ### 9. `radroots-transport`
+
+ **Rust crate path:** `radroots_transport`
+ **Tier:** network SPI
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc data model; std feature
+ **Direct intended consumers:** radroots-storage, radroots-transport-nostr, radroots-sync, radroots-sdk, services, future adapters
+
+ **Normative responsibility.** Transport-neutral target identities, capability/status models, source and sink SPIs, delivery/fetch policies, bounded requests, provenance, and normalized outcomes.
+
+ **Required Radroots dependencies:** `radroots-identity`, `radroots-event`, `radroots-protocol`
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`
+ **Complete public feature vocabulary:** `std`, `serde`
+
+ **Public modules**
+
+ - `capability`
+- `endpoint`
+- `error`
+- `outcome`
+- `policy`
+- `sink`
+- `source`
+- `target`
+
+ **Permitted root exports:** `TransportId`, `Target`, `TargetSet`, `EventSource`, `EventSink`, `DeliveryRequest`, `DeliveryReceipt`, `FetchRequest`, `FetchPage`, `Error`
+
+ **Explicitly forbidden.** Closed enums that prevent new transports, Reticulum-specific constants, Nostr URLs at the generic root, storage/outbox access, retries, scheduler ownership, or silent fallback.
+
+
+ ### 10. `radroots-nostr`
+
+ **Rust crate path:** `radroots_nostr`
+ **Tier:** protocol adapter
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc for conversion surface; std feature
+ **Direct intended consumers:** radroots-nostr-connect, radroots-transport-nostr, radroots-sdk, Myc, radrootsd
+
+ **Normative responsibility.** Portable conversion between Radroots native event/identity types and Nostr protocol types, typed NIP helpers, and concrete local signing adapters; no live relay client.
+
+ **Required Radroots dependencies:** `radroots-identity`, `radroots-event`, `radroots-event-codec`
+ **Optional Radroots dependencies:** `radroots-signing`, `radroots-blossom`
+ **Default features:** `std`, `events`
+ **Complete public feature vocabulary:** `std`, `events`, `signing`, `nip17`, `blossom`
+
+ **Public modules**
+
+ - `blossom`
+- `event`
+- `filter`
+- `key`
+- `nip17`
+- `signing`
+- `tag`
+
+ **Permitted root exports:** `Error`
+
+ **Explicitly forbidden.** nostr-sdk relay pools, reqwest clients, runtime ownership, broad aliases of upstream nostr types at the root, account persistence, or outbox orchestration.
+
+
+ ### 11. `radroots-nostr-connect`
+
+ **Rust crate path:** `radroots_nostr_connect`
+ **Tier:** security protocol
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** std for v1; protocol data kept portable
+ **Direct intended consumers:** radroots-sdk, Myc, remote signer tooling
+
+ **Normative responsibility.** Nostr Connect/NIP-46 URIs, methods, permissions, requests, responses, client/server state machines, timeout-independent protocol validation, and normalized errors.
+
+ **Required Radroots dependencies:** `radroots-identity`, `radroots-event`, `radroots-nostr`, `radroots-protocol`
+ **Optional Radroots dependencies:** None
+ **Default features:** `serde`
+ **Complete public feature vocabulary:** `serde`
+
+ **Public modules**
+
+ - `client`
+- `error`
+- `message`
+- `method`
+- `permission`
+- `server`
+- `uri`
+
+ **Permitted root exports:** `Client`, `Server`, `Method`, `Permission`, `Request`, `Response`, `BunkerUri`, `ClientUri`, `Error`
+
+ **Explicitly forbidden.** Relay-pool implementation, secret persistence, approval UI, global sessions, Tokio runtime ownership, or Myc-specific service storage.
+
+
+ ### 12. `radroots-secrets`
+
+ **Rust crate path:** `radroots_secrets`
+ **Tier:** security SPI
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** no_std + alloc core; std adapters
+ **Direct intended consumers:** radroots-storage-sqlite, radroots-sdk, signing hosts, services
+
+ **Normative responsibility.** Secret references, provider and key-wrapping SPIs, versioned encrypted envelopes, zeroization-safe secret handling, and explicit memory/file/keyring adapters.
+
+ **Required Radroots dependencies:** None
+ **Optional Radroots dependencies:** None
+ **Default features:** `std`, `serde`
+ **Complete public feature vocabulary:** `std`, `serde`, `memory`, `file`, `keyring`
+
+ **Public modules**
+
+ - `envelope`
+- `error`
+- `id`
+- `provider`
+- `wrapping`
+- `memory`
+- `file`
+- `keyring`
+
+ **Permitted root exports:** `SecretId`, `SecretRef`, `SecretProvider`, `KeyWrapping`, `EncryptedEnvelope`, `Error`
+
+ **Explicitly forbidden.** Public secret bytes, Clone/Debug/Serialize for secret-bearing values, identity profiles, domain tables, arbitrary key/value storage, hidden key generation, or process-global vaults.
+
+
+ ### 13. `radroots-storage`
+
+ **Rust crate path:** `radroots_storage`
+ **Tier:** storage SPI
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** std for v1
+ **Direct intended consumers:** radroots-storage-sqlite, radroots-sync, radroots-sdk, indexers, tests, future backends
+
+ **Normative responsibility.** Backend-neutral canonical event, operation journal, outbox, transport evidence, projection, private-artifact metadata, backup, status, and atomic commit interfaces, plus an in-memory reference backend.
+
+ **Required Radroots dependencies:** `radroots-event`, `radroots-trade`, `radroots-transport`, `radroots-protocol`
+ **Optional Radroots dependencies:** None
+ **Default features:** `memory`, `serde`
+ **Complete public feature vocabulary:** `memory`, `serde`
+
+ **Public modules**
+
+ - `atomic`
+- `backup`
+- `event`
+- `journal`
+- `memory`
+- `outbox`
+- `private_artifact`
+- `projection`
+- `status`
+
+ **Permitted root exports:** `Storage`, `EventStore`, `Journal`, `Outbox`, `ProjectionStore`, `BackupSource`, `StorageStatus`, `Error`
+
+ **Explicitly forbidden.** SQL text, SQLx pools or transactions, filesystem paths, application UI state, concrete retry loops, Nostr clients, or unconstrained raw key/value escape hatches.
+
+
+ ### 14. `radroots-storage-sqlite`
+
+ **Rust crate path:** `radroots_storage_sqlite`
+ **Tier:** native storage backend
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** std-only native backend
+ **Direct intended consumers:** radroots-sdk, CLI, Studio, mobile/FFI
+
+ **Normative responsibility.** SQLite implementation of the storage SPIs with schema migration, WAL, locking, integrity, backup/restore, crash recovery, and encrypted private storage.
+
+ **Required Radroots dependencies:** `radroots-storage`, `radroots-event-codec`, `radroots-secrets`
+ **Optional Radroots dependencies:** None
+ **Default features:** None
+ **Complete public feature vocabulary:** None
+
+ **Public modules**
+
+ - `backup`
+- `config`
+- `integrity`
+- `lock`
+- `migration`
+- `open`
+- `status`
+
+ **Permitted root exports:** `SqliteStorage`, `OpenOptions`, `OpenMode`, `Paths`, `Error`
+
+ **Explicitly forbidden.** Public SqlitePool/Connection/Transaction handles, caller-supplied arbitrary SQL, Studio state, global connection pools, runtime installation, or silent schema downgrade.
+
+
+ ### 15. `radroots-transport-nostr`
+
+ **Rust crate path:** `radroots_transport_nostr`
+ **Tier:** native network adapter
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** std-only; Tokio implementation detail in v1
+ **Direct intended consumers:** radroots-sdk, CLI, radrootsd, advanced hosts
+
+ **Normative responsibility.** Concrete Nostr EventSource/EventSink implementation: relay URL policy, connection, NIP-42 authentication, bounded fetch pages, delivery, status, and relay-outcome normalization.
+
+ **Required Radroots dependencies:** `radroots-transport`, `radroots-nostr`, `radroots-event-codec`, `radroots-protocol`
+ **Optional Radroots dependencies:** None
+ **Default features:** None
+ **Complete public feature vocabulary:** None
+
+ **Public modules**
+
+ - `auth`
+- `client`
+- `relay`
+- `sink`
+- `source`
+- `status`
+
+ **Permitted root exports:** `NostrTransport`, `Config`, `RelayUrl`, `RelayUrlPolicy`, `Error`
+
+ **Explicitly forbidden.** Event-store ingestion, outbox claiming, retry scheduling, projection refresh, global relay clients, direct SQL, or transport fallback.
+
+
+ ### 16. `radroots-sync`
+
+ **Rust crate path:** `radroots_sync`
+ **Tier:** local-first orchestration
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** std-only in v1; executor-neutral public API
+ **Direct intended consumers:** radroots-sdk, CLI, Studio, mobile/FFI, advanced hosts
+
+ **Normative responsibility.** Shared pull, verification, canonical admission, duplicate handling, projection refresh, outbox signing/delivery, status, and retry-decision orchestration without owning scheduling.
+
+ **Required Radroots dependencies:** `radroots-event`, `radroots-event-codec`, `radroots-signing`, `radroots-transport`, `radroots-storage`, `radroots-trade`, `radroots-protocol`
+ **Optional Radroots dependencies:** None
+ **Default features:** `serde`
+ **Complete public feature vocabulary:** `serde`
+
+ **Public modules**
+
+ - `ingest`
+- `policy`
+- `projection`
+- `pull`
+- `push`
+- `status`
+
+ **Permitted root exports:** `Engine`, `PullRequest`, `PullReceipt`, `PushRequest`, `PushReceipt`, `SyncStatus`, `Error`
+
+ **Explicitly forbidden.** Creating an executor, spawning hidden workers, installing timers globally, owning process lifecycle, storing UI state, or transport-specific branches outside adapters.
+
+
+ ### 17. `radroots-geonames`
+
+ **Rust crate path:** `radroots_geonames`
+ **Tier:** concrete data provider
+ **API maturity at first publish:** durable identity; pre-1.0 API
+ **Platform contract:** std-only
+ **Direct intended consumers:** radroots-sdk, CLI, geocoding applications
+
+ **Normative responsibility.** GeoNames asset specification, authenticated/integrity-checked acquisition, database lifecycle, and forward/reverse locality lookup using provider-owned types.
+
+ **Required Radroots dependencies:** None
+ **Optional Radroots dependencies:** None
+ **Default features:** None
+ **Complete public feature vocabulary:** None
+
+ **Public modules**
+
+ - `asset`
+- `database`
+- `download`
+- `model`
+- `query`
+
+ **Permitted root exports:** `Geocoder`, `AssetSpec`, `AssetStatus`, `Query`, `Candidate`, `Point`, `Error`
+
+ **Explicitly forbidden.** Generic multi-provider abstraction before a second provider exists, runtime-path policy, hidden downloads, SDK configuration types, SQLx/reqwest types in the public API, or test-fixture features.
+
+
+ ### 18. `radroots-sdk`
+
+ **Rust crate path:** `radroots_sdk`
+ **Tier:** advanced front door
+ **API maturity at first publish:** durable identity; lockstep pre-1.0 API with radroots
+ **Platform contract:** std-only native engine
+ **Direct intended consumers:** CLI, Studio, FFI/mobile, advanced native applications
+
+ **Normative responsibility.** Host-neutral asynchronous client engine, product operations, capability reporting, explicit storage/signing/transport composition, diagnostics, backup/restore, and safe commit semantics.
+
+ **Required Radroots dependencies:** `radroots-core`, `radroots-identity`, `radroots-protocol`, `radroots-event`, `radroots-event-codec`, `radroots-trade`, `radroots-signing`, `radroots-transport`, `radroots-storage`
+ **Optional Radroots dependencies:** `radroots-secrets`, `radroots-storage-sqlite`, `radroots-nostr`, `radroots-nostr-connect`, `radroots-transport-nostr`, `radroots-sync`, `radroots-geonames`
+ **Default features:** `memory`
+ **Complete public feature vocabulary:** `memory`, `sqlite`, `sync`, `nostr`, `nip46`, `local-signing`, `radrootsd`, `geonames`, `knowledge`, `native`, `full`
+
+ **Public modules**
+
+ - `capability`
+- `client`
+- `diagnostics`
+- `error`
+- `farm`
+- `listing`
+- `signing`
+- `storage`
+- `sync`
+- `trade`
+- `transport`
+
+ **Permitted root exports:** `Client`, `ClientBuilder`, `Error`, `Result`
+
+ **Explicitly forbidden.** Global runtimes or subscribers, hidden workers, process signals, CLI parsing, UI state, Studio databases, raw SQLx/upstream client types, broad wildcard reexports, or a nominal no_std claim.
+
+
+ ### 19. `radroots`
+
+ **Rust crate path:** `radroots`
+ **Tier:** ordinary-user front door
+ **API maturity at first publish:** durable identity; lockstep pre-1.0 API with radroots-sdk
+ **Platform contract:** std-only
+ **Direct intended consumers:** ordinary Rust applications, examples, documentation
+
+ **Normative responsibility.** Canonical Rust onboarding package with curated modules, safe defaults, stable convenience builders, domain aggregation, examples, and primary documentation.
+
+ **Required Radroots dependencies:** `radroots-sdk`, `radroots-core`, `radroots-identity`, `radroots-event`, `radroots-trade`, `radroots-transport`
+ **Optional Radroots dependencies:** None
+ **Default features:** `client`
+ **Complete public feature vocabulary:** `client`, `native`, `nostr`, `nip46`, `radrootsd`, `geonames`, `knowledge`, `full`
+
+ **Public modules**
+
+ - `client`
+- `event`
+- `farm`
+- `identity`
+- `knowledge`
+- `listing`
+- `signing`
+- `storage`
+- `sync`
+- `trade`
+- `transport`
+
+ **Permitted root exports:** `Client`, `ClientBuilder`, `Error`, `Result`
+
+ **Explicitly forbidden.** A public radroots::sdk namespace, wildcard reexport of radroots-sdk, duplicate engine implementation, CLI binary, hidden network/filesystem/keychain side effects, or exposure of every lower-crate symbol.
+
+
+## 7. Normative dependency graph
+
+### 7.1 Direct Radroots edges
+
+| Dependency | Dependent | Edge |
+|---|---|---|
+| `radroots-blossom` | `radroots-event` | required |
+| `radroots-core` | `radroots-event` | required |
+| `radroots-identity` | `radroots-event` | required |
+| `radroots-protocol` | `radroots-event` | required |
+| `radroots-blossom` | `radroots-event-codec` | required |
+| `radroots-event` | `radroots-event-codec` | required |
+| `radroots-protocol` | `radroots-event-codec` | required |
+| `radroots-core` | `radroots-trade` | required |
+| `radroots-event` | `radroots-trade` | required |
+| `radroots-identity` | `radroots-trade` | required |
+| `radroots-event` | `radroots-signing` | required |
+| `radroots-identity` | `radroots-signing` | required |
+| `radroots-protocol` | `radroots-signing` | required |
+| `radroots-event` | `radroots-transport` | required |
+| `radroots-identity` | `radroots-transport` | required |
+| `radroots-protocol` | `radroots-transport` | required |
+| `radroots-blossom` | `radroots-nostr` | optional |
+| `radroots-signing` | `radroots-nostr` | optional |
+| `radroots-event` | `radroots-nostr` | required |
+| `radroots-event-codec` | `radroots-nostr` | required |
+| `radroots-identity` | `radroots-nostr` | required |
+| `radroots-event` | `radroots-nostr-connect` | required |
+| `radroots-identity` | `radroots-nostr-connect` | required |
+| `radroots-nostr` | `radroots-nostr-connect` | required |
+| `radroots-protocol` | `radroots-nostr-connect` | required |
+| `radroots-event` | `radroots-storage` | required |
+| `radroots-protocol` | `radroots-storage` | required |
+| `radroots-trade` | `radroots-storage` | required |
+| `radroots-transport` | `radroots-storage` | required |
+| `radroots-event-codec` | `radroots-storage-sqlite` | required |
+| `radroots-secrets` | `radroots-storage-sqlite` | required |
+| `radroots-storage` | `radroots-storage-sqlite` | required |
+| `radroots-event-codec` | `radroots-transport-nostr` | required |
+| `radroots-nostr` | `radroots-transport-nostr` | required |
+| `radroots-protocol` | `radroots-transport-nostr` | required |
+| `radroots-transport` | `radroots-transport-nostr` | required |
+| `radroots-event` | `radroots-sync` | required |
+| `radroots-event-codec` | `radroots-sync` | required |
+| `radroots-protocol` | `radroots-sync` | required |
+| `radroots-signing` | `radroots-sync` | required |
+| `radroots-storage` | `radroots-sync` | required |
+| `radroots-trade` | `radroots-sync` | required |
+| `radroots-transport` | `radroots-sync` | required |
+| `radroots-geonames` | `radroots-sdk` | optional |
+| `radroots-nostr` | `radroots-sdk` | optional |
+| `radroots-nostr-connect` | `radroots-sdk` | optional |
+| `radroots-secrets` | `radroots-sdk` | optional |
+| `radroots-storage-sqlite` | `radroots-sdk` | optional |
+| `radroots-sync` | `radroots-sdk` | optional |
+| `radroots-transport-nostr` | `radroots-sdk` | optional |
+| `radroots-core` | `radroots-sdk` | required |
+| `radroots-event` | `radroots-sdk` | required |
+| `radroots-event-codec` | `radroots-sdk` | required |
+| `radroots-identity` | `radroots-sdk` | required |
+| `radroots-protocol` | `radroots-sdk` | required |
+| `radroots-signing` | `radroots-sdk` | required |
+| `radroots-storage` | `radroots-sdk` | required |
+| `radroots-trade` | `radroots-sdk` | required |
+| `radroots-transport` | `radroots-sdk` | required |
+| `radroots-core` | `radroots` | required |
+| `radroots-event` | `radroots` | required |
+| `radroots-identity` | `radroots` | required |
+| `radroots-sdk` | `radroots` | required |
+| `radroots-trade` | `radroots` | required |
+| `radroots-transport` | `radroots` | required |
+
+### 7.2 Architectural graph
+
+```text
+radroots-core radroots-identity radroots-blossom
+ \ | /
+ \ | /
+ +---------- radroots-protocol --------+
+ |
+ radroots-event
+ / | \
+ / | \
+ radroots-event-codec | radroots-trade
+ |
+ +----------+-----------+
+ | | |
+ radroots-signing radroots-transport radroots-storage
+ | | |
+ | radroots-nostr +--> radroots-storage-sqlite
+ | |
+ | radroots-nostr-connect
+ | |
+ +---- radroots-transport-nostr
+ |
+ radroots-sync
+
+radroots-geonames -------------------------+
+ |
+all selected lower packages ----------> radroots-sdk ---> radroots
+```
+
+This diagram is explanatory. The release tool MUST use Cargo-resolved metadata as authority.
+
+## 8. Type ownership and canonical paths
+
+| Concept | Canonical owning crate | Rule |
+|---|---|---|
+| Decimal, money, quantity, unit, pricing | `radroots-core` | No duplicate wrapper in SDK or trade. |
+| Public key, identity ID, account ID, username | `radroots-identity` | Secret material is forbidden here. |
+| Event ID, event signature, coordinate, D-tag, event kind | `radroots-event` | Store bytes/newtypes, not unvalidated Strings. |
+| Event contract author role | `radroots-event::contract` | This is an event-authoring rule, not an account property. |
+| Actor provenance and author context | `radroots-signing` | Combines identity with event author roles at the signing boundary. |
+| Canonical protocol TradeId/CandidateId/MutationId | `radroots-event::trade` | Exactly one definition. |
+| Human/business OrderId | `radroots-trade` | MUST NOT be aliased or wrapped as TradeId. |
+| Runtime/wire DTO generations | `radroots-protocol` | Native packages convert at boundaries. |
+| Secret references and encrypted envelopes | `radroots-secrets` | No domain-specific tables. |
+| Transport ID, target, capability, outcome | `radroots-transport` | TransportId is extensible, not a closed enum. |
+| Native event/outbox/journal/projection storage | `radroots-storage` | Backend-neutral interfaces only. |
+| SQLite schema and connection behavior | `radroots-storage-sqlite` | SQLx remains private. |
+| Relay URL and Nostr network status | `radroots-transport-nostr` | Protocol conversions remain in `radroots-nostr`. |
+| Pull/push/ingest/projection orchestration | `radroots-sync` | No host scheduling. |
+| Client-level requests, plans, receipts, diagnostics | `radroots-sdk` | Use lower canonical types rather than duplicate wrappers. |
+
+## 9. Rust API and naming law
+
+### 9.1 Packages, crates, modules, and types
+
+- Cargo package names MUST be lowercase and hyphenated: `radroots-event-codec`.
+- Rust crate paths MUST be snake case: `radroots_event_codec`.
+- Modules MUST use singular snake-case nouns unless the concept is inherently plural.
+- Types and traits MUST use `UpperCamelCase`; functions and methods MUST use `snake_case`.
+- Items MUST NOT repeat their crate or module name:
+ - `radroots_core::Money`, not `RadrootsCoreMoney`.
+ - `radroots_sdk::Error`, not `RadrootsSdkError`.
+ - `radroots_transport::Target`, not `RadrootsTransportTarget`.
+- Protocol schema IDs retain the `radroots.*` namespace.
+- Generated Swift/Kotlin types MAY retain a `Radroots` prefix where the target language lacks module-level namespacing.
+
+### 9.2 Public surface discipline
+
+- Crate roots MUST be small.
+- Wildcard reexports and `pub use models::*` are forbidden.
+- Lower crates MUST NOT publish a broad `prelude` in V1.
+- Every native public struct MUST have private fields unless it is an intentionally passive versioned DTO in `radroots-protocol`.
+- Evolvable enums and reports SHOULD be `#[non_exhaustive]`.
+- Semantic IDs MUST NOT implement `Deref<Target = str>`.
+- IDs SHOULD store canonical bytes or validated compact representations; string encoding belongs at boundaries.
+- Use `FromStr`, `TryFrom`, `AsRef`, `Display`, and explicit `into_string`/`to_hex` methods.
+- No root-level aliases to upstream `nostr`, `nostr_sdk`, `sqlx`, `reqwest`, `tokio`, or keyring types.
+- Public functions MUST NOT panic for untrusted input.
+- Builders/plans/receipts SHOULD be `#[must_use]`.
+- Constructors with more than three independent options SHOULD use builders or option structs.
+- Empty request structs are forbidden when an idiomatic no-argument method conveys the same operation.
+
+### 9.3 Trait classification
+
+Every public trait MUST be marked in documentation as one of:
+
+1. **Host SPI** — downstream implementation is supported.
+2. **Sealed extension** — downstream calls are supported; implementation is not.
+3. **Internal** — not public.
+
+Host SPIs MUST:
+
+- be dyn-compatible where runtime injection is needed;
+- be `Send + Sync` for the native SDK;
+- return boxed futures or equivalent dyn-compatible futures;
+- define cancellation and deadline behavior;
+- define error normalization;
+- avoid associated types that leak backend implementations;
+- not expose private or third-party implementation types.
+
+The Rust SPI is native. Browser and generated-language transports use `radroots-protocol` DTOs and language-native interfaces rather than weakening native `Send + Sync` guarantees.
+
+## 10. Feature law
+
+1. Features MUST be additive and safe under unification.
+2. Features MUST describe user-visible capabilities, not implementation assembly.
+3. Optional dependencies MUST be referenced with `dep:` so implementation names do not become accidental features.
+4. Default features MUST remain safe for the life of a compatible release line.
+5. Enabling a feature MUST NOT itself:
+ - access a network;
+ - create files;
+ - read a keyring;
+ - generate keys;
+ - contact a daemon;
+ - install logging;
+ - start workers.
+6. Mutually exclusive backend features are forbidden; incompatible backends belong in separate packages.
+7. Public crates MUST NOT expose `dto-bindgen`, fixtures, coverage, codegen, migration-forge, or internal runtime features.
+8. `std` is the only valid feature name for standard-library support.
+9. Public feature removal is a breaking change.
+10. `--all-features` MUST build on every declared target for which the package claims support.
+
+### 10.1 `radroots-sdk`
+
+```toml
+[features]
+default = ["memory"]
+
+# Safe, in-process storage; no files or network.
+memory = ["radroots-storage/memory"]
+
+# Explicit native capabilities.
+sqlite = ["dep:radroots-storage-sqlite"]
+sync = ["dep:radroots-sync"]
+nostr = [
+ "sync",
+ "dep:radroots-nostr",
+ "dep:radroots-transport-nostr",
+]
+nip46 = [
+ "nostr",
+ "dep:radroots-nostr-connect",
+]
+local-signing = [
+ "dep:radroots-secrets",
+ "radroots-nostr/signing",
+]
+radrootsd = [
+ "sync",
+ "dep:reqwest",
+]
+geonames = ["dep:radroots-geonames"]
+knowledge = [
+ "radroots-event/knowledge",
+ "radroots-event-codec/knowledge",
+]
+
+native = ["sqlite", "sync", "local-signing"]
+full = [
+ "native",
+ "nostr",
+ "nip46",
+ "radrootsd",
+ "geonames",
+ "knowledge",
+]
+```
+
+### 10.2 `radroots`
+
+```toml
+[features]
+default = ["client"]
+
+client = ["radroots-sdk/default"]
+native = ["client", "radroots-sdk/native"]
+nostr = ["client", "radroots-sdk/nostr"]
+nip46 = ["nostr", "radroots-sdk/nip46"]
+radrootsd = ["client", "radroots-sdk/radrootsd"]
+geonames = ["client", "radroots-sdk/geonames"]
+knowledge = ["client", "radroots-sdk/knowledge"]
+full = ["radroots-sdk/full"]
+```
+
+Reticulum, mesh, Simplex, NostrDB, replica, and SP1 feature names MUST NOT appear in published V1 manifests.
+
+## 11. Network and transport SPI
+
+### 11.1 Separate source and sink contracts
+
+One monolithic transport trait is rejected. The final SPI provides independent contracts:
+
+```rust
+pub trait EventSource: Send + Sync {
+ fn status(&self) -> BoxFuture<'_, Result<SourceStatus, Error>>;
+ fn fetch(&self, request: FetchRequest)
+ -> BoxFuture<'_, Result<FetchPage, Error>>;
+}
+
+pub trait EventSink: Send + Sync {
+ fn status(&self) -> BoxFuture<'_, Result<SinkStatus, Error>>;
+ fn deliver(&self, request: DeliveryRequest)
+ -> BoxFuture<'_, Result<DeliveryReceipt, Error>>;
+}
+```
+
+A transport MAY implement either or both.
+
+### 11.2 Extensible transport identity
+
+`TransportId` MUST be a validated newtype with built-in constants such as `NOSTR`, `RETICULUM`, `LOCAL`, and `RADROOTSD`. It MUST NOT be a closed enum that forces a breaking release for every new transport.
+
+### 11.3 Bounded and explicit operation semantics
+
+- Fetch is paginated or streaming and always bounded.
+- Every request carries an operation/request ID.
+- Deadlines are explicit; no adapter owns a global timeout.
+- Delivery satisfaction policy is explicit.
+- Partial success is represented per target.
+- Retryability is data, not an implicit loop.
+- Authentication challenges are explicit outcomes.
+- No transport silently falls back to another.
+- Provenance records source, endpoint fingerprint, observed time, and adapter.
+- Adapter errors are normalized while preserving a non-secret source chain.
+- Target URIs and relay URLs are validated before connection.
+- SSRF-sensitive schemes and private-network policies are explicit.
+- TLS verification is enabled by default and cannot be silently disabled.
+- Payload, target, tag, response, and page limits are constants covered by tests.
+
+## 12. Storage architecture
+
+### 12.1 Logical ownership
+
+`radroots-storage` owns interfaces for:
+
+- canonical event admission and queries;
+- operation journal;
+- outbox and delivery evidence;
+- projection checkpoints and invalidation;
+- private-artifact metadata;
+- backup/restore contracts;
+- storage status and integrity;
+- atomic workflow commits.
+
+`radroots-storage-sqlite` implements them.
+
+### 12.2 Native layout
+
+The SQLite V1 layout SHALL use:
+
+```text
+runtime.sqlite
+ canonical event source
+ event admission/visibility
+ operation journal
+ outbox and delivery evidence
+ projection metadata and checkpoints
+
+private.sqlite
+ encrypted signing references
+ private farm coordinates
+ private trade artifacts
+ NIP-46 private session material where host policy permits
+
+host-owned databases
+ UI preferences
+ Studio state
+ application presentation caches
+```
+
+`studio.sqlite` is removed from the SDK.
+
+### 12.3 Correctness requirements
+
+- One runtime database permits atomic event/journal/outbox transitions.
+- Cross-database workflows use explicit staged commits and recovery markers.
+- Public API exposes high-level atomic operations, not raw SQL transactions.
+- No public `pool()` escape hatch.
+- Open modes: read-only, read-write-existing, create.
+- Explicit asynchronous `close()` and shutdown status.
+- Advisory/process locking is mandatory for writable file stores.
+- Concurrent readers are supported; writer policy is explicit.
+- Migrations are transactional and forward-only by default.
+- Downgrade requires an explicit offline export/import path.
+- WAL and busy timeout are configured and reported.
+- Backup uses a versioned manifest, per-member hashes, path/symlink validation, and atomic finalization.
+- Restore uses staging, verification, and atomic replacement.
+- Crash/failure injection covers every durable commit point.
+- Secret material inclusion in backup is explicit and policy-controlled.
+
+## 13. Identity, signing, and secret boundaries
+
+### 13.1 Identity
+
+`radroots-identity` contains no private key and no upstream Nostr event object. `PublicKey` is a validated canonical Radroots author key. NIP-19/npub conversion lives in `radroots-nostr`.
+
+### 13.2 Signing
+
+`radroots-signing::Signer` signs a frozen canonical `EventDraft`. The signing layer:
+
+- authorizes actor role and expected public key before invoking a signer;
+- verifies the signer result matches the exact draft;
+- supports local and remote implementations;
+- exposes capability and progress data;
+- defines cancellation before and after remote request publication;
+- never logs or serializes private material.
+
+Concrete local Nostr signing lives in `radroots-nostr`; NIP-46 protocol state lives in `radroots-nostr-connect`; host composition lives in `radroots-sdk`.
+
+### 13.3 Secrets
+
+Secret-bearing values:
+
+- MUST NOT implement ordinary `Debug`;
+- MUST NOT implement `Serialize`;
+- MUST NOT implement `Clone` unless the clone is a reference/handle;
+- MUST zeroize owned plaintext where technically possible;
+- MUST expose only redacted diagnostics;
+- MUST use typed `SecretRef` handles across storage boundaries.
+
+## 14. Event and trade model corrections
+
+1. `radroots-event` remains the canonical owner of event-bound identifiers and trade wire identities.
+2. `radroots-trade` MUST delete its conflicting `TradeId(OrderId)` definition.
+3. `TradeId` and `OrderId` MUST remain semantically distinct.
+4. `radroots-trade` consumes canonical event trade models and owns reducers, evidence, validation, and workflow plans.
+5. Trade MUST NOT depend on authority, storage, SQLx, Nostr clients, or transports.
+6. Event codec MUST own wire conversion; trade reducers operate on validated native inputs.
+7. Typed authoring policy MUST reject reserved event kinds before any signer is consulted.
+8. Native event typestates distinguish raw, ID-verified, signature-verified, contract-validated, admitted, and visible events.
+
+## 15. Error model
+
+Each crate owns a native `Error` with preserved sources. `radroots-protocol::error::v1::ErrorReport` is the serialized boundary.
+
+One generated authority MUST define:
+
+- stable code;
+- class;
+- retryability;
+- recovery actions;
+- capability ID;
+- operation ID;
+- safe structured details;
+- redaction behavior.
+
+Hand-maintained duplicate match tables and a separate unsynchronized catalog are forbidden.
+
+Third-party errors MUST NOT appear as public variants. Sensitive source messages MUST be redacted before entering a protocol report or tracing field.
+
+## 16. SDK and façade rules
+
+### 16.1 `radroots-sdk`
+
+- `Client` is `Clone + Send + Sync`.
+- The host owns the executor and scheduling.
+- The SDK starts no unbounded or hidden worker.
+- Background processing requires an explicit returned worker/driver handle.
+- Dropping a future before/after commit has documented effects.
+- `Client::close()` is explicit and asynchronous where storage is active.
+- Product writes retain prepare → authorize/sign → durable enqueue → optional deliver semantics.
+- Lower canonical types are reused rather than copied into `Sdk*` wrappers.
+- No `RadrootsSdk*` prefixes inside the crate.
+- Root exports are only `Client`, `ClientBuilder`, `Error`, and `Result`.
+
+### 16.2 `radroots`
+
+- Primary documentation and examples use `radroots`.
+- The façade adds curated modules, convenience constructors, safe defaults, and domain aggregation.
+- Advanced hosts use `radroots-sdk` directly.
+- There is no `radroots::sdk` public namespace.
+- The façade does not expose implementation crates accidentally.
+
+## 17. Public code generation and cross-language policy
+
+- Rust binding, WASM, UniFFI, Swift, Kotlin, TypeScript, and codegen crates remain `publish = false`.
+- Public runtime crates have no codegen feature or codegen dependency.
+- Versioned language DTOs derive from `radroots-protocol`.
+- Deterministic event algorithms derive from `radroots-event-codec`.
+- Generated artifacts are checked in or generated reproducibly and carry source hashes.
+- Rust native module structure is not mechanically mirrored into other languages.
+- Language runtimes own networking, scheduling, keychain prompts, and UI lifecycle where appropriate.
+
+## 18. Private and deferred packages
+
+The following remain private in release V1:
+
+```text
+replica schema/store/sync family
+Reticulum adapter
+mesh protocol/agent/client family
+SimpleX protocol/crypto/store/runtime family
+NostrDB adapter
+SP1 guest/host
+runtime paths/manager/distribution helpers
+radrootsd SDK adapter implementation
+FFI, binding, WASM, and generated-package build crates
+fixtures, conformance runners, fuzz targets, and xtask
+```
+
+Private preview code remains tested. It may become public only after passing the new-package admission rule.
+
+## 19. New-package admission rule
+
+After release V1, a new `radroots-*` package requires an ADR proving:
+
+1. a durable domain/protocol/SPI/backend boundary;
+2. at least two meaningful direct consumers, or one unavoidable platform/backend isolation boundary;
+3. an independently supportable SemVer surface;
+4. a publishable resolved dependency closure;
+5. a name expected to survive five years;
+6. why a module or feature is insufficient;
+7. documentation, conformance tests, ownership, security review, and release automation.
+
+Names containing `common`, `utils`, `types`, `models`, `preview`, `unstable`, `v1`, `v2`, `manager`, or a second `core` are presumptively rejected.
+
+## 20. Current-to-target migration map
+
+| Current package/family | Final owner | Required action |
+|---|---|---|
+| `radroots_core` | `radroots-core` | Retain and rename package with hyphens; remove RadrootsCore type prefixes. |
+| `radroots_identity` | `radroots-identity + radroots-signing + radroots-secrets + radroots-storage` | Keep only public identity/account concepts in identity; move secrets, signers, and persistence. |
+| `radroots_blossom` | `radroots-blossom` | Retain portable protocol primitives. |
+| `radroots_protocol_contract_v1` | `radroots-protocol::event::v1 / capability::v1` | Merge; generation becomes a module, never a package suffix. |
+| `radroots_runtime_contract_v1` | `radroots-protocol::runtime::v1` | Merge; generation becomes a module. |
+| `radroots_transport_publish_protocol` | `radroots-protocol::radrootsd::transport_publish::v5` | Merge daemon wire DTOs into the versioned protocol package. |
+| `radroots_event` | `radroots-event` | Retain singular package; narrow to canonical event-domain model. |
+| `radroots_event_codec` | `radroots-event-codec` | Retain; remove live Nostr/upstream client responsibilities. |
+| `radroots_event_index` | `radroots-storage::projection/index` | Merge; current checkpoint/manifest model is not an independent indexing engine. |
+| `radroots_trade` | `radroots-trade` | Retain algorithms; remove authority, storage, SQL, transport, and duplicate TradeId. |
+| `radroots_authority` | `radroots-identity + radroots-event::contract + radroots-signing` | Split account/public-key ownership, author-role contracts, and signing/authorization SPI. |
+| `radroots_transport` | `radroots-transport` | Retain and redesign as extensible source/sink SPI. |
+| `radroots_transport_nostr` | `radroots-transport-nostr` | Retain adapter; remove storage and sync orchestration. |
+| `radroots_transport_reticulum` | `private preview` | Withhold until a real adapter passes the transport conformance suite. |
+| `radroots_nostr` | `radroots-nostr` | Retain protocol conversion; remove live relay client and broad upstream aliases. |
+| `radroots_nostr_connect` | `radroots-nostr-connect` | Retain as independent bidirectional NIP-46 protocol boundary. |
+| `radroots_nostr_accounts` | `radroots-identity + radroots-secrets + radroots-storage + radroots-sdk` | Split mixed account, vault, persistence, and manager responsibilities. |
+| `radroots_nostr_signer` | `radroots-signing + radroots-nostr-connect + Myc-private state` | Do not publish current service-state package. |
+| `radroots_nostr_runtime` | `radroots-transport-nostr + radroots-sync` | Merge live relay runtime into adapter/orchestration layers. |
+| `radroots_nostrdb` | `private; possible future radroots-storage-nostrdb` | Withhold until the storage SPI and external consumers justify a backend package. |
+| `radroots_event_store` | `radroots-storage + radroots-storage-sqlite` | Split backend-neutral contracts from SQLite implementation. |
+| `radroots_outbox` | `radroots-storage + radroots-storage-sqlite` | Merge as one persistence capability with atomic operation commits. |
+| `radroots_runtime_store` | `radroots-storage or host-private state` | Retire broad name and classify each table by owner. |
+| `radroots_sql_core` | `radroots-storage-sqlite private internals` | Remove raw SQL/JSON executor from public API. |
+| `radroots_secret_vault` | `radroots-secrets` | Merge provider/wrapping SPI. |
+| `radroots_protected_store` | `radroots-secrets` | Merge encrypted-envelope semantics. |
+| `radroots_geocoder` | `radroots-geonames` | Rename to the actual concrete provider. |
+| `radroots_runtime` | `radroots-sync + radroots-storage + host-private tooling` | Dismantle mixed config/signals/logging/queue/transport package. |
+| `radroots_log` | `no replacement package` | Libraries emit tracing; hosts install subscribers. |
+| `radroots_net` | `radroots-transport + radroots-sync + radroots-sdk` | Retire broad duplicated network/runtime package. |
+| `radroots_runtime_paths` | `private host utility` | Do not place host path policy in the SDK registry closure. |
+| `radroots_runtime_manager` | `private host tooling` | Runtime installation and process lifecycle remain host-owned. |
+| `radroots_runtime_distribution` | `private host tooling` | Artifact distribution is not a public SDK dependency. |
+| `radroots_replica_*` | `private/deferred` | Preserve and redesign; no public names until generated CRUD/raw SQL surfaces are replaced. |
+| `radroots_mesh_*` | `private preview` | Preserve; publish only a real adapter or protocol with external consumers. |
+| `radroots_simplex_*` | `private preview` | Preserve internal decomposition; no crates.io commitment in release v1. |
+| `radroots_trade_sp1_*` | `private build/preview` | Keep specialized guest/host packages private. |
+| `binding, WASM, FFI, codegen, fixtures, xtask` | `private build/test packages` | Publish generated language artifacts, not Rust build machinery. |
+
+## 21. Workspace and manifest policy
+
+```toml
+[workspace]
+resolver = "3"
+
+[workspace.package]
+edition = "2024"
+rust-version = "1.97.1"
+license = "MIT OR Apache-2.0"
+homepage = "https://radroots.org"
+```
+
+Each standalone workspace sets its own repository metadata:
+
+```toml
+# radrootslabs/lib
+[workspace.package]
+repository = "https://github.com/radrootslabs/lib"
+```
+
+```toml
+# radrootslabs/sdk
+[workspace.package]
+repository = "https://github.com/radrootslabs/sdk"
+```
+
+Every public package MUST define:
+
+```toml
+[package]
+name = "radroots-..."
+version = "0.1.0"
+publish = ["crates-io"]
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+repository.workspace = true
+homepage.workspace = true
+readme = "README.md"
+documentation = "https://docs.rs/radroots-..."
+```
+
+Additional rules:
+
+- Use an explicit `include` whitelist.
+- Include both license files.
+- Every same-repository public dependency uses `path + version`.
+- Every dependency from `radrootslabs/sdk` to a package owned by
+ `radrootslabs/lib` uses a registry version and MUST NOT use a sibling path or
+ Git override in a release candidate.
+- No Git dependency exists in a published normal/build/target/optional closure.
+- Public packages avoid build scripts; generated source is checked and freshness-tested.
+- Workspace lints forbid unsafe code by default.
+- Public API crates deny broken rustdoc links.
+- Package metadata lists only accurate keywords/categories.
+- docs.rs metadata selects an intentional feature set instead of blindly enabling platform-incompatible features.
+
+## 22. Versioning and release policy
+
+### 22.1 Initial versions
+
+All 19 packages start at `0.1.0`. This document's “V1” is the architecture specification version, not a claim that Rust APIs are already 1.0-stable.
+
+### 22.2 SemVer groups
+
+- `radroots` and `radroots-sdk` release in lockstep and `radroots` uses `=X.Y.Z` for the SDK.
+- Lower packages version independently after the first release.
+- Lower dependencies use ordinary compatible requirements at the actual minimum supported version.
+- Exact requirements are reserved for genuinely inseparable package pairs.
+- Wire/event/runtime/storage/backup/generated-schema versions are independent of Cargo package versions.
+- Every package gets its own changelog section and public API baseline.
+- The repository maintains a tested compatibility manifest for the current SDK release.
+
+### 22.3 Breaking changes before 1.0
+
+For `0.y.z` packages:
+
+- breaking API changes increment `y`;
+- compatible fixes/features increment `z`;
+- package names and responsibility charters remain permanent;
+- moving a public type between packages is breaking and requires an ADR;
+- first-party consumers migrate in the same coordinated cutover.
+
+## 23. Indicative publication order
+
+The actual order is computed from `cargo metadata`; the expected order is:
+
+```text
+radroots-core
+radroots-identity
+radroots-blossom
+radroots-protocol
+radroots-secrets
+radroots-geonames
+radroots-event
+radroots-event-codec
+radroots-trade
+radroots-signing
+radroots-transport
+radroots-nostr
+radroots-nostr-connect
+radroots-storage
+radroots-storage-sqlite
+radroots-transport-nostr
+radroots-sync
+radroots-sdk
+radroots
+```
+
+Actual publication waits for each dependency to appear in the crates.io index before publishing dependents.
+
+## 24. Required CI and release gates
+
+### 24.1 Workspace
+
+- `cargo fmt --all -- --check`
+- `cargo check --workspace --all-targets`
+- `cargo clippy --workspace --all-targets --all-features -- -D warnings`
+- `cargo test --workspace --all-targets`
+- `cargo doc --workspace --no-deps`
+- doctests
+- generated-output freshness
+- protocol/contract/conformance validation
+- forbidden identifier and dependency checks
+
+### 24.2 Feature/target matrix
+
+For every public package:
+
+- no default features;
+- default features;
+- each public feature independently;
+- supported feature bundles;
+- all features;
+- MSRV 1.97.1;
+- current stable;
+- Linux, macOS, Windows;
+- declared no_std target;
+- `wasm32-unknown-unknown` where supported;
+- native package targets;
+- minimal and latest compatible dependencies.
+
+### 24.3 Public API
+
+- `cargo-semver-checks`;
+- public API baseline;
+- rustdoc with warnings denied;
+- no undocumented public item exceptions without review;
+- examples compile from packaged artifacts;
+- no duplicate canonical type paths except deliberate façade reexports;
+- no third-party type leakage in generic packages.
+
+### 24.4 Reliability and security
+
+- fuzz event, protocol, NIP-46, URL, manifest, backup, and restore parsers;
+- malformed and oversized network payloads;
+- cancellation before and after commit;
+- idempotency replay and conflict;
+- outbox claim expiry;
+- partial delivery and retry;
+- signer timeout/wrong response/auth challenge;
+- storage multi-reader/writer/locking;
+- migration and corruption failure;
+- crash recovery at every commit point;
+- backup/restore interruption, traversal, symlink, and hash mismatch;
+- projection invalidation/rebuild;
+- secret redaction;
+- dependency audit, license policy, provenance, SBOM, and advisory checks.
+
+### 24.5 Package-realistic release validation
+
+For every public package:
+
+1. Resolve the graph with `cargo metadata`.
+2. Reject all public-to-private edges across normal, optional, build, target, and reachable-feature dependencies.
+3. Run `cargo package --locked`.
+4. Inspect the normalized manifest.
+5. Inspect `cargo package --list`.
+6. Extract the `.crate`.
+7. Build, test, and document the extracted package.
+8. Run `cargo publish --dry-run --locked`.
+9. Publish to an ephemeral/local registry.
+10. Build clean external projects against registry artifacts.
+11. Build CLI, Studio, FFI/mobile, web packages, services, and indexers against package artifacts.
+12. Confirm no sibling path or Git override remains.
+
+## 25. Source-evidence record
+
+| Repository | Reviewed SHA | Source | Pressure-test finding |
+|---|---|---|---|
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `Cargo.toml` | Workspace currently contains 49+ packages, uses edition 2024 with resolver 2, and centralizes underscore-named path dependencies. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `contracts/releases/publish_policy.toml` | Current public classification contains broad runtime/storage/tooling crates while SDK-required packages remain internal. |
+| `radrootslabs/sdk` | `fd8384aee348034e0c8ea17a868fe7f094770050` | `crates/sdk/Cargo.toml` | SDK feature graph names implementation assembly and directly references private authority, event-store, outbox, transport, and adapter crates. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `crates/authority/src/{actor,authorization,signer}.rs` | Current authority package combines account provenance, event contract roles, signing SPI, authorization, and concrete local signing. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `crates/event/src/ids.rs` | Semantic identifiers are stored as Strings, implement Deref<str>, and include trade/account/network concepts in one module. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `crates/trade/src/identity.rs` | A second TradeId wraps OrderId, conflicting with the canonical event TradeId concept. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `crates/identity/src/identity.rs` | Identity owns raw secret keys, upstream Nostr event values, file formats, generation, and secret export methods. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `crates/transport/src/{kind,transport}.rs` | TransportKind is a closed enum and one monolithic trait requires both fetch and deliver. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `crates/transport_nostr/{Cargo.toml,src/lib.rs}` | Nostr adapter currently couples relay transport to event-store and outbox persistence. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `crates/event_store/src/store.rs and crates/outbox/src/store.rs` | Concrete stores expose SQLx pools/transactions and split related runtime state across separately opened stores. |
+| `radrootslabs/lib` | `466f3cc36739179bc17edb9db796530729ba5219` | `crates/runtime/src/lib.rs and crates/log/src/init.rs` | Runtime package combines host concerns; logging installs process-global subscriber state. |
+| `radrootslabs/sdk` | `fd8384aee348034e0c8ea17a868fe7f094770050` | `crates/sdk/src/{lib,runtime,studio_store,error}.rs` | SDK root broadly reexports implementation-shaped types, owns studio.sqlite, exposes many public fields, and duplicates error metadata. |
+
+## 26. Rejected alternatives
+
+### Publish the current public list
+
+Rejected because it permanently exposes host tooling and still omits SDK-required private dependencies.
+
+### Publish every current dependency unchanged
+
+Rejected because temporary implementation boundaries would become permanent package identities.
+
+### Collapse lower crates into `radroots-sdk`
+
+Rejected because domain, protocol, SPI, backend, and adapter packages have independent consumers and semver responsibilities.
+
+### One `radroots-runtime` package
+
+Rejected because runtime configuration, process lifecycle, paths, logging, queues, storage, and networking are not one coherent library boundary.
+
+### Separate packages for every domain or NIP
+
+Rejected because it creates package proliferation. Only independently substantial protocols with direct consumers—such as Nostr Connect—receive a package.
+
+### Versioned package names
+
+Rejected. Versions belong in modules and schema IDs.
+
+### Public preview placeholder packages
+
+Rejected. Preview code remains private until the implementation is real and conformance-tested.
+
+### Public codegen features
+
+Rejected. Code generation is a private build concern and must not enlarge the runtime registry closure.
+
+## 27. Cutover sequence
+
+1. Freeze publication and record this specification as an ADR.
+2. Preserve the independent `radrootslabs/lib` and `radrootslabs/sdk`
+ histories; record the 17/2 package allocation and synchronized contract
+ hashes without forming or importing a third repository.
+3. Switch workspace to resolver 3 and MSRV 1.97.1.
+4. Create final hyphenated package manifests with `publish = false` during migration.
+5. Refactor identity/public-key ownership and remove all secret material.
+6. Split authority among identity, event contracts, and signing.
+7. Remove the duplicate TradeId and make trade algorithm-only.
+8. Create `radroots-protocol`.
+9. Create `radroots-secrets`.
+10. Create `radroots-storage` and `radroots-storage-sqlite`; migrate event/outbox/journal/private storage.
+11. Remove Studio state from SDK storage.
+12. Redesign `radroots-transport`; separate source/sink.
+13. Narrow `radroots-nostr` and `radroots-transport-nostr`.
+14. Refactor and retain `radroots-nostr-connect`.
+15. Create `radroots-sync`.
+16. Rename/refocus GeoNames.
+17. Refactor SDK root, features, errors, lifecycle, and commit semantics.
+18. Add the curated `radroots` façade.
+19. Migrate every first-party consumer.
+20. Run package-realistic validation.
+21. Change only the 19 final packages to `publish = ["crates-io"]`.
+22. Publish in Cargo-derived order after explicit authorization.
+
+## 28. Completion and publication decision
+
+The package identities and boundaries in this specification are final for release V1.
+
+Publication is authorized only when all of the following are simultaneously true:
+
+- all 19 packages implement their charters;
+- no forbidden responsibility remains;
+- Cargo-resolved closure contains only public Radroots packages;
+- all feature/target/package/downstream gates pass;
+- naming availability and ownership are confirmed;
+- current-source licensing and contributor provenance are cleared;
+- generated cross-language contracts are coherent;
+- no first-party host remains on legacy or sibling-path APIs;
+- the actual `.crate` archives have been inspected and tested.
+
+Until then, the correct status is:
+
+```text
+Architecture: FINAL
+Implementation: REQUIRED
+Publication: BLOCKED
+```
+
+## 29. Final reaffirmation
+
+This is the final recommended Radroots crates surface.
+
+It preserves real modularity without turning every current workspace folder into a permanent public package. It establishes stable identities for foundational values, identity, event protocol, trade algorithms, signing, transport, secrets, storage, Nostr, synchronization, a concrete geodata provider, the advanced SDK, and the ordinary-user façade.
+
+It intentionally withholds host utilities, preview transports, generated CRUD/replica code, experimental messaging/proof systems, codegen, FFI machinery, and test support.
+
+No additional public crate is required for release V1, and no package in the 19-package family is present merely to satisfy Cargo. Each has a durable responsibility, named consumers, a one-way dependency position, and a credible independent SemVer surface.
diff --git a/docs/specs/radroots_crates_release_v1.sha256 b/docs/specs/radroots_crates_release_v1.sha256
@@ -0,0 +1,4 @@
+8ddb51b5f186cb7ebcd7d2cd60217dce183ad9c87d7363f91fbaa6ff8db9777e radroots_crates_release_v1.md
+f1f6661da8cec1bb1128b4f2846d4c2c0d97f391cb458003ced7296074c7bc9f radroots_crates_release_v1.toml
+6e4a1c00d762e36e18e530d8e88846d500aeb8889d6f36d7ef906a055ef30a37 radroots_crates_release_v1_inventory.csv
+dc5a24247df8feb6bad11985475cd3ccb5b7740a0dce8ad5198f47da7aff3480 radroots_crates_release_v1.dot
diff --git a/docs/specs/radroots_crates_release_v1.toml b/docs/specs/radroots_crates_release_v1.toml
@@ -0,0 +1,339 @@
+spec_id = "radroots.crates.release.v1"
+status = "final_architecture"
+date = "2026-07-26"
+package_count = 19
+initial_version = "0.1.0"
+edition = "2024"
+resolver = "3"
+rust_version = "1.97.1"
+license = "MIT OR Apache-2.0"
+canonical_repositories = [
+ "https://github.com/radrootslabs/lib",
+ "https://github.com/radrootslabs/sdk",
+]
+
+[repositories.lib]
+url = "https://github.com/radrootslabs/lib"
+packages = [
+ "radroots-core",
+ "radroots-identity",
+ "radroots-blossom",
+ "radroots-protocol",
+ "radroots-event",
+ "radroots-event-codec",
+ "radroots-trade",
+ "radroots-signing",
+ "radroots-transport",
+ "radroots-nostr",
+ "radroots-nostr-connect",
+ "radroots-secrets",
+ "radroots-storage",
+ "radroots-storage-sqlite",
+ "radroots-transport-nostr",
+ "radroots-sync",
+ "radroots-geonames",
+]
+
+[repositories.sdk]
+url = "https://github.com/radrootslabs/sdk"
+packages = ["radroots-sdk", "radroots"]
+
+[repository_policy]
+new_repository_forbidden = true
+history_merge_forbidden = true
+cross_repository_dependency = "registry_version"
+synchronized_contract_copies_required = true
+
+[release_policy]
+sdk_facade_lockstep = true
+lower_packages_independent_semver = true
+public_codegen_features_forbidden = true
+public_to_private_edges_forbidden = true
+same_repository_path_and_version_required = true
+package_realistic_validation_required = true
+preview_packages_withheld = true
+
+[[package]]
+name = "radroots-core"
+crate = "radroots_core"
+publish_order_hint = 1
+tier = "foundation"
+platform = "no_std + alloc; std feature"
+responsibility = "Foundational value objects and deterministic invariants: decimal, currency, money, percentage, quantity, units, and pricing."
+default_features = ["std", "serde"]
+features = ["std", "serde"]
+required_radroots_dependencies = []
+optional_radroots_dependencies = []
+modules = ["currency", "decimal", "money", "percent", "pricing", "quantity", "unit"]
+root_exports = ["Currency", "Decimal", "Money", "Percent", "Quantity", "QuantityPrice", "Unit", "Error"]
+forbidden = "Identifiers, identities, event kinds, networking, persistence, clocks, filesystem paths, process behavior, or application configuration."
+
+[[package]]
+name = "radroots-identity"
+crate = "radroots_identity"
+publish_order_hint = 2
+tier = "foundation"
+platform = "no_std + alloc; std feature"
+responsibility = "Public identity and account value types: canonical public keys, identity IDs, account IDs, public profiles, and usernames."
+default_features = ["std", "serde"]
+features = ["std", "serde"]
+required_radroots_dependencies = []
+optional_radroots_dependencies = []
+modules = ["account", "key", "profile", "username"]
+root_exports = ["AccountId", "IdentityId", "PublicIdentity", "PublicKey", "Profile", "Username", "Error"]
+forbidden = "Secret keys, key generation, NIP-49 encryption, keyrings, files, SQLite, runtime paths, upstream nostr::Event values, signer sessions, or host account selection."
+
+[[package]]
+name = "radroots-blossom"
+crate = "radroots_blossom"
+publish_order_hint = 3
+tier = "protocol primitive"
+platform = "no_std + alloc; std feature"
+responsibility = "Portable Blossom protocol primitives: canonical blob URLs, hashes, media descriptors, byte-verification typestates, and authorization claims."
+default_features = ["std", "serde"]
+features = ["std", "serde"]
+required_radroots_dependencies = []
+optional_radroots_dependencies = []
+modules = ["authorization", "descriptor", "hash", "media_type", "url"]
+root_exports = ["BlobUrl", "Sha256", "MediaType", "BlobDescriptor", "ByteVerifiedDescriptor", "AuthorizationClaim", "Error"]
+forbidden = "HTTP clients, upload scheduling, cache management, filesystem traversal, application media policy, or global authentication state."
+
+[[package]]
+name = "radroots-protocol"
+crate = "radroots_protocol"
+publish_order_hint = 4
+tier = "versioned wire contract"
+platform = "no_std + alloc; std feature"
+responsibility = "Versioned cross-process and cross-language schemas, capability catalogs, operation descriptors, stable error reports, schema IDs, and structural validation."
+default_features = ["std", "serde"]
+features = ["std", "serde"]
+required_radroots_dependencies = []
+optional_radroots_dependencies = []
+modules = ["capability::v1", "error::v1", "event::v1", "runtime::v1", "radrootsd::transport_publish::v5", "schema"]
+root_exports = []
+forbidden = "Native clients, storage, network I/O, executor/runtime ownership, domain reducers, upstream dependency types, unversioned serialized DTOs, or package names containing protocol generations."
+
+[[package]]
+name = "radroots-event"
+crate = "radroots_event"
+publish_order_hint = 5
+tier = "domain protocol model"
+platform = "no_std + alloc; std feature"
+responsibility = "Canonical Radroots event-domain models, validated event identifiers, tags, event contracts, authoring drafts, signed/verified typestates, and NIP-01 wire-neutral representations."
+default_features = ["std", "serde"]
+features = ["std", "serde", "knowledge"]
+required_radroots_dependencies = ["radroots-core", "radroots-identity", "radroots-blossom", "radroots-protocol"]
+optional_radroots_dependencies = []
+modules = ["admission", "calendar", "contract", "draft", "envelope", "farm", "food", "id", "knowledge", "listing", "media", "post", "profile", "social", "tag", "trade", "wire"]
+root_exports = ["Event", "EventDraft", "SignedEvent", "VerifiedEvent", "EventId", "EventKind", "EventTag", "Error"]
+forbidden = "Live Nostr clients, relay pools, signing backends, SQLite, outbox claims, retry scheduling, application state, or duplicate trade/order identifier concepts."
+
+[[package]]
+name = "radroots-event-codec"
+crate = "radroots_event_codec"
+publish_order_hint = 6
+tier = "deterministic algorithm"
+platform = "no_std + alloc where selected features permit; std feature"
+responsibility = "Deterministic canonical encoding, decoding, ID/signature verification, contract validation, admission, and manifest generation for Radroots events."
+default_features = ["std", "json"]
+features = ["std", "serde", "json", "knowledge", "manifests"]
+required_radroots_dependencies = ["radroots-event", "radroots-blossom", "radroots-protocol"]
+optional_radroots_dependencies = []
+modules = ["admission", "canonical", "decode", "encode", "manifest", "verify"]
+root_exports = ["Codec", "DecodeError", "EncodeError", "VerificationError"]
+forbidden = "nostr-sdk clients, relay networking, persistence, background work, upstream client errors, or host configuration."
+
+[[package]]
+name = "radroots-trade"
+crate = "radroots_trade"
+publish_order_hint = 7
+tier = "domain algorithm"
+platform = "no_std + alloc for model/reducer; std feature"
+responsibility = "Trade validation, evidence models, deterministic reduction, conflict analysis, and side-effect-free workflow plans over the canonical event trade model."
+default_features = ["std", "serde", "json"]
+features = ["std", "serde", "json"]
+required_radroots_dependencies = ["radroots-core", "radroots-identity", "radroots-event"]
+optional_radroots_dependencies = []
+modules = ["evidence", "model", "reducer", "validation", "workflow"]
+root_exports = ["Projection", "ReductionInput", "ReducerIssue", "WorkflowPlan", "ValidationError", "Error"]
+forbidden = "A second TradeId definition, actor authorization, signers, event-store access, SQLx, filesystem state, transport delivery, outbox mutation, or process scheduling."
+
+[[package]]
+name = "radroots-signing"
+crate = "radroots_signing"
+publish_order_hint = 8
+tier = "host SPI"
+platform = "no_std + alloc core; std feature"
+responsibility = "Object-safe author/signing SPI, actor provenance, authorization checks, requests, receipts, progress, capabilities, and normalized signing errors."
+default_features = ["std", "serde"]
+features = ["std", "serde"]
+required_radroots_dependencies = ["radroots-identity", "radroots-event", "radroots-protocol"]
+optional_radroots_dependencies = []
+modules = ["actor", "capability", "error", "request", "receipt", "signer", "status"]
+root_exports = ["Actor", "Signer", "SignRequest", "SignReceipt", "SignerStatus", "Error"]
+forbidden = "Raw secret-key ownership, keyrings, relay networking, NIP-46 session persistence, SQL, UI prompts, or executor creation."
+
+[[package]]
+name = "radroots-transport"
+crate = "radroots_transport"
+publish_order_hint = 9
+tier = "network SPI"
+platform = "no_std + alloc data model; std feature"
+responsibility = "Transport-neutral target identities, capability/status models, source and sink SPIs, delivery/fetch policies, bounded requests, provenance, and normalized outcomes."
+default_features = ["std", "serde"]
+features = ["std", "serde"]
+required_radroots_dependencies = ["radroots-identity", "radroots-event", "radroots-protocol"]
+optional_radroots_dependencies = []
+modules = ["capability", "endpoint", "error", "outcome", "policy", "sink", "source", "target"]
+root_exports = ["TransportId", "Target", "TargetSet", "EventSource", "EventSink", "DeliveryRequest", "DeliveryReceipt", "FetchRequest", "FetchPage", "Error"]
+forbidden = "Closed enums that prevent new transports, Reticulum-specific constants, Nostr URLs at the generic root, storage/outbox access, retries, scheduler ownership, or silent fallback."
+
+[[package]]
+name = "radroots-nostr"
+crate = "radroots_nostr"
+publish_order_hint = 10
+tier = "protocol adapter"
+platform = "no_std + alloc for conversion surface; std feature"
+responsibility = "Portable conversion between Radroots native event/identity types and Nostr protocol types, typed NIP helpers, and concrete local signing adapters; no live relay client."
+default_features = ["std", "events"]
+features = ["std", "events", "signing", "nip17", "blossom"]
+required_radroots_dependencies = ["radroots-identity", "radroots-event", "radroots-event-codec"]
+optional_radroots_dependencies = ["radroots-signing", "radroots-blossom"]
+modules = ["blossom", "event", "filter", "key", "nip17", "signing", "tag"]
+root_exports = ["Error"]
+forbidden = "nostr-sdk relay pools, reqwest clients, runtime ownership, broad aliases of upstream nostr types at the root, account persistence, or outbox orchestration."
+
+[[package]]
+name = "radroots-nostr-connect"
+crate = "radroots_nostr_connect"
+publish_order_hint = 11
+tier = "security protocol"
+platform = "std for v1; protocol data kept portable"
+responsibility = "Nostr Connect/NIP-46 URIs, methods, permissions, requests, responses, client/server state machines, timeout-independent protocol validation, and normalized errors."
+default_features = ["serde"]
+features = ["serde"]
+required_radroots_dependencies = ["radroots-identity", "radroots-event", "radroots-nostr", "radroots-protocol"]
+optional_radroots_dependencies = []
+modules = ["client", "error", "message", "method", "permission", "server", "uri"]
+root_exports = ["Client", "Server", "Method", "Permission", "Request", "Response", "BunkerUri", "ClientUri", "Error"]
+forbidden = "Relay-pool implementation, secret persistence, approval UI, global sessions, Tokio runtime ownership, or Myc-specific service storage."
+
+[[package]]
+name = "radroots-secrets"
+crate = "radroots_secrets"
+publish_order_hint = 12
+tier = "security SPI"
+platform = "no_std + alloc core; std adapters"
+responsibility = "Secret references, provider and key-wrapping SPIs, versioned encrypted envelopes, zeroization-safe secret handling, and explicit memory/file/keyring adapters."
+default_features = ["std", "serde"]
+features = ["std", "serde", "memory", "file", "keyring"]
+required_radroots_dependencies = []
+optional_radroots_dependencies = []
+modules = ["envelope", "error", "id", "provider", "wrapping", "memory", "file", "keyring"]
+root_exports = ["SecretId", "SecretRef", "SecretProvider", "KeyWrapping", "EncryptedEnvelope", "Error"]
+forbidden = "Public secret bytes, Clone/Debug/Serialize for secret-bearing values, identity profiles, domain tables, arbitrary key/value storage, hidden key generation, or process-global vaults."
+
+[[package]]
+name = "radroots-storage"
+crate = "radroots_storage"
+publish_order_hint = 13
+tier = "storage SPI"
+platform = "std for v1"
+responsibility = "Backend-neutral canonical event, operation journal, outbox, transport evidence, projection, private-artifact metadata, backup, status, and atomic commit interfaces, plus an in-memory reference backend."
+default_features = ["memory", "serde"]
+features = ["memory", "serde"]
+required_radroots_dependencies = ["radroots-event", "radroots-trade", "radroots-transport", "radroots-protocol"]
+optional_radroots_dependencies = []
+modules = ["atomic", "backup", "event", "journal", "memory", "outbox", "private_artifact", "projection", "status"]
+root_exports = ["Storage", "EventStore", "Journal", "Outbox", "ProjectionStore", "BackupSource", "StorageStatus", "Error"]
+forbidden = "SQL text, SQLx pools or transactions, filesystem paths, application UI state, concrete retry loops, Nostr clients, or unconstrained raw key/value escape hatches."
+
+[[package]]
+name = "radroots-storage-sqlite"
+crate = "radroots_storage_sqlite"
+publish_order_hint = 14
+tier = "native storage backend"
+platform = "std-only native backend"
+responsibility = "SQLite implementation of the storage SPIs with schema migration, WAL, locking, integrity, backup/restore, crash recovery, and encrypted private storage."
+default_features = []
+features = []
+required_radroots_dependencies = ["radroots-storage", "radroots-event-codec", "radroots-secrets"]
+optional_radroots_dependencies = []
+modules = ["backup", "config", "integrity", "lock", "migration", "open", "status"]
+root_exports = ["SqliteStorage", "OpenOptions", "OpenMode", "Paths", "Error"]
+forbidden = "Public SqlitePool/Connection/Transaction handles, caller-supplied arbitrary SQL, Studio state, global connection pools, runtime installation, or silent schema downgrade."
+
+[[package]]
+name = "radroots-transport-nostr"
+crate = "radroots_transport_nostr"
+publish_order_hint = 15
+tier = "native network adapter"
+platform = "std-only; Tokio implementation detail in v1"
+responsibility = "Concrete Nostr EventSource/EventSink implementation: relay URL policy, connection, NIP-42 authentication, bounded fetch pages, delivery, status, and relay-outcome normalization."
+default_features = []
+features = []
+required_radroots_dependencies = ["radroots-transport", "radroots-nostr", "radroots-event-codec", "radroots-protocol"]
+optional_radroots_dependencies = []
+modules = ["auth", "client", "relay", "sink", "source", "status"]
+root_exports = ["NostrTransport", "Config", "RelayUrl", "RelayUrlPolicy", "Error"]
+forbidden = "Event-store ingestion, outbox claiming, retry scheduling, projection refresh, global relay clients, direct SQL, or transport fallback."
+
+[[package]]
+name = "radroots-sync"
+crate = "radroots_sync"
+publish_order_hint = 16
+tier = "local-first orchestration"
+platform = "std-only in v1; executor-neutral public API"
+responsibility = "Shared pull, verification, canonical admission, duplicate handling, projection refresh, outbox signing/delivery, status, and retry-decision orchestration without owning scheduling."
+default_features = ["serde"]
+features = ["serde"]
+required_radroots_dependencies = ["radroots-event", "radroots-event-codec", "radroots-signing", "radroots-transport", "radroots-storage", "radroots-trade", "radroots-protocol"]
+optional_radroots_dependencies = []
+modules = ["ingest", "policy", "projection", "pull", "push", "status"]
+root_exports = ["Engine", "PullRequest", "PullReceipt", "PushRequest", "PushReceipt", "SyncStatus", "Error"]
+forbidden = "Creating an executor, spawning hidden workers, installing timers globally, owning process lifecycle, storing UI state, or transport-specific branches outside adapters."
+
+[[package]]
+name = "radroots-geonames"
+crate = "radroots_geonames"
+publish_order_hint = 17
+tier = "concrete data provider"
+platform = "std-only"
+responsibility = "GeoNames asset specification, authenticated/integrity-checked acquisition, database lifecycle, and forward/reverse locality lookup using provider-owned types."
+default_features = []
+features = []
+required_radroots_dependencies = []
+optional_radroots_dependencies = []
+modules = ["asset", "database", "download", "model", "query"]
+root_exports = ["Geocoder", "AssetSpec", "AssetStatus", "Query", "Candidate", "Point", "Error"]
+forbidden = "Generic multi-provider abstraction before a second provider exists, runtime-path policy, hidden downloads, SDK configuration types, SQLx/reqwest types in the public API, or test-fixture features."
+
+[[package]]
+name = "radroots-sdk"
+crate = "radroots_sdk"
+publish_order_hint = 18
+tier = "advanced front door"
+platform = "std-only native engine"
+responsibility = "Host-neutral asynchronous client engine, product operations, capability reporting, explicit storage/signing/transport composition, diagnostics, backup/restore, and safe commit semantics."
+default_features = ["memory"]
+features = ["memory", "sqlite", "sync", "nostr", "nip46", "local-signing", "radrootsd", "geonames", "knowledge", "native", "full"]
+required_radroots_dependencies = ["radroots-core", "radroots-identity", "radroots-protocol", "radroots-event", "radroots-event-codec", "radroots-trade", "radroots-signing", "radroots-transport", "radroots-storage"]
+optional_radroots_dependencies = ["radroots-secrets", "radroots-storage-sqlite", "radroots-nostr", "radroots-nostr-connect", "radroots-transport-nostr", "radroots-sync", "radroots-geonames"]
+modules = ["capability", "client", "diagnostics", "error", "farm", "listing", "signing", "storage", "sync", "trade", "transport"]
+root_exports = ["Client", "ClientBuilder", "Error", "Result"]
+forbidden = "Global runtimes or subscribers, hidden workers, process signals, CLI parsing, UI state, Studio databases, raw SQLx/upstream client types, broad wildcard reexports, or a nominal no_std claim."
+
+[[package]]
+name = "radroots"
+crate = "radroots"
+publish_order_hint = 19
+tier = "ordinary-user front door"
+platform = "std-only"
+responsibility = "Canonical Rust onboarding package with curated modules, safe defaults, stable convenience builders, domain aggregation, examples, and primary documentation."
+default_features = ["client"]
+features = ["client", "native", "nostr", "nip46", "radrootsd", "geonames", "knowledge", "full"]
+required_radroots_dependencies = ["radroots-sdk", "radroots-core", "radroots-identity", "radroots-event", "radroots-trade", "radroots-transport"]
+optional_radroots_dependencies = []
+modules = ["client", "event", "farm", "identity", "knowledge", "listing", "signing", "storage", "sync", "trade", "transport"]
+root_exports = ["Client", "ClientBuilder", "Error", "Result"]
+forbidden = "A public radroots::sdk namespace, wildcard reexport of radroots-sdk, duplicate engine implementation, CLI binary, hidden network/filesystem/keychain side effects, or exposure of every lower-crate symbol."
diff --git a/docs/specs/radroots_crates_release_v1_inventory.csv b/docs/specs/radroots_crates_release_v1_inventory.csv
@@ -0,0 +1,20 @@
+publish_order_hint,package,crate,repository,tier,platform,initial_version,default_features,features,required_radroots_dependencies,optional_radroots_dependencies,direct_consumers,responsibility,forbidden
+1,radroots-core,radroots_core,lib,foundation,no_std + alloc; std feature,0.1.0,std;serde,std;serde,,,radroots-event;radroots-trade;radroots-sdk;radroots,"Foundational value objects and deterministic invariants: decimal, currency, money, percentage, quantity, units, and pricing.","Identifiers, identities, event kinds, networking, persistence, clocks, filesystem paths, process behavior, or application configuration."
+2,radroots-identity,radroots_identity,lib,foundation,no_std + alloc; std feature,0.1.0,std;serde,std;serde,,,radroots-event;radroots-signing;radroots-transport;radroots-nostr;radroots-nostr-connect;radroots-sdk;services,"Public identity and account value types: canonical public keys, identity IDs, account IDs, public profiles, and usernames.","Secret keys, key generation, NIP-49 encryption, keyrings, files, SQLite, runtime paths, upstream nostr::Event values, signer sessions, or host account selection."
+3,radroots-blossom,radroots_blossom,lib,protocol primitive,no_std + alloc; std feature,0.1.0,std;serde,std;serde,,,radroots-event;radroots-event-codec;radroots-nostr;media clients,"Portable Blossom protocol primitives: canonical blob URLs, hashes, media descriptors, byte-verification typestates, and authorization claims.","HTTP clients, upload scheduling, cache management, filesystem traversal, application media policy, or global authentication state."
+4,radroots-protocol,radroots_protocol,lib,versioned wire contract,no_std + alloc; std feature,0.1.0,std;serde,std;serde,,,radroots-event;radroots-signing;radroots-transport;radroots-storage;radroots-sync;radroots-sdk;radrootsd;bindings,"Versioned cross-process and cross-language schemas, capability catalogs, operation descriptors, stable error reports, schema IDs, and structural validation.","Native clients, storage, network I/O, executor/runtime ownership, domain reducers, upstream dependency types, unversioned serialized DTOs, or package names containing protocol generations."
+5,radroots-event,radroots_event,lib,domain protocol model,no_std + alloc; std feature,0.1.0,std;serde,std;serde;knowledge,radroots-core;radroots-identity;radroots-blossom;radroots-protocol,,radroots-event-codec;radroots-trade;radroots-signing;radroots-transport;radroots-storage;radroots-sync;radroots-nostr;radroots-sdk;indexers,"Canonical Radroots event-domain models, validated event identifiers, tags, event contracts, authoring drafts, signed/verified typestates, and NIP-01 wire-neutral representations.","Live Nostr clients, relay pools, signing backends, SQLite, outbox claims, retry scheduling, application state, or duplicate trade/order identifier concepts."
+6,radroots-event-codec,radroots_event_codec,lib,deterministic algorithm,no_std + alloc where selected features permit; std feature,0.1.0,std;json,std;serde;json;knowledge;manifests,radroots-event;radroots-blossom;radroots-protocol,,radroots-nostr;radroots-storage-sqlite;radroots-transport-nostr;radroots-sync;radroots-sdk;bindings,"Deterministic canonical encoding, decoding, ID/signature verification, contract validation, admission, and manifest generation for Radroots events.","nostr-sdk clients, relay networking, persistence, background work, upstream client errors, or host configuration."
+7,radroots-trade,radroots_trade,lib,domain algorithm,no_std + alloc for model/reducer; std feature,0.1.0,std;serde;json,std;serde;json,radroots-core;radroots-identity;radroots-event,,radroots-storage;radroots-sync;radroots-sdk;RHI;applications,"Trade validation, evidence models, deterministic reduction, conflict analysis, and side-effect-free workflow plans over the canonical event trade model.","A second TradeId definition, actor authorization, signers, event-store access, SQLx, filesystem state, transport delivery, outbox mutation, or process scheduling."
+8,radroots-signing,radroots_signing,lib,host SPI,no_std + alloc core; std feature,0.1.0,std;serde,std;serde,radroots-identity;radroots-event;radroots-protocol,,radroots-nostr;radroots-sync;radroots-sdk;CLI;Studio;FFI hosts,"Object-safe author/signing SPI, actor provenance, authorization checks, requests, receipts, progress, capabilities, and normalized signing errors.","Raw secret-key ownership, keyrings, relay networking, NIP-46 session persistence, SQL, UI prompts, or executor creation."
+9,radroots-transport,radroots_transport,lib,network SPI,no_std + alloc data model; std feature,0.1.0,std;serde,std;serde,radroots-identity;radroots-event;radroots-protocol,,radroots-storage;radroots-transport-nostr;radroots-sync;radroots-sdk;services;future adapters,"Transport-neutral target identities, capability/status models, source and sink SPIs, delivery/fetch policies, bounded requests, provenance, and normalized outcomes.","Closed enums that prevent new transports, Reticulum-specific constants, Nostr URLs at the generic root, storage/outbox access, retries, scheduler ownership, or silent fallback."
+10,radroots-nostr,radroots_nostr,lib,protocol adapter,no_std + alloc for conversion surface; std feature,0.1.0,std;events,std;events;signing;nip17;blossom,radroots-identity;radroots-event;radroots-event-codec,radroots-signing;radroots-blossom,radroots-nostr-connect;radroots-transport-nostr;radroots-sdk;Myc;radrootsd,"Portable conversion between Radroots native event/identity types and Nostr protocol types, typed NIP helpers, and concrete local signing adapters; no live relay client.","nostr-sdk relay pools, reqwest clients, runtime ownership, broad aliases of upstream nostr types at the root, account persistence, or outbox orchestration."
+11,radroots-nostr-connect,radroots_nostr_connect,lib,security protocol,std for v1; protocol data kept portable,0.1.0,serde,serde,radroots-identity;radroots-event;radroots-nostr;radroots-protocol,,radroots-sdk;Myc;remote signer tooling,"Nostr Connect/NIP-46 URIs, methods, permissions, requests, responses, client/server state machines, timeout-independent protocol validation, and normalized errors.","Relay-pool implementation, secret persistence, approval UI, global sessions, Tokio runtime ownership, or Myc-specific service storage."
+12,radroots-secrets,radroots_secrets,lib,security SPI,no_std + alloc core; std adapters,0.1.0,std;serde,std;serde;memory;file;keyring,,,radroots-storage-sqlite;radroots-sdk;signing hosts;services,"Secret references, provider and key-wrapping SPIs, versioned encrypted envelopes, zeroization-safe secret handling, and explicit memory/file/keyring adapters.","Public secret bytes, Clone/Debug/Serialize for secret-bearing values, identity profiles, domain tables, arbitrary key/value storage, hidden key generation, or process-global vaults."
+13,radroots-storage,radroots_storage,lib,storage SPI,std for v1,0.1.0,memory;serde,memory;serde,radroots-event;radroots-trade;radroots-transport;radroots-protocol,,radroots-storage-sqlite;radroots-sync;radroots-sdk;indexers;tests;future backends,"Backend-neutral canonical event, operation journal, outbox, transport evidence, projection, private-artifact metadata, backup, status, and atomic commit interfaces, plus an in-memory reference backend.","SQL text, SQLx pools or transactions, filesystem paths, application UI state, concrete retry loops, Nostr clients, or unconstrained raw key/value escape hatches."
+14,radroots-storage-sqlite,radroots_storage_sqlite,lib,native storage backend,std-only native backend,0.1.0,,,radroots-storage;radroots-event-codec;radroots-secrets,,radroots-sdk;CLI;Studio;mobile/FFI,"SQLite implementation of the storage SPIs with schema migration, WAL, locking, integrity, backup/restore, crash recovery, and encrypted private storage.","Public SqlitePool/Connection/Transaction handles, caller-supplied arbitrary SQL, Studio state, global connection pools, runtime installation, or silent schema downgrade."
+15,radroots-transport-nostr,radroots_transport_nostr,lib,native network adapter,std-only; Tokio implementation detail in v1,0.1.0,,,radroots-transport;radroots-nostr;radroots-event-codec;radroots-protocol,,radroots-sdk;CLI;radrootsd;advanced hosts,"Concrete Nostr EventSource/EventSink implementation: relay URL policy, connection, NIP-42 authentication, bounded fetch pages, delivery, status, and relay-outcome normalization.","Event-store ingestion, outbox claiming, retry scheduling, projection refresh, global relay clients, direct SQL, or transport fallback."
+16,radroots-sync,radroots_sync,lib,local-first orchestration,std-only in v1; executor-neutral public API,0.1.0,serde,serde,radroots-event;radroots-event-codec;radroots-signing;radroots-transport;radroots-storage;radroots-trade;radroots-protocol,,radroots-sdk;CLI;Studio;mobile/FFI;advanced hosts,"Shared pull, verification, canonical admission, duplicate handling, projection refresh, outbox signing/delivery, status, and retry-decision orchestration without owning scheduling.","Creating an executor, spawning hidden workers, installing timers globally, owning process lifecycle, storing UI state, or transport-specific branches outside adapters."
+17,radroots-geonames,radroots_geonames,lib,concrete data provider,std-only,0.1.0,,,,,radroots-sdk;CLI;geocoding applications,"GeoNames asset specification, authenticated/integrity-checked acquisition, database lifecycle, and forward/reverse locality lookup using provider-owned types.","Generic multi-provider abstraction before a second provider exists, runtime-path policy, hidden downloads, SDK configuration types, SQLx/reqwest types in the public API, or test-fixture features."
+18,radroots-sdk,radroots_sdk,sdk,advanced front door,std-only native engine,0.1.0,memory,memory;sqlite;sync;nostr;nip46;local-signing;radrootsd;geonames;knowledge;native;full,radroots-core;radroots-identity;radroots-protocol;radroots-event;radroots-event-codec;radroots-trade;radroots-signing;radroots-transport;radroots-storage,radroots-secrets;radroots-storage-sqlite;radroots-nostr;radroots-nostr-connect;radroots-transport-nostr;radroots-sync;radroots-geonames,CLI;Studio;FFI/mobile;advanced native applications,"Host-neutral asynchronous client engine, product operations, capability reporting, explicit storage/signing/transport composition, diagnostics, backup/restore, and safe commit semantics.","Global runtimes or subscribers, hidden workers, process signals, CLI parsing, UI state, Studio databases, raw SQLx/upstream client types, broad wildcard reexports, or a nominal no_std claim."
+19,radroots,radroots,sdk,ordinary-user front door,std-only,0.1.0,client,client;native;nostr;nip46;radrootsd;geonames;knowledge;full,radroots-sdk;radroots-core;radroots-identity;radroots-event;radroots-trade;radroots-transport,,ordinary Rust applications;examples;documentation,"Canonical Rust onboarding package with curated modules, safe defaults, stable convenience builders, domain aggregation, examples, and primary documentation.","A public radroots::sdk namespace, wildcard reexport of radroots-sdk, duplicate engine implementation, CLI binary, hidden network/filesystem/keychain side effects, or exposure of every lower-crate symbol."