ADR-0027: Bridge-Runtime Streaming Protocol

Date: 2026-03-09 Status: Proposed Author: Architect Agent Supersedes: N/A

1. Context

The project is migrating the OpenAI-compatible bridge to use the OpenClawGuardCore contract layer (PR-C1). The current OpenAiCompatService supports streaming but the OpenClawGuardCoreResponseEnvelope is a single object. For PR-C1, the Runtime must own stream generation while the Bridge acts as a proxy.

2. Decision

We will adopt a Head-Snapshot + Event-Stream pattern for the Bridge-Runtime contract.

2.1 Protocol Definition

  1. Request: The Bridge sends an OpenClawGuardCoreRequest (with stream: true).
  2. Synchronous Guard: The Runtime immediately resolves the OpenClawGuardCoreScopeDecision and OpenClawGuardCoreResolvedCapability synchronously.
  3. Initial Response (Head): The Runtime returns a single "Head Chunk" containing the status, degradedMode, capability, and scope metadata.
  4. Streaming Body: The Runtime then streams the content (sanitized per chunk) followed by a final [DONE] signal.

2.2 Implementation

  • Bridge (NestJS): Uses an Observable or AsyncIterable to consume the Runtime's internal stream.
  • Sanitization: Sanitization (sanitizeGuardCoreOutput) must be applied to every chunk in the stream.
  • Proxying: OpenAiCompatService pipes the sanitized chunks into the Express Response using the standard OpenAI data: {...} format.

3. Alternatives Considered

  • Buffering: Waiting for the full content before sanitizing. Rejected: Increases TTFT (Time To First Token) and breaks streaming UX.
  • Bridge-Side Sanitization: Let the Bridge sanitize. Rejected: Violates the "Pure Guard Core" principle where the Runtime is responsible for its own output safety.

4. Consequences

Positive

  • Low Latency: Preserves the streaming experience for users.
  • Safety: Ensures every token is sanitized before leaving the Runtime boundary.

Negative

  • Complexity: Requires handling partial tokens if a secret is split across two chunks (mitigated by using regex over the sliding window if necessary, though current redaction is simple enough for per-chunk).