diff --git a/agents/rap-node-agent/cmd/rap-node-agent/main_test.go b/agents/rap-node-agent/cmd/rap-node-agent/main_test.go index 83789d9..208db1b 100644 --- a/agents/rap-node-agent/cmd/rap-node-agent/main_test.go +++ b/agents/rap-node-agent/cmd/rap-node-agent/main_test.go @@ -708,6 +708,7 @@ func TestHeartbeatPayloadIncludesMeshEndpointReport(t *testing.T) { MeshProductionForwardingEnabled: true, MeshFabricSessionEnabled: true, VPNFabricSessionTransportEnabled: true, + VPNFabricSessionStreamShards: 6, VPNFabricQUICMaxStreamsPerConn: 24, MeshQUICFabricEnabled: true, MeshQUICFabricListenAddr: ":19443", @@ -759,11 +760,15 @@ func TestHeartbeatPayloadIncludesMeshEndpointReport(t *testing.T) { if report, ok := payload.Metadata["vpn_fabric_session_transport_report"].(map[string]any); !ok || report["packet_payload"] != "rap.vpn_packet_batch.fabric.v1" || report["transport"] != "fabric_session_binary_frames" || + report["stream_shards_per_class"] != 6 || report["peer_sessions"] == nil { t.Fatalf("vpn fabric session report missing: %+v", payload.Metadata) } else if report["quic_sessions"] == nil || report["quic_max_streams_per_conn"] != 24 { t.Fatalf("vpn fabric quic session report missing: %+v", report) } + if payload.Capabilities["vpn_fabric_session_stream_shards"] != true { + t.Fatalf("vpn fabric stream shard capability missing: %+v", payload.Capabilities) + } if payload.Capabilities["vpn_fabric_endpoint_health_feedback"] != true { t.Fatalf("vpn fabric endpoint health capability missing: %+v", payload.Capabilities) } diff --git a/docs/architecture/DISTRIBUTED_FABRIC_NODE_PROTOCOL_PLAN.md b/docs/architecture/DISTRIBUTED_FABRIC_NODE_PROTOCOL_PLAN.md index 15d4798..1861902 100644 --- a/docs/architecture/DISTRIBUTED_FABRIC_NODE_PROTOCOL_PLAN.md +++ b/docs/architecture/DISTRIBUTED_FABRIC_NODE_PROTOCOL_PLAN.md @@ -408,6 +408,8 @@ The smoke report also exposes the mixed-batch frame fanout so regressions show up as a concrete fanout drop, not just a failed boolean. Batch fanout is bounded by configured stream shards, so a large batch with many flows cannot explode into unbounded fabric frames. +Heartbeat tests assert the advertised VPN fabric stream-shard count and +capability, keeping control-plane diagnostics aligned with runtime behavior. Fabric-session packet transport snapshots now report packets per stream plus last/max batch fanout, making real multi-site load distribution measurable from gateway status.