:PROPERTIES: :ID: 89ee87e0-ac9f-45cd-9fb4-e3dc5c52fe34 :CREATED: [2026-03-31 Tue 18:43] :EDITED: [2026-04-07 Tue 13:42] :END: #+TITLE: SKILL: Inbound Multi-Channel Gateway (Universal Literate Note) #+STARTUP: content #+FILETAGS: :gateway:sensors:io:autonomy: * Overview The *Inbound Multi-Channel Gateway* provides the sensory interface for external messaging. It enables the agent to "hear" the user from various platforms (Signal, Telegram, SMS) by normalizing disparate inbound payloads into standard Probabilistic-Deterministic Kernel stimuli. * Phase A: Demand (PRD) :PROPERTIES: :STATUS: FROZEN :END: ** 1. Purpose Define a secure and extensible ingress for external communication channels. ** 2. User Needs - *Multi-Channel Ingress:* Support Signal (via signal-cli), Telegram (via Bot API), and generic Webhooks. - *Payload Normalization:* Convert platform-specific JSON into standard Lisp plists. - *Security & Authentication:* Verify sender identity before injecting stimuli into the harness. - *Asynchronous Reception:* Non-blocking monitoring of inbound message queues. ** 3. Success Criteria *** TODO Signal-cli message reception and parsing *** TODO Telegram Bot API webhook normalization *** TODO Sender verification logic (Whitelisting) *** TODO Autonomous stimulus injection into the harness Bus * Phase B: Blueprint (PROTOCOL) :PROPERTIES: :STATUS: SIGNED :END: * Phase B: Blueprint (PROTOCOL) :PROPERTIES: :STATUS: DRAFT :END: ** 1. Architectural Intent The Inbound Gateway should operate as a modular, asynchronous service. Each channel (Signal, Telegram, Webhook) will have its own adapter responsible for receiving and normalizing messages. A central dispatcher will then authenticate and inject these normalized messages as stimuli into the Probabilistic-Deterministic Kernel’s message bus. Error handling and logging will be crucial for observability and maintainability. ** 2. Semantic Interfaces (Lisp Signatures) *** `inbound-message-handler` - *Purpose:* Main entry point for processing inbound messages from all channels. - *Signature:* `(inbound-message-handler channel message-payload)` - *Arguments:* - `channel` (keyword): Identifies the source channel (e.g., `:signal`, `:telegram`, `:webhook`). - `message-payload` (string): The raw message payload received from the channel. - *Returns:* Boolean indicating successful processing (T) or failure (NIL). *** `normalize-message` - *Purpose:* Converts a platform-specific message payload into a standard Lisp plist. - *Signature:* `(normalize-message channel message-payload)` - *Arguments:* - `channel` (keyword): The source channel. - `message-payload` (string): The raw message payload. - *Returns:* A Lisp plist representing the normalized message. Example: `(:sender "+15551234567" :text "Hello, world!" :timestamp 1678886400)`. *** `authenticate-sender` - *Purpose:* Verifies the identity of the message sender based on the channel. - *Signature:* `(authenticate-sender channel sender-id)` - *Arguments:* - `channel` (keyword): The source channel. - `sender-id` (string): The sender's unique identifier (e.g., phone number for Signal, username for Telegram). - *Returns:* Boolean indicating successful authentication (T) or failure (NIL). Consider using ACLs (Access Control Lists). *** `inject-stimulus` - *Purpose:* Injects a normalized message into the Probabilistic-Deterministic Kernel's message bus as a stimulus. - *Signature:* `(inject-stimulus stimulus-plist)` - *Arguments:* - `stimulus-plist` (plist): The normalized message plist. - *Returns:* A unique identifier for the injected stimulus. *** `channel-listener` - *Purpose:* Asynchronously listens for inbound messages on a specific channel. - *Signature:* `(channel-listener channel-config)` - *Arguments:* - `channel-config` (plist): Configuration parameters specific to the channel (e.g., API key, webhook URL). - *Returns:* (Non-blocking) N/A. The listener will spawn threads to handle incoming messages. ** 3. Example Flow (Signal) 1. `channel-listener` (for `:signal`) receives a new message via `signal-cli`. 2. The raw message is passed to `inbound-message-handler` with `channel` = `:signal`. 3. `inbound-message-handler` calls `normalize-message` to convert the Signal payload to a standard plist. 4. `inbound-message-handler` calls `authenticate-sender` to verify the sender's identity. 5. If authentication succeeds, `inbound-message-handler` calls `inject-stimulus` to inject the message into the harness. 6. Error handling and logging are performed at each step.