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:
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,
),