diff --git a/docs/specs/mesh-service-layer.md b/docs/specs/mesh-service-layer.md new file mode 100644 index 0000000..7aedc79 --- /dev/null +++ b/docs/specs/mesh-service-layer.md @@ -0,0 +1,373 @@ +# Mesh Service Layer — Generic Application Protocol + +## Vision + +FAPP (therapy slots) ist nur **eine** Anwendung. Die gleiche Infrastruktur könnte tragen: + +| Service | Announce | Query | Reserve | +|---------|----------|-------|---------| +| **FAPP** | Therapist slots | Patient search | Book appointment | +| **Housing** | Available rooms/flats | Tenant search | Reserve viewing | +| **Repair** | Craftsman availability | Customer search | Book repair | +| **Tutoring** | Tutor slots | Student search | Book lesson | +| **Medical** | Doctor appointments | Patient search | Book slot | +| **Legal** | Lawyer availability | Client search | Book consultation | +| **Volunteer** | Helper availability | Org search | Coordinate help | +| **Events** | Open seats/tickets | Attendee search | Reserve seat | + +**Gemeinsames Muster:** +1. Provider announces availability +2. Consumer queries anonymously +3. Match → encrypted reservation +4. Confirmation + +## Design Principles + +### 1. Service Namespacing + +Jeder Service hat einen **Service ID** (32-bit): + +```rust +pub const SERVICE_FAPP: u32 = 0x0001; // Psychotherapy +pub const SERVICE_HOUSING: u32 = 0x0002; // Housing/Rooms +pub const SERVICE_REPAIR: u32 = 0x0003; // Craftsmen +pub const SERVICE_TUTOR: u32 = 0x0004; // Tutoring +pub const SERVICE_MEDICAL: u32 = 0x0005; // Medical appointments +// ... +pub const SERVICE_CUSTOM: u32 = 0xFFFF; // User-defined +``` + +### 2. Generic Message Envelope + +```rust +/// Generic service message that wraps any application payload. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ServiceMessage { + /// Service identifier (which application). + pub service_id: u32, + /// Message type within service (Announce=1, Query=2, Response=3, etc.). + pub message_type: u8, + /// Version for forward compatibility. + pub version: u8, + /// Application-specific CBOR payload. + pub payload: Vec, + /// Provider's mesh address. + pub provider_address: [u8; 16], + /// Ed25519 signature over (service_id, message_type, version, payload). + pub signature: Vec, + /// Propagation control. + pub hop_count: u8, + pub max_hops: u8, + pub ttl_hours: u16, + pub timestamp: u64, +} +``` + +### 3. Capability System + +Erweitere die Capability Flags: + +```rust +// Base capabilities (existing) +pub const CAP_RELAY: u16 = 0x0001; +pub const CAP_STORE: u16 = 0x0002; +pub const CAP_GATEWAY: u16 = 0x0004; + +// Service-specific capabilities (dynamic) +// Format: 0xSSCC where SS = service_id (high byte), CC = capability +pub const CAP_SERVICE_PROVIDER: u16 = 0x0100; // Can announce +pub const CAP_SERVICE_RELAY: u16 = 0x0200; // Caches & forwards +pub const CAP_SERVICE_CONSUMER: u16 = 0x0400; // Can query + +// Example: FAPP therapist +// capabilities = CAP_RELAY | (SERVICE_FAPP << 8) | CAP_SERVICE_PROVIDER +``` + +### 4. Schema Registry + +Services definieren ihr Schema — aber das Schema ist **nicht im Wire-Protokoll**: + +```rust +/// Service schema definition (stored locally, not transmitted). +pub struct ServiceSchema { + pub service_id: u32, + pub name: String, + pub version: u8, + /// CBOR schema for Announce payload. + pub announce_schema: Vec, + /// CBOR schema for Query payload. + pub query_schema: Vec, + /// CBOR schema for Response payload. + pub response_schema: Vec, + /// Required verification level. + pub min_verification: u8, + /// Human-readable description. + pub description: String, +} +``` + +Nodes können Schemas per Out-of-Band bekommen (Website, Git, DNS TXT records). + +### 5. Service Router + +```rust +pub struct ServiceRouter { + /// Registered service handlers. + handlers: HashMap>, + /// Shared routing table. + routes: Arc>, + /// Transport manager. + transports: Arc, + /// Per-service stores. + stores: HashMap>, +} + +pub trait ServiceHandler: Send + Sync { + fn service_id(&self) -> u32; + fn handle_announce(&self, msg: &ServiceMessage) -> ServiceAction; + fn handle_query(&self, msg: &ServiceMessage) -> ServiceAction; + fn handle_response(&self, msg: &ServiceMessage) -> ServiceAction; +} + +pub trait ServiceStore: Send + Sync { + fn store(&mut self, msg: ServiceMessage) -> bool; + fn query(&self, filter: &[u8]) -> Vec; + fn gc_expired(&mut self) -> usize; +} +``` + +## Wire Protocol + +### Message Format + +``` +┌──────────────────────────────────────────────────────────┐ +│ Byte 0-3: Service ID (u32 LE) │ +│ Byte 4: Message Type (1=Announce, 2=Query, 3=Resp) │ +│ Byte 5: Version │ +│ Byte 6-7: Payload Length (u16 LE) │ +│ Byte 8-23: Provider Address (16 bytes) │ +│ Byte 24-87: Signature (64 bytes) │ +│ Byte 88: Hop Count │ +│ Byte 89: Max Hops │ +│ Byte 90-91: TTL Hours (u16 LE) │ +│ Byte 92-99: Timestamp (u64 LE) │ +│ Byte 100+: CBOR Payload │ +└──────────────────────────────────────────────────────────┘ +``` + +**Total header: 100 bytes** + variable payload. + +### Message Types + +| Type | Value | Direction | +|------|-------|-----------| +| Announce | 0x01 | Provider → Mesh | +| Query | 0x02 | Consumer → Mesh | +| Response | 0x03 | Relay/Provider → Consumer | +| Reserve | 0x04 | Consumer → Provider | +| Confirm | 0x05 | Provider → Consumer | +| Cancel | 0x06 | Either → Other | +| Update | 0x07 | Provider → Mesh (partial update) | +| Revoke | 0x08 | Provider → Mesh (cancel announce) | + +## Example: Housing Service + +```rust +// Define the service +pub const SERVICE_HOUSING: u32 = 0x0002; + +#[derive(Serialize, Deserialize)] +pub struct HousingAnnounce { + pub room_type: RoomType, // WG, Apartment, House + pub size_sqm: u16, + pub rent_euros: u16, + pub available_from: u64, + pub plz: String, + pub amenities: Vec, + pub landlord_profile_url: Option, +} + +#[derive(Serialize, Deserialize)] +pub struct HousingQuery { + pub room_type: Option, + pub max_rent: Option, + pub min_size: Option, + pub plz_prefix: Option, + pub available_before: Option, +} + +// Register with ServiceRouter +router.register(HousingHandler::new(housing_store)); +``` + +## Migration Path for FAPP + +FAPP kann auf die generische Schicht migriert werden: + +```rust +// Before: FAPP-specific +let announce = SlotAnnounce::new(...); +fapp_router.broadcast_announce(announce)?; + +// After: Generic service layer +let payload = FappAnnouncePayload { ... }; +let msg = ServiceMessage::announce(SERVICE_FAPP, &identity, payload)?; +service_router.broadcast(msg)?; +``` + +**Backwards compatibility:** +- Alte FAPP-Nodes verstehen nur FAPP-Wire-Format +- Neue Nodes können beide Formate +- Transition über 6 Monate, dann deprecate altes Format + +## Verification Framework + +Generische Verification die für alle Services gilt: + +```rust +pub struct Verification { + /// Who endorsed this provider. + pub endorser_address: [u8; 16], + /// Signature over (provider_address, service_id, timestamp). + pub signature: [u8; 64], + /// Unix timestamp. + pub timestamp: u64, + /// Verification level achieved. + pub level: u8, + /// Service-specific verification data (e.g., license number). + pub credential_hash: Option<[u8; 32]>, + /// Human-readable reason. + pub reason: String, +} + +/// Verification levels (generic across services). +pub const VERIFY_NONE: u8 = 0; +pub const VERIFY_ENDORSED: u8 = 1; // Web-of-trust +pub const VERIFY_REGISTRY: u8 = 2; // Official registry +pub const VERIFY_CREDENTIAL: u8 = 3; // Verified credential (eHBA, etc.) +``` + +## Service Discovery + +Wie finden Nodes heraus welche Services existieren? + +### Option A: Hardcoded Core Services + +```rust +const CORE_SERVICES: &[u32] = &[ + SERVICE_FAPP, + SERVICE_HOUSING, + SERVICE_REPAIR, +]; +``` + +### Option B: Service Announce + +```rust +/// Node announces which services it supports. +pub struct ServiceCapabilityAnnounce { + pub node_address: [u8; 16], + pub services: Vec, + pub signature: [u8; 64], +} + +pub struct ServiceCapability { + pub service_id: u32, + pub roles: u8, // Provider | Relay | Consumer + pub version: u8, +} +``` + +### Option C: DNS-SD / mDNS + +``` +_fapp._mesh._udp.local. +_housing._mesh._udp.local. +``` + +**Recommendation:** Start with Option A (hardcoded), add Option B when needed. + +## Privacy Considerations + +| Aspect | Design | +|--------|--------| +| Provider identity | Public (bound to credential) | +| Consumer identity | Anonymous (no ID in queries) | +| Query content | Visible to relays (filter by service) | +| Reservation | E2E encrypted to provider | +| Location | Coarse only (PLZ, not address) | + +## Cost Model + +Relay nodes do work. How to compensate? + +| Model | Pros | Cons | +|-------|------|------| +| **Altruism** | Simple, no tokens | Free-rider problem | +| **Reciprocity** | "I relay, you relay" | Complex accounting | +| **Micropayments** | Fair, incentivizes | Needs payment rails | +| **Subscription** | Predictable | Centralization risk | + +**Recommendation:** Start altruistic, add optional micropayments later. + +## Implementation Roadmap + +### Phase 1: Generic Layer (Now) + +1. `ServiceMessage` struct +2. `ServiceRouter` with handler registration +3. `ServiceStore` trait +4. Migrate FAPP to generic layer +5. Tests + +### Phase 2: Second Service (Q2 2026) + +1. Pick one: Housing or Tutoring +2. Implement as second service on same layer +3. Prove the abstraction works + +### Phase 3: Verification Framework (Q3 2026) + +1. Generic endorsement messages +2. Verification levels +3. Trusted relay network + +### Phase 4: Service Discovery (Q4 2026) + +1. ServiceCapabilityAnnounce +2. Dynamic service registration +3. Schema distribution + +## Open Questions + +1. **Payload size limits?** LoRa vs. TCP have very different constraints. +2. **Query routing?** Flood vs. DHT vs. gossip? +3. **Cross-service queries?** "Find therapist OR coach near me" +4. **Service-specific rate limits?** Housing might need different limits than FAPP. +5. **Governance?** Who assigns service IDs? IANA-style registry? + +## Conclusion + +QuicProQuo's mesh layer can become a **generic decentralized service platform**: + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Application Services │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │ FAPP │ │ Housing │ │ Repair │ │ Custom │ ... │ +│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ +│ │ │ │ │ │ +│ ─────┴────────────┴────────────┴────────────┴────────── │ +│ Service Layer │ +│ ServiceMessage, ServiceRouter, Verification │ +│ ─────────────────────────────────────────────────────── │ +│ Mesh Layer │ +│ MeshRouter, RoutingTable, Announce, Store-and-Forward │ +│ ─────────────────────────────────────────────────────── │ +│ Transport Layer │ +│ Iroh (QUIC), TCP, LoRa, Serial │ +└─────────────────────────────────────────────────────────────┘ +``` + +**The mesh IS the platform.** No central servers, no vendor lock-in, no single point of failure.