commit ef53ce07d5eaac77f388b48d9ec73e7a0922de8b
parent 370dee1ac85d6ccb5d4a7bbf8e8363c8d6905341
Author: triesap <tyson@radroots.org>
Date: Sun, 23 Aug 2026 22:25:18 +0000
api(rhi): freeze the curated root surface
Hide implementation modules, replace dependency-owned attestation errors with stable redacted RHI classifications, redact protected Debug output, and check in the exact reviewed API baseline.
Diffstat:
10 files changed, 1020 insertions(+), 40 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
@@ -277,6 +277,11 @@
- Prefer pure transformations, explicit state machines, validated newtypes,
tagged serialized enums, narrow side-effect boundaries, and private or
`pub(crate)` visibility.
+- Keep every implementation module private and expose intended library names
+ only through the curated crate root. Regenerate and byte-compare
+ `contracts/api_baselines/rhi.txt` whenever that public surface changes.
+- Public errors must use RHI-owned stable classifications with redacted
+ Display and Debug output and no raw dependency-owned source chain.
- Use `thiserror` for library/domain errors and `anyhow` only at binary, xtask,
or one-shot composition boundaries. Avoid production `unwrap`/`expect` and
environment-dependent `Default`; ordinary `Debug` must never expose secrets.
diff --git a/README b/README
@@ -3,6 +3,26 @@
This is the README for `rhi` which listens on Rad Roots networks and maintains
a stable activity record for parties buying and selling agricultural goods.
+## Public API boundary
+
+The library exposes one curated crate-root API. Every implementation module is
+private, and public errors use RHI-owned stable classifications with redacted
+diagnostics and no raw dependency-owned source chain or caller path. The shared
+runtime-path, service-SQLite, storage, event, and trade values that appear in
+signatures are deliberate governed contract types; raw SQLx, Serde, transport,
+filesystem, and task authority never crosses this boundary.
+
+Child modules cannot bypass the reviewed root surface:
+
+```compile_fail
+use rhi::features::trade_agreement_attestation::TradeAgreementAttestationPolicy;
+
+fn bypass(_: TradeAgreementAttestationPolicy) {}
+```
+
+The reviewed all-features surface is frozen in the
+[RHI API baseline](contracts/api_baselines/rhi.txt).
+
RHI publishes its service kind-0 Profile only through the sealed
`radroots_nostr` Profile builder after constructing the strict
`RadrootsAuthoredProfile` replacement snapshot. It does not retain a generic
@@ -135,9 +155,9 @@ state metadata, the encrypted identity, and its separately resolved credential
to one service instance. It proves that state initialization and existing-only
open do not persist the identity secret, credential, encrypted-envelope wire
material, or credential reference in `state.sqlite`. The envelope and
-credential remain excluded from the state-backup contract. Actual online
-backup, offline restore, and recovery execution remain owned by their later
-ordered checkpoint and are not claimed by this boundary proof.
+credential remain excluded from the state-backup contract. That earlier
+wave-two boundary proof did not itself execute a backup; the governed
+resilience boundary below now owns the actual backup and recovery mechanics.
RHI's state surface is partitioned into eighteen distinct non-forgeable typed
repository capabilities bound to one already-opened `RhiStateHost`. Their
@@ -183,7 +203,7 @@ commands through `cargo extbuild run --` from this repository root.
Except as otherwise noted, all files in the `rhi` distribution are
- Copyright (c) 2025 Tyson Lupul
+`Copyright (c) 2025 Tyson Lupul`
## License
diff --git a/contracts/api_baselines/rhi.txt b/contracts/api_baselines/rhi.txt
@@ -0,0 +1,660 @@
+pub mod rhi
+pub use rhi::INSTANCE_ID_MAX_BYTES
+pub use rhi::InstanceId
+pub use rhi::RadrootsHostEnvironment
+pub use rhi::RadrootsPathProfile
+pub use rhi::RadrootsPathResolver
+pub use rhi::RadrootsPlatform
+pub use rhi::RadrootsServiceInstanceArtifacts
+pub use rhi::RuntimeContext
+pub use rhi::RuntimeContextSource
+pub use rhi::ServiceId
+pub enum rhi::RhiBootstrapProfileV1
+pub rhi::RhiBootstrapProfileV1::Interactive
+pub rhi::RhiBootstrapProfileV1::RepoLocal
+pub rhi::RhiBootstrapProfileV1::ServiceHost
+pub enum rhi::RhiCliOutputModeV1
+pub rhi::RhiCliOutputModeV1::Human
+pub rhi::RhiCliOutputModeV1::Json
+pub enum rhi::RhiCliV1ErrorKind
+pub rhi::RhiCliV1ErrorKind::InvalidArguments
+pub rhi::RhiCliV1ErrorKind::InvalidConfigPath
+pub rhi::RhiCliV1ErrorKind::InvalidInstance
+pub rhi::RhiCliV1ErrorKind::InvalidRepoLocalRoot
+pub rhi::RhiCliV1ErrorKind::UnexpectedRepoLocalRoot
+pub enum rhi::RhiCommandV1
+pub rhi::RhiCommandV1::Config(rhi::RhiConfigCommandV1)
+pub rhi::RhiCommandV1::Doctor
+pub rhi::RhiCommandV1::Identity(rhi::RhiIdentityCommandV1)
+pub rhi::RhiCommandV1::Metrics(rhi::RhiMetricsCommandV1)
+pub rhi::RhiCommandV1::Presence(rhi::RhiPresenceCommandV1)
+pub rhi::RhiCommandV1::Publication(rhi::RhiPublicationCommandV1)
+pub rhi::RhiCommandV1::Reconciliation(rhi::RhiReconciliationCommandV1)
+pub rhi::RhiCommandV1::Run
+pub rhi::RhiCommandV1::Sources(rhi::RhiSourcesCommandV1)
+pub rhi::RhiCommandV1::State(rhi::RhiStateCommandV1)
+pub rhi::RhiCommandV1::Status
+pub rhi::RhiCommandV1::Trade(rhi::RhiTradeCommandV1)
+pub enum rhi::RhiConfigCommandV1
+pub rhi::RhiConfigCommandV1::Apply
+pub rhi::RhiConfigCommandV1::Init
+pub rhi::RhiConfigCommandV1::Schema
+pub rhi::RhiConfigCommandV1::Show
+pub rhi::RhiConfigCommandV1::Validate
+pub enum rhi::RhiConfigDefaultAuthority
+pub rhi::RhiConfigDefaultAuthority::AcceptedServiceAuthority
+pub rhi::RhiConfigDefaultAuthority::EngineeringSafety
+pub rhi::RhiConfigDefaultAuthority::RadrootsEvent
+pub rhi::RhiConfigDefaultAuthority::RadrootsServiceHost
+pub rhi::RhiConfigDefaultAuthority::RadrootsServiceSqlite
+pub rhi::RhiConfigDefaultAuthority::RhiEvidencePolicy
+pub enum rhi::RhiConfigProfile
+pub rhi::RhiConfigProfile::Production
+pub rhi::RhiConfigProfile::RepoLocal
+pub enum rhi::RhiConfigV1ErrorKind
+pub rhi::RhiConfigV1ErrorKind::Encoding
+pub rhi::RhiConfigV1ErrorKind::InvalidDocument
+pub rhi::RhiConfigV1ErrorKind::InvalidRelationship
+pub rhi::RhiConfigV1ErrorKind::InvalidSchema
+pub rhi::RhiConfigV1ErrorKind::InvalidSchemaVersion
+pub rhi::RhiConfigV1ErrorKind::InvalidUtf8
+pub rhi::RhiConfigV1ErrorKind::MalformedToml
+pub rhi::RhiConfigV1ErrorKind::MissingSchema
+pub rhi::RhiConfigV1ErrorKind::MissingSchemaVersion
+pub rhi::RhiConfigV1ErrorKind::SchemaMismatch
+pub rhi::RhiConfigV1ErrorKind::TooLarge
+pub rhi::RhiConfigV1ErrorKind::UnsupportedSchemaVersion
+pub enum rhi::RhiConfigValueSource
+pub rhi::RhiConfigValueSource::BootstrapCli
+pub rhi::RhiConfigValueSource::DerivedPath
+pub rhi::RhiConfigValueSource::SafeDefault
+pub rhi::RhiConfigValueSource::Toml
+pub enum rhi::RhiCredentialResolutionErrorKind
+pub rhi::RhiCredentialResolutionErrorKind::InsecureCredential
+pub rhi::RhiCredentialResolutionErrorKind::InsecureSecretsRoot
+pub rhi::RhiCredentialResolutionErrorKind::InvalidBinding
+pub rhi::RhiCredentialResolutionErrorKind::InvalidCredential
+pub rhi::RhiCredentialResolutionErrorKind::InvalidReference
+pub rhi::RhiCredentialResolutionErrorKind::Io
+pub rhi::RhiCredentialResolutionErrorKind::MissingCredential
+pub rhi::RhiCredentialResolutionErrorKind::UnsupportedPlatform
+pub rhi::RhiCredentialResolutionErrorKind::UnsupportedProfile
+impl rhi::RhiCredentialResolutionErrorKind
+pub const fn rhi::RhiCredentialResolutionErrorKind::code(self) -> &'static str
+pub enum rhi::RhiEncryptedIdentityEnvelopeErrorKind
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::AlreadyExists
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::IdentityMismatch
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::InsecureArtifact
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::InsecureParent
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::InvalidBinding
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::InvalidCredential
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::InvalidPath
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::InvalidProvisioningMaterial
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::Io
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::MalformedEnvelope
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::MissingEnvelope
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::UnsupportedEnvelopeVersion
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::UnsupportedPlatform
+pub rhi::RhiEncryptedIdentityEnvelopeErrorKind::WrongCredential
+impl rhi::RhiEncryptedIdentityEnvelopeErrorKind
+pub const fn rhi::RhiEncryptedIdentityEnvelopeErrorKind::code(self) -> &'static str
+pub enum rhi::RhiIdentityCommandV1
+pub rhi::RhiIdentityCommandV1::ExportPublic
+pub rhi::RhiIdentityCommandV1::Init
+pub rhi::RhiIdentityCommandV1::Status
+pub enum rhi::RhiIdentityProviderKind
+pub rhi::RhiIdentityProviderKind::EncryptedFile
+pub enum rhi::RhiIdentityRole
+pub rhi::RhiIdentityRole::Service
+impl rhi::RhiIdentityRole
+pub const fn rhi::RhiIdentityRole::as_str(self) -> &'static str
+pub enum rhi::RhiMetricsCommandV1
+pub rhi::RhiMetricsCommandV1::Snapshot
+pub enum rhi::RhiPresenceCommandV1
+pub rhi::RhiPresenceCommandV1::Desired
+pub rhi::RhiPresenceCommandV1::Refresh
+pub rhi::RhiPresenceCommandV1::Render
+pub enum rhi::RhiPublicationCommandV1
+pub rhi::RhiPublicationCommandV1::Backlog
+pub rhi::RhiPublicationCommandV1::Retry
+pub rhi::RhiPublicationCommandV1::Targets
+pub enum rhi::RhiReconciliationCommandV1
+pub rhi::RhiReconciliationCommandV1::Jobs
+pub rhi::RhiReconciliationCommandV1::Refresh
+pub rhi::RhiReconciliationCommandV1::Status
+pub enum rhi::RhiRuntimeContextErrorKind
+pub rhi::RhiRuntimeContextErrorKind::InvalidBootstrapBinding
+pub rhi::RhiRuntimeContextErrorKind::InvalidServiceIdentity
+pub rhi::RhiRuntimeContextErrorKind::PathSelection
+pub enum rhi::RhiSourcesCommandV1
+pub rhi::RhiSourcesCommandV1::List
+pub enum rhi::RhiStateCatalogErrorKind
+pub rhi::RhiStateCatalogErrorKind::CatalogMismatch
+pub rhi::RhiStateCatalogErrorKind::MigrationCatalog
+pub rhi::RhiStateCatalogErrorKind::SchemaCatalog
+impl rhi::RhiStateCatalogErrorKind
+pub const fn rhi::RhiStateCatalogErrorKind::code(self) -> &'static str
+pub enum rhi::RhiStateCommandV1
+pub rhi::RhiStateCommandV1::Backup
+pub rhi::RhiStateCommandV1::Init
+pub rhi::RhiStateCommandV1::Migrate
+pub rhi::RhiStateCommandV1::Restore
+pub rhi::RhiStateCommandV1::Status
+pub rhi::RhiStateCommandV1::Verify
+pub enum rhi::RhiStateHostErrorKind
+pub rhi::RhiStateHostErrorKind::Catalog
+pub rhi::RhiStateHostErrorKind::Close
+pub rhi::RhiStateHostErrorKind::Initialize
+pub rhi::RhiStateHostErrorKind::InspectionOpen
+pub rhi::RhiStateHostErrorKind::InvalidEvidence
+pub rhi::RhiStateHostErrorKind::InvalidPaths
+pub rhi::RhiStateHostErrorKind::ReadWriteOpen
+impl rhi::RhiStateHostErrorKind
+pub const fn rhi::RhiStateHostErrorKind::code(self) -> &'static str
+pub enum rhi::RhiStateHostMode
+pub rhi::RhiStateHostMode::ReadOnlyInspection
+pub rhi::RhiStateHostMode::ReadWriteExisting
+pub enum rhi::RhiStateMaintenanceErrorKind
+pub rhi::RhiStateMaintenanceErrorKind::Authority
+pub rhi::RhiStateMaintenanceErrorKind::Backup
+pub rhi::RhiStateMaintenanceErrorKind::Catalog
+pub rhi::RhiStateMaintenanceErrorKind::Integrity
+pub rhi::RhiStateMaintenanceErrorKind::InvalidEvidence
+pub rhi::RhiStateMaintenanceErrorKind::InvalidMode
+pub rhi::RhiStateMaintenanceErrorKind::Metadata
+pub rhi::RhiStateMaintenanceErrorKind::Migration
+pub rhi::RhiStateMaintenanceErrorKind::Open
+pub rhi::RhiStateMaintenanceErrorKind::Recovery
+pub rhi::RhiStateMaintenanceErrorKind::Restore
+impl rhi::RhiStateMaintenanceErrorKind
+pub const fn rhi::RhiStateMaintenanceErrorKind::code(self) -> &'static str
+pub enum rhi::RhiStateMetadataErrorKind
+pub rhi::RhiStateMetadataErrorKind::Configuration
+pub rhi::RhiStateMetadataErrorKind::Database
+pub rhi::RhiStateMetadataErrorKind::EvidencePolicy
+pub rhi::RhiStateMetadataErrorKind::Identity
+pub rhi::RhiStateMetadataErrorKind::Invariant
+pub rhi::RhiStateMetadataErrorKind::Paths
+pub rhi::RhiStateMetadataErrorKind::Profile
+#[repr(u8)] pub enum rhi::RhiStateRepositoryKind
+pub rhi::RhiStateRepositoryKind::DesiredPresence
+pub rhi::RhiStateRepositoryKind::DirtyTrade
+pub rhi::RhiStateRepositoryKind::EvidenceManifest
+pub rhi::RhiStateRepositoryKind::Mutation
+pub rhi::RhiStateRepositoryKind::Projection
+pub rhi::RhiStateRepositoryKind::Provenance
+pub rhi::RhiStateRepositoryKind::PublicationAttempt
+pub rhi::RhiStateRepositoryKind::PublicationOutbox
+pub rhi::RhiStateRepositoryKind::PublicationTarget
+pub rhi::RhiStateRepositoryKind::ReconciliationAttempt
+pub rhi::RhiStateRepositoryKind::ReconciliationJob
+pub rhi::RhiStateRepositoryKind::Report
+pub rhi::RhiStateRepositoryKind::SignedAttestationEvent
+pub rhi::RhiStateRepositoryKind::SignedEvent
+pub rhi::RhiStateRepositoryKind::Source
+pub rhi::RhiStateRepositoryKind::SourceCompletion
+pub rhi::RhiStateRepositoryKind::SourceCursor
+pub rhi::RhiStateRepositoryKind::Supersession
+impl rhi::RhiStateRepositoryKind
+pub const fn rhi::RhiStateRepositoryKind::backing_table(self) -> &'static str
+pub const fn rhi::RhiStateRepositoryKind::code(self) -> &'static str
+pub const fn rhi::RhiStateRepositoryKind::write_class(self) -> rhi::RhiStateRepositoryWriteClass
+pub enum rhi::RhiStateRepositoryWriteClass
+pub rhi::RhiStateRepositoryWriteClass::AppendOnly
+pub rhi::RhiStateRepositoryWriteClass::CompareAndSwap
+pub rhi::RhiStateRepositoryWriteClass::Immutable
+impl rhi::RhiStateRepositoryWriteClass
+pub const fn rhi::RhiStateRepositoryWriteClass::code(self) -> &'static str
+pub enum rhi::RhiTradeCommandV1
+pub rhi::RhiTradeCommandV1::Projection
+pub rhi::RhiTradeCommandV1::ReportCurrent
+pub rhi::RhiTradeCommandV1::Reports
+pub enum rhi::TradeAgreementAttestationBackend
+pub rhi::TradeAgreementAttestationBackend::LocalStatementHash
+impl rhi::TradeAgreementAttestationBackend
+pub const fn rhi::TradeAgreementAttestationBackend::as_str(self) -> &'static str
+pub enum rhi::TradeAgreementAttestationErrorKind
+pub rhi::TradeAgreementAttestationErrorKind::Encoding
+pub rhi::TradeAgreementAttestationErrorKind::InvalidHashField
+pub rhi::TradeAgreementAttestationErrorKind::InvalidValidatorSetBinding
+pub rhi::TradeAgreementAttestationErrorKind::MissingAgreementClaim
+pub rhi::TradeAgreementAttestationErrorKind::MissingValidatorSetBinding
+pub rhi::TradeAgreementAttestationErrorKind::TradeProtocol
+impl rhi::TradeAgreementAttestationErrorKind
+pub const fn rhi::TradeAgreementAttestationErrorKind::code(self) -> &'static str
+impl core::fmt::Display for rhi::TradeAgreementAttestationErrorKind
+pub fn rhi::TradeAgreementAttestationErrorKind::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::NostrEventAdapter<'a>
+impl<'a> rhi::NostrEventAdapter<'a>
+pub fn rhi::NostrEventAdapter<'a>::new(&'a nostr::event::Event) -> Self
+impl core::fmt::Debug for rhi::NostrEventAdapter<'_>
+pub fn rhi::NostrEventAdapter<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl radroots_event_codec::job::traits::JobEventLike for rhi::NostrEventAdapter<'_>
+pub fn rhi::NostrEventAdapter<'_>::raw_author(&self) -> alloc::string::String
+pub fn rhi::NostrEventAdapter<'_>::raw_content(&self) -> alloc::string::String
+pub fn rhi::NostrEventAdapter<'_>::raw_id(&self) -> alloc::string::String
+pub fn rhi::NostrEventAdapter<'_>::raw_kind(&self) -> u32
+pub fn rhi::NostrEventAdapter<'_>::raw_published_at(&self) -> u64
+pub fn rhi::NostrEventAdapter<'_>::raw_sig(&self) -> alloc::string::String
+pub fn rhi::NostrEventAdapter<'_>::raw_tags(&self) -> alloc::vec::Vec<alloc::vec::Vec<alloc::string::String>>
+impl<'a> radroots_event_codec::job::traits::JobEventBorrow<'a> for rhi::NostrEventAdapter<'a>
+pub fn rhi::NostrEventAdapter<'a>::raw_author(&'a self) -> alloc::string::String
+pub fn rhi::NostrEventAdapter<'a>::raw_content(&'a self) -> &'a str
+pub fn rhi::NostrEventAdapter<'a>::raw_id(&'a self) -> alloc::string::String
+pub fn rhi::NostrEventAdapter<'a>::raw_kind(&'a self) -> u32
+pub struct rhi::RhiCliInvocationV1
+impl rhi::RhiCliInvocationV1
+pub const fn rhi::RhiCliInvocationV1::command(&self) -> rhi::RhiCommandV1
+pub fn rhi::RhiCliInvocationV1::config_path(&self) -> core::option::Option<&std::path::Path>
+pub const fn rhi::RhiCliInvocationV1::instance(&self) -> &radroots_runtime_paths::identifier::InstanceId
+pub const fn rhi::RhiCliInvocationV1::output_mode(&self) -> rhi::RhiCliOutputModeV1
+pub const fn rhi::RhiCliInvocationV1::profile(&self) -> rhi::RhiBootstrapProfileV1
+pub fn rhi::RhiCliInvocationV1::repo_local_root(&self) -> core::option::Option<&std::path::Path>
+impl core::fmt::Debug for rhi::RhiCliInvocationV1
+pub fn rhi::RhiCliInvocationV1::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiCliV1Error
+impl rhi::RhiCliV1Error
+pub const fn rhi::RhiCliV1Error::kind(self) -> rhi::RhiCliV1ErrorKind
+impl core::error::Error for rhi::RhiCliV1Error
+impl core::fmt::Debug for rhi::RhiCliV1Error
+pub fn rhi::RhiCliV1Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiCliV1Error
+pub fn rhi::RhiCliV1Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiConfigDocumentV1
+impl rhi::RhiConfigDocumentV1
+pub const fn rhi::RhiConfigDocumentV1::effective(&self) -> &rhi::RhiEffectiveConfigV1
+pub fn rhi::RhiConfigDocumentV1::evidence_source_count(&self) -> usize
+pub const fn rhi::RhiConfigDocumentV1::profile(&self) -> rhi::RhiConfigProfile
+pub fn rhi::RhiConfigDocumentV1::relay_count(&self) -> usize
+pub const fn rhi::RhiConfigDocumentV1::runtime_thread_limits(&self) -> rhi::RhiRuntimeThreadLimitsV1
+pub const fn rhi::RhiConfigDocumentV1::schema(&self) -> &'static str
+pub const fn rhi::RhiConfigDocumentV1::schema_version(&self) -> u32
+impl core::fmt::Debug for rhi::RhiConfigDocumentV1
+pub fn rhi::RhiConfigDocumentV1::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiConfigV1Error
+impl rhi::RhiConfigV1Error
+pub const fn rhi::RhiConfigV1Error::kind(self) -> rhi::RhiConfigV1ErrorKind
+impl core::error::Error for rhi::RhiConfigV1Error
+impl core::fmt::Debug for rhi::RhiConfigV1Error
+pub fn rhi::RhiConfigV1Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiConfigV1Error
+pub fn rhi::RhiConfigV1Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiCredentialResolutionError
+impl rhi::RhiCredentialResolutionError
+pub const fn rhi::RhiCredentialResolutionError::code(self) -> &'static str
+pub const fn rhi::RhiCredentialResolutionError::kind(self) -> rhi::RhiCredentialResolutionErrorKind
+impl core::error::Error for rhi::RhiCredentialResolutionError
+impl core::fmt::Debug for rhi::RhiCredentialResolutionError
+pub fn rhi::RhiCredentialResolutionError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiCredentialResolutionError
+pub fn rhi::RhiCredentialResolutionError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiDecryptedIdentity
+impl rhi::RhiDecryptedIdentity
+pub fn rhi::RhiDecryptedIdentity::public_identity(&self) -> &rhi::RhiExpectedPublicIdentity
+impl core::fmt::Debug for rhi::RhiDecryptedIdentity
+pub fn rhi::RhiDecryptedIdentity::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiDesiredPresenceRepository<'host>
+impl rhi::RhiDesiredPresenceRepository<'_>
+pub const fn rhi::RhiDesiredPresenceRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiDesiredPresenceRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiDesiredPresenceRepository<'_>
+pub fn rhi::RhiDesiredPresenceRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiDirtyTradeRepository<'host>
+impl rhi::RhiDirtyTradeRepository<'_>
+pub const fn rhi::RhiDirtyTradeRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiDirtyTradeRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiDirtyTradeRepository<'_>
+pub fn rhi::RhiDirtyTradeRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiEffectiveConfigV1
+impl rhi::RhiEffectiveConfigV1
+pub fn rhi::RhiEffectiveConfigV1::canonical_json(&self) -> &str
+pub const fn rhi::RhiEffectiveConfigV1::field_count(&self) -> usize
+impl core::fmt::Debug for rhi::RhiEffectiveConfigV1
+pub fn rhi::RhiEffectiveConfigV1::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiEncryptedIdentityEnvelopeError
+impl rhi::RhiEncryptedIdentityEnvelopeError
+pub const fn rhi::RhiEncryptedIdentityEnvelopeError::code(self) -> &'static str
+pub const fn rhi::RhiEncryptedIdentityEnvelopeError::kind(self) -> rhi::RhiEncryptedIdentityEnvelopeErrorKind
+impl core::error::Error for rhi::RhiEncryptedIdentityEnvelopeError
+impl core::fmt::Debug for rhi::RhiEncryptedIdentityEnvelopeError
+pub fn rhi::RhiEncryptedIdentityEnvelopeError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiEncryptedIdentityEnvelopeError
+pub fn rhi::RhiEncryptedIdentityEnvelopeError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiEncryptedIdentityProvisioningMaterial
+impl rhi::RhiEncryptedIdentityProvisioningMaterial
+pub fn rhi::RhiEncryptedIdentityProvisioningMaterial::new([u8; 32], [u8; 32], [u8; 24], [u8; 24]) -> core::result::Result<Self, rhi::RhiEncryptedIdentityEnvelopeError>
+impl core::fmt::Debug for rhi::RhiEncryptedIdentityProvisioningMaterial
+pub fn rhi::RhiEncryptedIdentityProvisioningMaterial::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiEvidenceManifestRepository<'host>
+impl rhi::RhiEvidenceManifestRepository<'_>
+pub const fn rhi::RhiEvidenceManifestRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiEvidenceManifestRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiEvidenceManifestRepository<'_>
+pub fn rhi::RhiEvidenceManifestRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiEvidencePolicyDigest(_)
+impl rhi::RhiEvidencePolicyDigest
+pub const fn rhi::RhiEvidencePolicyDigest::as_bytes(&self) -> &[u8; 32]
+impl core::fmt::Debug for rhi::RhiEvidencePolicyDigest
+pub fn rhi::RhiEvidencePolicyDigest::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiExpectedPublicIdentity(_)
+impl rhi::RhiExpectedPublicIdentity
+pub fn rhi::RhiExpectedPublicIdentity::as_hex(&self) -> &str
+impl core::fmt::Debug for rhi::RhiExpectedPublicIdentity
+pub fn rhi::RhiExpectedPublicIdentity::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiIdentityEnvelopeBinding
+impl rhi::RhiIdentityEnvelopeBinding
+pub const fn rhi::RhiIdentityEnvelopeBinding::expected_identity(&self) -> &rhi::RhiExpectedPublicIdentity
+pub fn rhi::RhiIdentityEnvelopeBinding::from_configuration(&rhi::RhiConfigDocumentV1, &rhi::RhiStateMetadata) -> core::result::Result<Self, rhi::RhiEncryptedIdentityEnvelopeError>
+pub const fn rhi::RhiIdentityEnvelopeBinding::kind(&self) -> rhi::RhiIdentityProviderKind
+pub const fn rhi::RhiIdentityEnvelopeBinding::role(&self) -> rhi::RhiIdentityRole
+impl core::fmt::Debug for rhi::RhiIdentityEnvelopeBinding
+pub fn rhi::RhiIdentityEnvelopeBinding::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiMutationRepository<'host>
+impl rhi::RhiMutationRepository<'_>
+pub const fn rhi::RhiMutationRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiMutationRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiMutationRepository<'_>
+pub fn rhi::RhiMutationRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiNormalizedConfigDigest(_)
+impl rhi::RhiNormalizedConfigDigest
+pub const fn rhi::RhiNormalizedConfigDigest::as_bytes(&self) -> &[u8; 32]
+impl core::fmt::Debug for rhi::RhiNormalizedConfigDigest
+pub fn rhi::RhiNormalizedConfigDigest::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiProjectionRepository<'host>
+impl rhi::RhiProjectionRepository<'_>
+pub const fn rhi::RhiProjectionRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiProjectionRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiProjectionRepository<'_>
+pub fn rhi::RhiProjectionRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiProvenanceRepository<'host>
+impl rhi::RhiProvenanceRepository<'_>
+pub const fn rhi::RhiProvenanceRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiProvenanceRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiProvenanceRepository<'_>
+pub fn rhi::RhiProvenanceRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiPublicationAttemptRepository<'host>
+impl rhi::RhiPublicationAttemptRepository<'_>
+pub const fn rhi::RhiPublicationAttemptRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiPublicationAttemptRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiPublicationAttemptRepository<'_>
+pub fn rhi::RhiPublicationAttemptRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiPublicationOutboxRepository<'host>
+impl rhi::RhiPublicationOutboxRepository<'_>
+pub const fn rhi::RhiPublicationOutboxRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiPublicationOutboxRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiPublicationOutboxRepository<'_>
+pub fn rhi::RhiPublicationOutboxRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiPublicationTargetRepository<'host>
+impl rhi::RhiPublicationTargetRepository<'_>
+pub const fn rhi::RhiPublicationTargetRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiPublicationTargetRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiPublicationTargetRepository<'_>
+pub fn rhi::RhiPublicationTargetRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiReconciliationAttemptRepository<'host>
+impl rhi::RhiReconciliationAttemptRepository<'_>
+pub const fn rhi::RhiReconciliationAttemptRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiReconciliationAttemptRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiReconciliationAttemptRepository<'_>
+pub fn rhi::RhiReconciliationAttemptRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiReconciliationJobRepository<'host>
+impl rhi::RhiReconciliationJobRepository<'_>
+pub const fn rhi::RhiReconciliationJobRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiReconciliationJobRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiReconciliationJobRepository<'_>
+pub fn rhi::RhiReconciliationJobRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiReportRepository<'host>
+impl rhi::RhiReportRepository<'_>
+pub const fn rhi::RhiReportRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiReportRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiReportRepository<'_>
+pub fn rhi::RhiReportRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiRuntimeContext
+impl rhi::RhiRuntimeContext
+pub const fn rhi::RhiRuntimeContext::artifacts(&self) -> &radroots_runtime_paths::conventions::RadrootsServiceInstanceArtifacts
+pub const fn rhi::RhiRuntimeContext::context(&self) -> &radroots_runtime_paths::context::RuntimeContext
+pub fn rhi::RhiRuntimeContext::identity_path(&self) -> &std::path::Path
+pub const fn rhi::RhiRuntimeContext::profile(&self) -> rhi::RhiBootstrapProfileV1
+pub fn rhi::RhiRuntimeContext::selected_config_path(&self) -> &std::path::Path
+impl core::fmt::Debug for rhi::RhiRuntimeContext
+pub fn rhi::RhiRuntimeContext::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiRuntimeContextError
+impl rhi::RhiRuntimeContextError
+pub const fn rhi::RhiRuntimeContextError::kind(self) -> rhi::RhiRuntimeContextErrorKind
+impl core::error::Error for rhi::RhiRuntimeContextError
+impl core::fmt::Debug for rhi::RhiRuntimeContextError
+pub fn rhi::RhiRuntimeContextError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiRuntimeContextError
+pub fn rhi::RhiRuntimeContextError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiRuntimeThreadLimitsV1
+impl rhi::RhiRuntimeThreadLimitsV1
+pub const fn rhi::RhiRuntimeThreadLimitsV1::blocking_threads(self) -> usize
+pub const fn rhi::RhiRuntimeThreadLimitsV1::worker_threads(self) -> usize
+pub struct rhi::RhiSignedAttestationEventRepository<'host>
+impl rhi::RhiSignedAttestationEventRepository<'_>
+pub const fn rhi::RhiSignedAttestationEventRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiSignedAttestationEventRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiSignedAttestationEventRepository<'_>
+pub fn rhi::RhiSignedAttestationEventRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiSignedEventRepository<'host>
+impl rhi::RhiSignedEventRepository<'_>
+pub const fn rhi::RhiSignedEventRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiSignedEventRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiSignedEventRepository<'_>
+pub fn rhi::RhiSignedEventRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiSourceCompletionRepository<'host>
+impl rhi::RhiSourceCompletionRepository<'_>
+pub const fn rhi::RhiSourceCompletionRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiSourceCompletionRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiSourceCompletionRepository<'_>
+pub fn rhi::RhiSourceCompletionRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiSourceCursorRepository<'host>
+impl rhi::RhiSourceCursorRepository<'_>
+pub const fn rhi::RhiSourceCursorRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiSourceCursorRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiSourceCursorRepository<'_>
+pub fn rhi::RhiSourceCursorRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiSourceRepository<'host>
+impl rhi::RhiSourceRepository<'_>
+pub const fn rhi::RhiSourceRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiSourceRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiSourceRepository<'_>
+pub fn rhi::RhiSourceRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStagedStateRestore
+impl core::fmt::Debug for rhi::RhiStagedStateRestore
+pub fn rhi::RhiStagedStateRestore::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStateCatalogError
+impl rhi::RhiStateCatalogError
+pub const fn rhi::RhiStateCatalogError::code(self) -> &'static str
+pub const fn rhi::RhiStateCatalogError::kind(self) -> rhi::RhiStateCatalogErrorKind
+impl core::error::Error for rhi::RhiStateCatalogError
+impl core::fmt::Debug for rhi::RhiStateCatalogError
+pub fn rhi::RhiStateCatalogError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiStateCatalogError
+pub fn rhi::RhiStateCatalogError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStateHost
+impl rhi::RhiStateHost
+pub async fn rhi::RhiStateHost::capture_online_backup(&self, &std::path::Path, radroots_service_sqlite::backup::manifest::BackupCreatedAtUnixMs) -> core::result::Result<radroots_service_sqlite::backup::manifest::ServiceBackupManifest, rhi::RhiStateMaintenanceError>
+pub async fn rhi::RhiStateHost::close(&self) -> core::result::Result<(), rhi::RhiStateHostError>
+pub async fn rhi::RhiStateHost::inspect_integrity(&self, radroots_service_sqlite::integrity::inspection::IntegrityCheckedAtUnixMs) -> core::result::Result<radroots_service_sqlite::integrity::inspection::ServiceSqliteIntegrityReport, rhi::RhiStateMaintenanceError>
+pub const fn rhi::RhiStateHost::metadata(&self) -> &rhi::RhiStateMetadata
+pub const fn rhi::RhiStateHost::mode(&self) -> rhi::RhiStateHostMode
+pub const fn rhi::RhiStateHost::repositories(&self) -> rhi::RhiStateRepositories<'_>
+impl core::fmt::Debug for rhi::RhiStateHost
+pub fn rhi::RhiStateHost::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStateHostError
+impl rhi::RhiStateHostError
+pub const fn rhi::RhiStateHostError::code(self) -> &'static str
+pub const fn rhi::RhiStateHostError::kind(self) -> rhi::RhiStateHostErrorKind
+impl core::error::Error for rhi::RhiStateHostError
+impl core::fmt::Debug for rhi::RhiStateHostError
+pub fn rhi::RhiStateHostError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiStateHostError
+pub fn rhi::RhiStateHostError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStateMaintenanceError
+impl rhi::RhiStateMaintenanceError
+pub const fn rhi::RhiStateMaintenanceError::code(self) -> &'static str
+pub const fn rhi::RhiStateMaintenanceError::kind(self) -> rhi::RhiStateMaintenanceErrorKind
+impl core::error::Error for rhi::RhiStateMaintenanceError
+impl core::fmt::Debug for rhi::RhiStateMaintenanceError
+pub fn rhi::RhiStateMaintenanceError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiStateMaintenanceError
+pub fn rhi::RhiStateMaintenanceError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStateMetadata
+impl rhi::RhiStateMetadata
+pub const fn rhi::RhiStateMetadata::configuration_digest(&self) -> rhi::RhiNormalizedConfigDigest
+pub const fn rhi::RhiStateMetadata::database(&self) -> &radroots_service_sqlite::metadata::ServiceDatabaseMetadata
+pub fn rhi::RhiStateMetadata::database_identity(&self) -> radroots_service_sqlite::metadata::ServiceDatabaseIdentity
+pub const fn rhi::RhiStateMetadata::evidence_policy_digest(&self) -> rhi::RhiEvidencePolicyDigest
+pub const fn rhi::RhiStateMetadata::expected_identity(&self) -> &rhi::RhiExpectedPublicIdentity
+pub fn rhi::RhiStateMetadata::new(&rhi::RhiRuntimeContext, &rhi::RhiConfigDocumentV1, radroots_storage::event::SourceGeneration, u64) -> core::result::Result<Self, rhi::RhiStateMetadataError>
+pub const fn rhi::RhiStateMetadata::policy_versions(&self) -> rhi::RhiStatePolicyVersions
+impl core::fmt::Debug for rhi::RhiStateMetadata
+pub fn rhi::RhiStateMetadata::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStateMetadataError
+impl rhi::RhiStateMetadataError
+pub const fn rhi::RhiStateMetadataError::kind(self) -> rhi::RhiStateMetadataErrorKind
+impl core::error::Error for rhi::RhiStateMetadataError
+impl core::fmt::Debug for rhi::RhiStateMetadataError
+pub fn rhi::RhiStateMetadataError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for rhi::RhiStateMetadataError
+pub fn rhi::RhiStateMetadataError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStatePolicyVersions
+impl rhi::RhiStatePolicyVersions
+pub const fn rhi::RhiStatePolicyVersions::admin(self) -> u32
+pub const fn rhi::RhiStatePolicyVersions::configuration(self) -> u32
+pub const fn rhi::RhiStatePolicyVersions::provider(self) -> u32
+pub const fn rhi::RhiStatePolicyVersions::state(self) -> u32
+pub const fn rhi::RhiStatePolicyVersions::status(self) -> u32
+pub struct rhi::RhiStateRepositories<'host>
+impl<'host> rhi::RhiStateRepositories<'host>
+pub const fn rhi::RhiStateRepositories<'host>::desired_presence(&self) -> rhi::RhiDesiredPresenceRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::dirty_trades(&self) -> rhi::RhiDirtyTradeRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::evidence_manifests(&self) -> rhi::RhiEvidenceManifestRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::mutations(&self) -> rhi::RhiMutationRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::projections(&self) -> rhi::RhiProjectionRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::provenance(&self) -> rhi::RhiProvenanceRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::publication_attempts(&self) -> rhi::RhiPublicationAttemptRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::publication_outbox(&self) -> rhi::RhiPublicationOutboxRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::publication_targets(&self) -> rhi::RhiPublicationTargetRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::reconciliation_attempts(&self) -> rhi::RhiReconciliationAttemptRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::reconciliation_jobs(&self) -> rhi::RhiReconciliationJobRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::reports(&self) -> rhi::RhiReportRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::signed_attestation_events(&self) -> rhi::RhiSignedAttestationEventRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::signed_events(&self) -> rhi::RhiSignedEventRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::source_completions(&self) -> rhi::RhiSourceCompletionRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::source_cursors(&self) -> rhi::RhiSourceCursorRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::sources(&self) -> rhi::RhiSourceRepository<'host>
+pub const fn rhi::RhiStateRepositories<'host>::supersessions(&self) -> rhi::RhiSupersessionRepository<'host>
+impl core::fmt::Debug for rhi::RhiStateRepositories<'_>
+pub fn rhi::RhiStateRepositories<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiStateRepositoryDescriptor
+impl rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiStateRepositoryDescriptor::backing_table(self) -> &'static str
+pub const fn rhi::RhiStateRepositoryDescriptor::code(self) -> &'static str
+pub const fn rhi::RhiStateRepositoryDescriptor::kind(self) -> rhi::RhiStateRepositoryKind
+pub const fn rhi::RhiStateRepositoryDescriptor::write_class(self) -> rhi::RhiStateRepositoryWriteClass
+impl core::fmt::Debug for rhi::RhiStateRepositoryDescriptor
+pub fn rhi::RhiStateRepositoryDescriptor::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiSupersessionRepository<'host>
+impl rhi::RhiSupersessionRepository<'_>
+pub const fn rhi::RhiSupersessionRepository<'_>::descriptor(&self) -> rhi::RhiStateRepositoryDescriptor
+pub const fn rhi::RhiSupersessionRepository<'_>::kind(&self) -> rhi::RhiStateRepositoryKind
+impl core::fmt::Debug for rhi::RhiSupersessionRepository<'_>
+pub fn rhi::RhiSupersessionRepository<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiVerifiedStateBackup
+impl rhi::RhiVerifiedStateBackup
+pub const fn rhi::RhiVerifiedStateBackup::database_metadata(&self) -> &radroots_service_sqlite::metadata::ServiceDatabaseMetadata
+pub const fn rhi::RhiVerifiedStateBackup::manifest(&self) -> &radroots_service_sqlite::backup::manifest::ServiceBackupManifest
+impl core::fmt::Debug for rhi::RhiVerifiedStateBackup
+pub fn rhi::RhiVerifiedStateBackup::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::RhiWrappingCredential(_)
+impl core::fmt::Debug for rhi::RhiWrappingCredential
+pub fn rhi::RhiWrappingCredential::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::TradeAgreementAttestationError
+impl rhi::TradeAgreementAttestationError
+pub const fn rhi::TradeAgreementAttestationError::code(self) -> &'static str
+pub const fn rhi::TradeAgreementAttestationError::kind(self) -> rhi::TradeAgreementAttestationErrorKind
+impl core::fmt::Debug for rhi::TradeAgreementAttestationError
+pub fn rhi::TradeAgreementAttestationError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::TradeAgreementAttestationPolicy
+pub rhi::TradeAgreementAttestationPolicy::backend: rhi::TradeAgreementAttestationBackend
+pub rhi::TradeAgreementAttestationPolicy::expected_statement_contract_hash: core::option::Option<alloc::string::String>
+pub rhi::TradeAgreementAttestationPolicy::validator_set_addr: core::option::Option<alloc::string::String>
+pub rhi::TradeAgreementAttestationPolicy::validator_set_event_id: core::option::Option<alloc::string::String>
+impl rhi::TradeAgreementAttestationPolicy
+pub fn rhi::TradeAgreementAttestationPolicy::validate(&self) -> core::result::Result<(), rhi::TradeAgreementAttestationError>
+impl core::fmt::Debug for rhi::TradeAgreementAttestationPolicy
+pub fn rhi::TradeAgreementAttestationPolicy::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::TradeAgreementAttestationReportV1
+pub rhi::TradeAgreementAttestationReportV1::attestation_id: alloc::string::String
+pub rhi::TradeAgreementAttestationReportV1::proof_identity_hash: alloc::string::String
+pub rhi::TradeAgreementAttestationReportV1::proof_system: alloc::string::String
+pub rhi::TradeAgreementAttestationReportV1::report_version: u16
+pub rhi::TradeAgreementAttestationReportV1::result: radroots_trade::trade_contract_v1::RadrootsTradeAttestationResultV1
+pub rhi::TradeAgreementAttestationReportV1::statement: rhi::TradeAgreementAttestationStatementV1
+pub rhi::TradeAgreementAttestationReportV1::statement_hash: alloc::string::String
+impl core::fmt::Debug for rhi::TradeAgreementAttestationReportV1
+pub fn rhi::TradeAgreementAttestationReportV1::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::TradeAgreementAttestationStatementV1
+pub rhi::TradeAgreementAttestationStatementV1::active_agreement_claim_ids: alloc::vec::Vec<alloc::string::String>
+pub rhi::TradeAgreementAttestationStatementV1::agreement_state: radroots_trade::trade_contract_v1::RadrootsTradeAgreementStateV1
+pub rhi::TradeAgreementAttestationStatementV1::attestation_state_before_report: radroots_trade::trade_contract_v1::RadrootsTradeAttestationStateV1
+pub rhi::TradeAgreementAttestationStatementV1::cancelled_claim_ids: alloc::vec::Vec<alloc::string::String>
+pub rhi::TradeAgreementAttestationStatementV1::claim_mutation_id: alloc::string::String
+pub rhi::TradeAgreementAttestationStatementV1::contested_claim_ids: alloc::vec::Vec<alloc::string::String>
+pub rhi::TradeAgreementAttestationStatementV1::evidence_state: radroots_trade::trade_contract_v1::RadrootsTradeEvidenceStateV1
+pub rhi::TradeAgreementAttestationStatementV1::projection_digest: alloc::string::String
+pub rhi::TradeAgreementAttestationStatementV1::protocol_id: alloc::string::String
+pub rhi::TradeAgreementAttestationStatementV1::reducer_contract_id: alloc::string::String
+pub rhi::TradeAgreementAttestationStatementV1::reducer_version: u16
+pub rhi::TradeAgreementAttestationStatementV1::schema_version: u16
+pub rhi::TradeAgreementAttestationStatementV1::trade_id: alloc::string::String
+pub rhi::TradeAgreementAttestationStatementV1::validator_set: core::option::Option<rhi::TradeAgreementAttestationValidatorSetBinding>
+impl core::fmt::Debug for rhi::TradeAgreementAttestationStatementV1
+pub fn rhi::TradeAgreementAttestationStatementV1::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct rhi::TradeAgreementAttestationValidatorSetBinding
+pub rhi::TradeAgreementAttestationValidatorSetBinding::validator_set_addr: alloc::string::String
+pub rhi::TradeAgreementAttestationValidatorSetBinding::validator_set_event_id: alloc::string::String
+impl core::fmt::Debug for rhi::TradeAgreementAttestationValidatorSetBinding
+pub fn rhi::TradeAgreementAttestationValidatorSetBinding::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub const rhi::RHI_ADMIN_CONTRACT_VERSION: u32
+pub const rhi::RHI_AGREEMENT_ATTESTATION_PROOF_SYSTEM_LOCAL_STATEMENT_HASH: &str
+pub const rhi::RHI_AGREEMENT_ATTESTATION_PROTOCOL_ID: &str
+pub const rhi::RHI_AGREEMENT_ATTESTATION_REPORT_VERSION: u16
+pub const rhi::RHI_CONFIG_DOCUMENT_MAX_UTF8_BYTES: usize
+pub const rhi::RHI_CONFIG_EFFECTIVE_MAX_UTF8_BYTES: usize
+pub const rhi::RHI_CONFIG_SCHEMA: &str
+pub const rhi::RHI_CONFIG_SCHEMA_VERSION: u32
+pub const rhi::RHI_ENCRYPTED_IDENTITY_BACKUP_INCLUDED: bool
+pub const rhi::RHI_ENCRYPTED_IDENTITY_ENVELOPE_CONTRACT_VERSION: u32
+pub const rhi::RHI_ENCRYPTED_IDENTITY_ENVELOPE_MAX_BYTES: usize
+pub const rhi::RHI_MIGRATION_CATALOG_SHA256: [u8; 32]
+pub const rhi::RHI_PROVIDER_CONTRACT_VERSION: u32
+pub const rhi::RHI_STATE_APPLICATION_ID: u32
+pub const rhi::RHI_STATE_REPOSITORY_CONTRACT_VERSION: u32
+pub const rhi::RHI_STATE_REPOSITORY_COUNT: usize
+pub const rhi::RHI_STATE_SCHEMA_CATALOG_SHA256: [u8; 32]
+pub const rhi::RHI_STATE_SCHEMA_VERSION: u32
+pub const rhi::RHI_STATE_SCHEMA_VERSION_1_OBJECT_COUNT: u32
+pub const rhi::RHI_STATE_SCHEMA_VERSION_1_SHA256: [u8; 32]
+pub const rhi::RHI_STATUS_CONTRACT_VERSION: u32
+pub const rhi::RHI_WRAPPING_CREDENTIAL_ARTIFACT_BYTES: usize
+pub const rhi::RHI_WRAPPING_CREDENTIAL_CONTRACT_VERSION: u32
+pub fn rhi::attest_projection_claim(&radroots_trade::trade_contract_v1::RadrootsTradeProjectionV1, &radroots_event::id::MutationId, &rhi::TradeAgreementAttestationPolicy) -> core::result::Result<rhi::TradeAgreementAttestationReportV1, rhi::TradeAgreementAttestationError>
+pub async fn rhi::finalize_rhi_state_restore(rhi::RhiStagedStateRestore) -> core::result::Result<(), rhi::RhiStateMaintenanceError>
+pub async fn rhi::initialize_rhi_state(&rhi::RhiRuntimeContext, &rhi::RhiStateMetadata, radroots_service_sqlite::migration::MigrationAppliedAtUnixSeconds, &radroots_service_sqlite::migration::MigrationBuildIdentity) -> core::result::Result<(), rhi::RhiStateHostError>
+pub fn rhi::open_rhi_encrypted_identity(&rhi::RhiIdentityEnvelopeBinding, &rhi::RhiWrappingCredential) -> core::result::Result<rhi::RhiDecryptedIdentity, rhi::RhiEncryptedIdentityEnvelopeError>
+pub async fn rhi::open_rhi_state_inspection(&rhi::RhiRuntimeContext, &rhi::RhiStateMetadata) -> core::result::Result<rhi::RhiStateHost, rhi::RhiStateHostError>
+pub async fn rhi::open_rhi_state_read_write(&rhi::RhiRuntimeContext, &rhi::RhiStateMetadata, radroots_service_sqlite::migration::MigrationAppliedAtUnixSeconds, &radroots_service_sqlite::migration::MigrationBuildIdentity) -> core::result::Result<rhi::RhiStateHost, rhi::RhiStateHostError>
+pub fn rhi::parse_rhi_cli_v1_from<I, T>(I) -> core::result::Result<rhi::RhiCliInvocationV1, rhi::RhiCliV1Error> where I: core::iter::traits::collect::IntoIterator<Item = T>, T: core::convert::Into<std::ffi::os_str::OsString> + core::clone::Clone
+pub fn rhi::parse_rhi_config_v1(&[u8], rhi::RhiConfigProfile) -> core::result::Result<rhi::RhiConfigDocumentV1, rhi::RhiConfigV1Error>
+pub fn rhi::provision_rhi_encrypted_identity(&rhi::RhiIdentityEnvelopeBinding, &rhi::RhiWrappingCredential, rhi::RhiEncryptedIdentityProvisioningMaterial) -> core::result::Result<rhi::RhiDecryptedIdentity, rhi::RhiEncryptedIdentityEnvelopeError>
+pub fn rhi::resolve_rhi_runtime_context(&radroots_runtime_paths::roots::RadrootsPathResolver, &rhi::RhiCliInvocationV1) -> core::result::Result<rhi::RhiRuntimeContext, rhi::RhiRuntimeContextError>
+pub fn rhi::resolve_rhi_wrapping_credential(&rhi::RhiRuntimeContext, &rhi::RhiIdentityEnvelopeBinding) -> core::result::Result<rhi::RhiWrappingCredential, rhi::RhiCredentialResolutionError>
+pub fn rhi::rhi_migration_catalog() -> core::result::Result<radroots_service_sqlite::migration::MigrationCatalog, rhi::RhiStateCatalogError>
+pub fn rhi::rhi_schema_catalog() -> core::result::Result<radroots_service_sqlite::integrity::catalog::SchemaCatalog, rhi::RhiStateCatalogError>
+pub const fn rhi::rhi_state_repository_descriptors() -> &'static [rhi::RhiStateRepositoryDescriptor; 18]
+pub async fn rhi::stage_rhi_state_restore(&rhi::RhiRuntimeContext, &rhi::RhiStateMetadata, rhi::RhiVerifiedStateBackup) -> core::result::Result<rhi::RhiStagedStateRestore, rhi::RhiStateMaintenanceError>
+pub fn rhi::trade_mutation_subscription_kinds() -> alloc::vec::Vec<u32>
+pub fn rhi::validate_rhi_state_catalogs(&radroots_service_sqlite::migration::MigrationCatalog, &radroots_service_sqlite::integrity::catalog::SchemaCatalog) -> core::result::Result<(), rhi::RhiStateCatalogError>
+pub fn rhi::verify_rhi_state_backup(&[u8], radroots_service_sqlite::backup::manifest::BackupManifestSha256, &std::path::Path, &rhi::RhiStateMetadata, core::num::nonzero::NonZeroU64) -> core::result::Result<rhi::RhiVerifiedStateBackup, rhi::RhiStateMaintenanceError>
diff --git a/src/adapters/mod.rs b/src/adapters/mod.rs
@@ -1 +1 @@
-pub mod nostr;
+pub(crate) mod nostr;
diff --git a/src/adapters/nostr/event.rs b/src/adapters/nostr/event.rs
@@ -1,13 +1,21 @@
+use core::fmt;
+
use nostr::{Event, Kind};
use radroots_event_codec::decode::job::{JobEventBorrow, JobEventLike};
-#[derive(Clone, Debug)]
+#[derive(Clone)]
pub struct NostrEventAdapter<'a> {
evt: &'a Event,
id_hex: String,
author_hex: String,
}
+impl fmt::Debug for NostrEventAdapter<'_> {
+ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("NostrEventAdapter([redacted])")
+ }
+}
+
impl<'a> NostrEventAdapter<'a> {
#[inline]
pub fn new(evt: &'a Event) -> Self {
@@ -100,6 +108,7 @@ mod tests {
let tags = vec![Tag::custom(TagKind::p(), vec![recipient_hex.clone()])];
let event = build_event(&keys, Kind::Custom(5322), tags);
let adapter = NostrEventAdapter::new(&event);
+ assert_eq!(format!("{adapter:?}"), "NostrEventAdapter([redacted])");
assert_eq!(JobEventBorrow::raw_id(&adapter), event.id.to_hex());
assert_eq!(
diff --git a/src/adapters/nostr/mod.rs b/src/adapters/nostr/mod.rs
@@ -1 +1 @@
-pub mod event;
+pub(crate) mod event;
diff --git a/src/features/mod.rs b/src/features/mod.rs
@@ -1 +1 @@
-pub mod trade_agreement_attestation;
+pub(crate) mod trade_agreement_attestation;
diff --git a/src/features/trade_agreement_attestation.rs b/src/features/trade_agreement_attestation.rs
@@ -33,7 +33,7 @@ impl TradeAgreementAttestationBackend {
}
}
-#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TradeAgreementAttestationPolicy {
#[serde(default)]
@@ -46,6 +46,12 @@ pub struct TradeAgreementAttestationPolicy {
pub expected_statement_contract_hash: Option<String>,
}
+impl core::fmt::Debug for TradeAgreementAttestationPolicy {
+ fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ formatter.write_str("TradeAgreementAttestationPolicy([redacted])")
+ }
+}
+
impl TradeAgreementAttestationPolicy {
pub fn validate(&self) -> Result<(), TradeAgreementAttestationError> {
validate_optional_hash32(&self.expected_statement_contract_hash)?;
@@ -55,21 +61,20 @@ impl TradeAgreementAttestationPolicy {
) {
(Some(addr), Some(event_id)) => {
AddressableCoordinate::parse(addr).map_err(|_| {
- TradeAgreementAttestationError::InvalidValidatorSetBinding("validator_set_addr")
+ TradeAgreementAttestationError::new(
+ TradeAgreementAttestationErrorKind::InvalidValidatorSetBinding,
+ )
})?;
EventId::parse(event_id).map_err(|_| {
- TradeAgreementAttestationError::InvalidValidatorSetBinding(
- "validator_set_event_id",
+ TradeAgreementAttestationError::new(
+ TradeAgreementAttestationErrorKind::InvalidValidatorSetBinding,
)
})?;
Ok(())
}
(None, None) => Ok(()),
- (Some(_), None) => Err(TradeAgreementAttestationError::MissingValidatorSetBinding(
- "validator_set_event_id",
- )),
- (None, Some(_)) => Err(TradeAgreementAttestationError::MissingValidatorSetBinding(
- "validator_set_addr",
+ (Some(_), None) | (None, Some(_)) => Err(TradeAgreementAttestationError::new(
+ TradeAgreementAttestationErrorKind::MissingValidatorSetBinding,
)),
}
}
@@ -94,14 +99,20 @@ impl TradeAgreementAttestationPolicy {
}
}
-#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TradeAgreementAttestationValidatorSetBinding {
pub validator_set_addr: String,
pub validator_set_event_id: String,
}
-#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+impl core::fmt::Debug for TradeAgreementAttestationValidatorSetBinding {
+ fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ formatter.write_str("TradeAgreementAttestationValidatorSetBinding([redacted])")
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TradeAgreementAttestationStatementV1 {
pub protocol_id: String,
@@ -121,7 +132,13 @@ pub struct TradeAgreementAttestationStatementV1 {
pub validator_set: Option<TradeAgreementAttestationValidatorSetBinding>,
}
-#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+impl core::fmt::Debug for TradeAgreementAttestationStatementV1 {
+ fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ formatter.write_str("TradeAgreementAttestationStatementV1([redacted])")
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TradeAgreementAttestationReportV1 {
pub report_version: u16,
@@ -133,20 +150,78 @@ pub struct TradeAgreementAttestationReportV1 {
pub proof_identity_hash: String,
}
-#[derive(Debug, Error)]
-pub enum TradeAgreementAttestationError {
- #[error("agreement claim is missing")]
+impl core::fmt::Debug for TradeAgreementAttestationReportV1 {
+ fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ formatter.write_str("TradeAgreementAttestationReportV1([redacted])")
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum TradeAgreementAttestationErrorKind {
MissingAgreementClaim,
- #[error("attestation policy is missing {0}")]
- MissingValidatorSetBinding(&'static str),
- #[error("attestation policy has invalid {0}")]
- InvalidValidatorSetBinding(&'static str),
- #[error("invalid configured hash field")]
+ MissingValidatorSetBinding,
+ InvalidValidatorSetBinding,
InvalidHashField,
- #[error("trade protocol error: {0}")]
- TradeProtocol(#[from] radroots_event::trade::TradeProtocolError),
- #[error("serde error: {0}")]
- Serde(#[from] serde_json::Error),
+ TradeProtocol,
+ Encoding,
+}
+
+impl TradeAgreementAttestationErrorKind {
+ #[must_use]
+ pub const fn code(self) -> &'static str {
+ match self {
+ Self::MissingAgreementClaim => "agreement_claim_missing",
+ Self::MissingValidatorSetBinding => "validator_set_binding_missing",
+ Self::InvalidValidatorSetBinding => "validator_set_binding_invalid",
+ Self::InvalidHashField => "configured_hash_invalid",
+ Self::TradeProtocol => "trade_protocol_invalid",
+ Self::Encoding => "attestation_encoding_failed",
+ }
+ }
+}
+
+impl core::fmt::Display for TradeAgreementAttestationErrorKind {
+ fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ formatter.write_str(match self {
+ Self::MissingAgreementClaim => "agreement claim is missing",
+ Self::MissingValidatorSetBinding => "attestation policy is incomplete",
+ Self::InvalidValidatorSetBinding => "attestation policy is invalid",
+ Self::InvalidHashField => "configured hash field is invalid",
+ Self::TradeProtocol => "trade protocol input is invalid",
+ Self::Encoding => "attestation encoding failed",
+ })
+ }
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Error)]
+#[error("{kind}")]
+pub struct TradeAgreementAttestationError {
+ kind: TradeAgreementAttestationErrorKind,
+}
+
+impl TradeAgreementAttestationError {
+ const fn new(kind: TradeAgreementAttestationErrorKind) -> Self {
+ Self { kind }
+ }
+
+ #[must_use]
+ pub const fn kind(self) -> TradeAgreementAttestationErrorKind {
+ self.kind
+ }
+
+ #[must_use]
+ pub const fn code(self) -> &'static str {
+ self.kind.code()
+ }
+}
+
+impl core::fmt::Debug for TradeAgreementAttestationError {
+ fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ formatter
+ .debug_struct("TradeAgreementAttestationError")
+ .field("kind", &self.kind)
+ .finish()
+ }
}
pub fn attest_projection_claim(
@@ -160,7 +235,9 @@ pub fn attest_projection_claim(
.iter()
.any(|claim| claim.claim_mutation_id() == claim_mutation_id)
{
- return Err(TradeAgreementAttestationError::MissingAgreementClaim);
+ return Err(TradeAgreementAttestationError::new(
+ TradeAgreementAttestationErrorKind::MissingAgreementClaim,
+ ));
}
let statement = TradeAgreementAttestationStatementV1 {
protocol_id: RHI_AGREEMENT_ATTESTATION_PROTOCOL_ID.to_owned(),
@@ -248,7 +325,9 @@ fn validate_optional_hash32(value: &Option<String>) -> Result<(), TradeAgreement
fn validate_hash32(value: &str) -> Result<(), TradeAgreementAttestationError> {
let stripped = value.strip_prefix("0x").unwrap_or(value);
if stripped.len() != 64 || !stripped.bytes().all(|byte| byte.is_ascii_hexdigit()) {
- return Err(TradeAgreementAttestationError::InvalidHashField);
+ return Err(TradeAgreementAttestationError::new(
+ TradeAgreementAttestationErrorKind::InvalidHashField,
+ ));
}
Ok(())
}
@@ -257,10 +336,92 @@ fn hash_canonical_value(
domain: &[u8],
value: &impl Serialize,
) -> Result<String, TradeAgreementAttestationError> {
- let value = serde_json::to_value(value)?;
- let canonical = canonical_jcs_value(&value)?;
+ let value = serde_json::to_value(value).map_err(|_| {
+ TradeAgreementAttestationError::new(TradeAgreementAttestationErrorKind::Encoding)
+ })?;
+ let canonical = canonical_jcs_value(&value).map_err(|_| {
+ TradeAgreementAttestationError::new(TradeAgreementAttestationErrorKind::TradeProtocol)
+ })?;
let mut hasher = Sha256::new();
hasher.update(domain);
hasher.update(canonical.as_bytes());
Ok(format!("{:x}", hasher.finalize()))
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn public_failures_are_closed_source_free_and_redacted() {
+ for kind in [
+ TradeAgreementAttestationErrorKind::MissingAgreementClaim,
+ TradeAgreementAttestationErrorKind::MissingValidatorSetBinding,
+ TradeAgreementAttestationErrorKind::InvalidValidatorSetBinding,
+ TradeAgreementAttestationErrorKind::InvalidHashField,
+ TradeAgreementAttestationErrorKind::TradeProtocol,
+ TradeAgreementAttestationErrorKind::Encoding,
+ ] {
+ let error = TradeAgreementAttestationError::new(kind);
+ assert_eq!(error.kind(), kind);
+ assert!(!error.code().is_empty());
+ assert!(std::error::Error::source(&error).is_none());
+ let rendered = format!("{error} {error:?}");
+ for forbidden in [
+ "validator_set_addr",
+ "validator_set_event_id",
+ "serde_json",
+ "TradeProtocolError",
+ "/tmp/",
+ ] {
+ assert!(!rendered.contains(forbidden));
+ }
+ }
+ }
+
+ #[test]
+ fn policy_failures_discard_field_values_and_dependency_causes() {
+ let missing_policy = TradeAgreementAttestationPolicy {
+ validator_set_addr: Some("secret:coordinate".to_owned()),
+ ..TradeAgreementAttestationPolicy::default()
+ };
+ assert_eq!(
+ format!("{missing_policy:?}"),
+ "TradeAgreementAttestationPolicy([redacted])"
+ );
+ let missing = missing_policy.validate().expect_err("partial binding");
+ assert_eq!(
+ missing.kind(),
+ TradeAgreementAttestationErrorKind::MissingValidatorSetBinding
+ );
+
+ let invalid = TradeAgreementAttestationPolicy {
+ validator_set_addr: Some("secret:coordinate".to_owned()),
+ validator_set_event_id: Some("secret:event".to_owned()),
+ ..TradeAgreementAttestationPolicy::default()
+ }
+ .validate()
+ .expect_err("invalid binding");
+ assert_eq!(
+ invalid.kind(),
+ TradeAgreementAttestationErrorKind::InvalidValidatorSetBinding
+ );
+
+ let hash = TradeAgreementAttestationPolicy {
+ expected_statement_contract_hash: Some("secret:hash".to_owned()),
+ ..TradeAgreementAttestationPolicy::default()
+ }
+ .validate()
+ .expect_err("invalid hash");
+ assert_eq!(
+ hash.kind(),
+ TradeAgreementAttestationErrorKind::InvalidHashField
+ );
+
+ let rendered = format!("{missing:?} {invalid:?} {hash:?}");
+ assert!(!rendered.contains("secret"));
+ assert!(!rendered.contains("coordinate"));
+ assert!(!rendered.contains("event"));
+ assert!(!rendered.contains("hash"));
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,9 +1,11 @@
#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
+#![forbid(unsafe_code)]
+#![doc = include_str!("../README")]
-pub mod adapters;
+mod adapters;
mod cli_v1;
mod config_v1;
-pub mod features;
+mod features;
mod identity_credential;
mod identity_envelope;
mod runtime_context;
@@ -13,6 +15,7 @@ mod state_maintenance;
mod state_metadata;
mod state_repository;
+pub use adapters::nostr::event::NostrEventAdapter;
pub use cli_v1::{
RhiBootstrapProfileV1, RhiCliInvocationV1, RhiCliOutputModeV1, RhiCliV1Error,
RhiCliV1ErrorKind, RhiCommandV1, RhiConfigCommandV1, RhiIdentityCommandV1, RhiMetricsCommandV1,
@@ -25,6 +28,15 @@ pub use config_v1::{
RhiConfigV1Error, RhiConfigV1ErrorKind, RhiConfigValueSource, RhiEffectiveConfigV1,
RhiRuntimeThreadLimitsV1, parse_rhi_config_v1,
};
+pub use features::trade_agreement_attestation::{
+ RHI_AGREEMENT_ATTESTATION_PROOF_SYSTEM_LOCAL_STATEMENT_HASH,
+ RHI_AGREEMENT_ATTESTATION_PROTOCOL_ID, RHI_AGREEMENT_ATTESTATION_REPORT_VERSION,
+ TradeAgreementAttestationBackend, TradeAgreementAttestationError,
+ TradeAgreementAttestationErrorKind, TradeAgreementAttestationPolicy,
+ TradeAgreementAttestationReportV1, TradeAgreementAttestationStatementV1,
+ TradeAgreementAttestationValidatorSetBinding, attest_projection_claim,
+ trade_mutation_subscription_kinds,
+};
pub use identity_credential::{
RHI_WRAPPING_CREDENTIAL_ARTIFACT_BYTES, RHI_WRAPPING_CREDENTIAL_CONTRACT_VERSION,
RhiCredentialResolutionError, RhiCredentialResolutionErrorKind,
diff --git a/tests/package_boundary.rs b/tests/package_boundary.rs
@@ -2,7 +2,26 @@
const MANIFEST: &str = include_str!("../Cargo.toml");
const README: &str = include_str!("../README");
+const AGENTS: &str = include_str!("../AGENTS.md");
const ROOT: &str = include_str!("../src/lib.rs");
+const ADAPTERS: &str = include_str!("../src/adapters/mod.rs");
+const NOSTR_ADAPTERS: &str = include_str!("../src/adapters/nostr/mod.rs");
+const FEATURES: &str = include_str!("../src/features/mod.rs");
+const PUBLIC_API: &str = include_str!("../contracts/api_baselines/rhi.txt");
+const SOURCES: &[&str] = &[
+ include_str!("../src/adapters/nostr/event.rs"),
+ include_str!("../src/cli_v1.rs"),
+ include_str!("../src/config_v1.rs"),
+ include_str!("../src/features/trade_agreement_attestation.rs"),
+ include_str!("../src/identity_credential.rs"),
+ include_str!("../src/identity_envelope.rs"),
+ include_str!("../src/runtime_context.rs"),
+ include_str!("../src/state_catalog.rs"),
+ include_str!("../src/state_host.rs"),
+ include_str!("../src/state_maintenance.rs"),
+ include_str!("../src/state_metadata.rs"),
+ include_str!("../src/state_repository.rs"),
+];
#[test]
fn package_identity_is_standalone_and_non_publishable() {
@@ -43,9 +62,37 @@ fn shared_host_implementations_do_not_escape_the_public_api() {
#[test]
fn state_catalog_module_is_private_and_root_api_is_curated() {
- assert!(ROOT.contains("mod state_catalog;"));
- assert!(!ROOT.contains("pub mod state_catalog;"));
+ for module in [
+ "adapters",
+ "cli_v1",
+ "config_v1",
+ "features",
+ "identity_credential",
+ "identity_envelope",
+ "runtime_context",
+ "state_catalog",
+ "state_host",
+ "state_maintenance",
+ "state_metadata",
+ "state_repository",
+ ] {
+ assert!(
+ ROOT.contains(&format!("mod {module};")),
+ "RHI root is missing private module {module}"
+ );
+ assert!(
+ !ROOT.contains(&format!("pub mod {module};")),
+ "RHI root exposes module {module}"
+ );
+ }
+ assert!(ADAPTERS.contains("pub(crate) mod nostr;"));
+ assert!(NOSTR_ADAPTERS.contains("pub(crate) mod event;"));
+ assert!(FEATURES.contains("pub(crate) mod trade_agreement_attestation;"));
+ assert!(ROOT.contains("#![doc = include_str!(\"../README\")]"));
for required in [
+ "NostrEventAdapter",
+ "TradeAgreementAttestationPolicy",
+ "TradeAgreementAttestationErrorKind",
"rhi_migration_catalog",
"rhi_schema_catalog",
"validate_rhi_state_catalogs",
@@ -56,6 +103,72 @@ fn state_catalog_module_is_private_and_root_api_is_curated() {
"RHI root API is missing {required}"
);
}
+
+ let public_modules = PUBLIC_API
+ .lines()
+ .filter(|line| line.starts_with("pub mod "))
+ .collect::<Vec<_>>();
+ assert_eq!(public_modules, ["pub mod rhi"]);
+ assert!(PUBLIC_API.contains("pub struct rhi::NostrEventAdapter<'a>"));
+ assert!(PUBLIC_API.contains("pub struct rhi::TradeAgreementAttestationError"));
+ assert!(!PUBLIC_API.contains("rhi::adapters::"));
+ assert!(!PUBLIC_API.contains("rhi::features::"));
+}
+
+#[test]
+fn public_errors_are_crate_owned_redacted_and_source_free() {
+ let production = SOURCES.join("\n");
+ assert!(!production.contains("fn source("));
+ for forbidden in [
+ "source: std::io::Error",
+ "source: sqlx::Error",
+ "source: serde_json::Error",
+ "source: toml::de::Error",
+ "source: url::ParseError",
+ ] {
+ assert!(
+ !production.contains(forbidden),
+ "raw error source `{forbidden}` escaped"
+ );
+ }
+ for forbidden in [
+ "serde_json::Error",
+ "radroots_event::trade::TradeProtocolError",
+ "sqlx::Error",
+ "std::io::Error",
+ "thiserror::",
+ ] {
+ assert!(
+ !PUBLIC_API.contains(forbidden),
+ "reviewed API exposes dependency error `{forbidden}`"
+ );
+ }
+ let public_error_count = PUBLIC_API
+ .lines()
+ .filter(|line| line.starts_with("pub struct rhi::") && line.ends_with("Error"))
+ .count();
+ assert_eq!(public_error_count, 10);
+}
+
+#[test]
+fn readme_freezes_the_root_only_boundary_and_exact_baseline() {
+ for required in [
+ "## Public API boundary",
+ "one curated crate-root API",
+ "public errors use RHI-owned stable classifications",
+ "```compile_fail",
+ "[RHI API baseline](contracts/api_baselines/rhi.txt)",
+ ] {
+ assert!(README.contains(required), "README is missing {required}");
+ }
+ for required in [
+ "Keep every implementation module private",
+ "contracts/api_baselines/rhi.txt",
+ "Public errors must use RHI-owned stable classifications",
+ "no raw dependency-owned source chain",
+ ] {
+ assert!(AGENTS.contains(required), "AGENTS is missing {required}");
+ }
}
#[test]