lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit b52a7a798516407ded7d33f914029880536a1fe8
parent 4ac3d4ddd79008f9bfc9ede30a95b6eedc06ff92
Author: triesap <tyson@radroots.org>
Date:   Thu,  9 Jul 2026 01:44:48 +0000

mesh_agent_proto: declare Transport V1 schema authority

Diffstat:
Mcrates/mesh_agent_proto/README | 8+++++---
Mcrates/mesh_agent_proto/schema/radroots_mesh_agent_v1.capnp | 32+++++++++++++++++++++++++-------
Mcrates/mesh_agent_proto/src/schema_validation.rs | 56+++++++++++++++++++++++++++++++++++++++++++++++++-------
Mcrates/mesh_agent_proto/tests/schema.rs | 95++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 173 insertions(+), 18 deletions(-)

diff --git a/crates/mesh_agent_proto/README b/crates/mesh_agent_proto/README @@ -5,10 +5,12 @@ agent protocol schema surface for the `radroots` core libraries. ## Overview - * Cap'n Proto schema text for the future `radroots.mesh_agent.v1` IPC surface; + * canonical Transport V1 Cap'n Proto schema text for the future + `radroots.mesh_agent.v1` IPC surface, superseding earlier handoff draft + schema text; * schema id and deterministic SHA-256 digest helpers; - * narrow validation helpers for required request, response, event, and error - schema declarations; + * narrow validation helpers for required request, response, status, Reticulum + transport, publish placeholder, receipt, and error schema declarations; * schema-only protocol posture without an agent runtime or IPC client. ## Copyright diff --git a/crates/mesh_agent_proto/schema/radroots_mesh_agent_v1.capnp b/crates/mesh_agent_proto/schema/radroots_mesh_agent_v1.capnp @@ -51,7 +51,7 @@ struct MeshAgentStatusResponse { } struct MeshAgentTransportStatus { - transportKind @0 :Text; + transportKind @0 :MeshAgentTransportKind; profileId @1 :Text; endpointUri @2 :Text; readiness @3 :MeshAgentReadinessState; @@ -69,30 +69,48 @@ enum MeshAgentReadinessState { } enum MeshAgentImplementationState { - available @0; - disabled @1; - misconfigured @2; - previewUnavailable @3; + previewNoop @0; + mock @1; + real @2; +} + +enum MeshAgentTransportKind { + reticulum @0; } struct MeshAgentPublishRequest { publishRequestId @0 :Text; payloadCbor @1 :Data; + eventId @2 :Text; + targetFingerprint @3 :Text; } struct MeshAgentPublishResponse { publishRequestId @0 :Text; status @1 :MeshAgentResponseStatus; transportReceipts @2 :List(MeshAgentTransportReceipt); + eventId @3 :Text; } struct MeshAgentTransportReceipt { - transportKind @0 :Text; + transportKind @0 :MeshAgentTransportKind; endpointUri @1 :Text; - deliveryStatus @2 :Text; + outcome @2 :MeshAgentTransportOutcome; redactedMessage @3 :Text; } +enum MeshAgentTransportOutcome { + accepted @0; + delivered @1; + forwarded @2; + storedByGateway @3; + deferredUntilImplemented @4; + rejected @5; + routeUnavailable @6; + timeout @7; + transportUnavailable @8; +} + struct MeshAgentError { code @0 :Text; message @1 :Text; diff --git a/crates/mesh_agent_proto/src/schema_validation.rs b/crates/mesh_agent_proto/src/schema_validation.rs @@ -96,7 +96,12 @@ const STATUS_FIELDS: &[RequiredField] = &[ 2, "List(MeshAgentTransportStatus)", ), - field("MeshAgentTransportStatus", "transportKind", 0, "Text"), + field( + "MeshAgentTransportStatus", + "transportKind", + 0, + "MeshAgentTransportKind", + ), field("MeshAgentTransportStatus", "profileId", 1, "Text"), field("MeshAgentTransportStatus", "endpointUri", 2, "Text"), field( @@ -124,15 +129,31 @@ const READINESS_VARIANTS: &[RequiredVariant] = &[ ]; const IMPLEMENTATION_VARIANTS: &[RequiredVariant] = &[ - variant("MeshAgentImplementationState", "available", 0), - variant("MeshAgentImplementationState", "disabled", 1), - variant("MeshAgentImplementationState", "misconfigured", 2), - variant("MeshAgentImplementationState", "previewUnavailable", 3), + variant("MeshAgentImplementationState", "previewNoop", 0), + variant("MeshAgentImplementationState", "mock", 1), + variant("MeshAgentImplementationState", "real", 2), +]; + +const TRANSPORT_KIND_VARIANTS: &[RequiredVariant] = + &[variant("MeshAgentTransportKind", "reticulum", 0)]; + +const TRANSPORT_OUTCOME_VARIANTS: &[RequiredVariant] = &[ + variant("MeshAgentTransportOutcome", "accepted", 0), + variant("MeshAgentTransportOutcome", "delivered", 1), + variant("MeshAgentTransportOutcome", "forwarded", 2), + variant("MeshAgentTransportOutcome", "storedByGateway", 3), + variant("MeshAgentTransportOutcome", "deferredUntilImplemented", 4), + variant("MeshAgentTransportOutcome", "rejected", 5), + variant("MeshAgentTransportOutcome", "routeUnavailable", 6), + variant("MeshAgentTransportOutcome", "timeout", 7), + variant("MeshAgentTransportOutcome", "transportUnavailable", 8), ]; const PUBLISH_FIELDS: &[RequiredField] = &[ field("MeshAgentPublishRequest", "publishRequestId", 0, "Text"), field("MeshAgentPublishRequest", "payloadCbor", 1, "Data"), + field("MeshAgentPublishRequest", "eventId", 2, "Text"), + field("MeshAgentPublishRequest", "targetFingerprint", 3, "Text"), field("MeshAgentPublishResponse", "publishRequestId", 0, "Text"), field( "MeshAgentPublishResponse", @@ -146,9 +167,20 @@ const PUBLISH_FIELDS: &[RequiredField] = &[ 2, "List(MeshAgentTransportReceipt)", ), - field("MeshAgentTransportReceipt", "transportKind", 0, "Text"), + field("MeshAgentPublishResponse", "eventId", 3, "Text"), + field( + "MeshAgentTransportReceipt", + "transportKind", + 0, + "MeshAgentTransportKind", + ), field("MeshAgentTransportReceipt", "endpointUri", 1, "Text"), - field("MeshAgentTransportReceipt", "deliveryStatus", 2, "Text"), + field( + "MeshAgentTransportReceipt", + "outcome", + 2, + "MeshAgentTransportOutcome", + ), field("MeshAgentTransportReceipt", "redactedMessage", 3, "Text"), ]; @@ -227,11 +259,21 @@ pub(crate) fn validate_schema_text(schema: &str) -> Result<(), RadrootsMeshAgent IMPLEMENTATION_VARIANTS, RadrootsMeshAgentProtoError::MissingStatusSurface, )?; + validate_variants( + &parsed, + TRANSPORT_KIND_VARIANTS, + RadrootsMeshAgentProtoError::MissingStatusSurface, + )?; validate_fields( &parsed, PUBLISH_FIELDS, RadrootsMeshAgentProtoError::MissingPublishSurface, )?; + validate_variants( + &parsed, + TRANSPORT_OUTCOME_VARIANTS, + RadrootsMeshAgentProtoError::MissingPublishSurface, + )?; validate_fields( &parsed, ERROR_FIELDS, diff --git a/crates/mesh_agent_proto/tests/schema.rs b/crates/mesh_agent_proto/tests/schema.rs @@ -16,6 +16,58 @@ fn schema_declares_mesh_agent_v1_surface() { assert!(RADROOTS_MESH_AGENT_SCHEMA.contains("struct MeshAgentStatusResponse")); assert!(RADROOTS_MESH_AGENT_SCHEMA.contains("struct MeshAgentPublishRequest")); assert!(RADROOTS_MESH_AGENT_SCHEMA.contains("struct MeshAgentPublishResponse")); + assert!(RADROOTS_MESH_AGENT_SCHEMA.contains("enum MeshAgentTransportKind")); + assert!(RADROOTS_MESH_AGENT_SCHEMA.contains("enum MeshAgentTransportOutcome")); +} + +#[test] +fn schema_is_canonical_transport_v1_authority() { + validate_schema().expect("schema validates"); + + assert_eq!(RADROOTS_MESH_AGENT_SCHEMA_ID, "0xb83e0c4f71838d9a"); + assert_ne!(RADROOTS_MESH_AGENT_SCHEMA_ID, "0xdecafbaddecaf001"); + assert_eq!( + validate_schema_text( + RADROOTS_MESH_AGENT_SCHEMA + .replace(RADROOTS_MESH_AGENT_SCHEMA_ID, "0xdecafbaddecaf001") + .as_str(), + ), + Err(RadrootsMeshAgentProtoError::MissingSchemaId) + ); +} + +#[test] +fn schema_covers_transport_v1_status_and_publish_intent() { + for required in [ + "requestId @0 :Text;", + "statusRequest @3 :MeshAgentStatusRequest;", + "publishRequest @4 :MeshAgentPublishRequest;", + "statusResponse @4 :MeshAgentStatusResponse;", + "publishResponse @5 :MeshAgentPublishResponse;", + "includeTransports @0 :Bool;", + "readiness @0 :MeshAgentReadinessState;", + "implementationState @1 :MeshAgentImplementationState;", + "transports @2 :List(MeshAgentTransportStatus);", + "transportKind @0 :MeshAgentTransportKind;", + "profileId @1 :Text;", + "publishUsable @5 :Bool;", + "fetchUsable @6 :Bool;", + "previewUnavailable @3;", + "previewNoop @0;", + "reticulum @0;", + "publishRequestId @0 :Text;", + "payloadCbor @1 :Data;", + "eventId @2 :Text;", + "targetFingerprint @3 :Text;", + "transportReceipts @2 :List(MeshAgentTransportReceipt);", + "eventId @3 :Text;", + "outcome @2 :MeshAgentTransportOutcome;", + "deferredUntilImplemented @4;", + "transportUnavailable @8;", + "errors @3 :List(MeshAgentError);", + ] { + assert!(RADROOTS_MESH_AGENT_SCHEMA.contains(required), "{required}"); + } } #[test] @@ -26,7 +78,7 @@ fn schema_hash_is_deterministic() { assert_eq!(first, second); assert_eq!( first, - "ea82bfc39ae963baf260a6c626ca9033767b0fec93aa013101f975e39baeae6a" + "eff807dfb46416296b51fa0214fee869fbe7ec1da068ffc9c1ce4facc308be17" ); } @@ -130,6 +182,18 @@ fn schema_validator_reports_each_missing_required_surface() { RadrootsMeshAgentProtoError::MissingStatusSurface, ), ( + valid.replace("profileId @1 :Text;", "transportProfileId @1 :Text;"), + RadrootsMeshAgentProtoError::MissingStatusSurface, + ), + ( + valid.replace("reticulum @0;", "reticulumPreview @0;"), + RadrootsMeshAgentProtoError::MissingStatusSurface, + ), + ( + valid.replace("previewNoop @0;", "previewUnavailable @0;"), + RadrootsMeshAgentProtoError::MissingStatusSurface, + ), + ( valid.replace( "struct MeshAgentPublishRequest", "struct MissingMeshAgentPublishRequest", @@ -141,6 +205,35 @@ fn schema_validator_reports_each_missing_required_surface() { RadrootsMeshAgentProtoError::MissingPublishSurface, ), ( + valid.replace("eventId @2 :Text;", "eventIdentifier @2 :Text;"), + RadrootsMeshAgentProtoError::MissingPublishSurface, + ), + ( + valid.replace("targetFingerprint @3 :Text;", "transportTarget @3 :Text;"), + RadrootsMeshAgentProtoError::MissingPublishSurface, + ), + ( + valid.replace( + "transportReceipts @2 :List(MeshAgentTransportReceipt);", + "transportResults @2 :List(MeshAgentTransportReceipt);", + ), + RadrootsMeshAgentProtoError::MissingPublishSurface, + ), + ( + valid.replace( + "outcome @2 :MeshAgentTransportOutcome;", + "outcome @2 :Text;", + ), + RadrootsMeshAgentProtoError::MissingPublishSurface, + ), + ( + valid.replace( + "transportUnavailable @8;", + "transportUnavailablePreview @8;", + ), + RadrootsMeshAgentProtoError::MissingPublishSurface, + ), + ( valid.replace("struct MeshAgentError", "struct MissingMeshAgentError"), RadrootsMeshAgentProtoError::MissingError, ),