This document explains the two ingress paths in spooky-edge and the intended boundary between them.

Short Version

  • QUIC is the main data-plane ingress path.
  • Bootstrap is a compatibility ingress path for HTTP/1.1 and HTTP/2.
  • Both paths should share the same policy, routing, transport, and observability layers.
  • They should differ mainly in ingress and egress mechanics.

Why Both Paths Exist

Spooky is built around QUIC and HTTP/3 at the edge, but operators still need a compatibility path for environments that cannot enter over QUIC immediately.

The bootstrap path exists so Spooky can:

  • accept HTTP/1.1 or HTTP/2 traffic where needed
  • support compatibility migration scenarios
  • preserve shared policy behavior while using different wire protocols at ingress

Bootstrap is not meant to be a second independent runtime architecture.

Boundary At a Glance

Concern QUIC path Bootstrap path Should semantic policy differ?
Downstream protocol HTTP/3 over QUIC HTTP/1.1 or HTTP/2 No
Intake mechanics UDP, QUIC, HTTP/3 streams HTTP server request intake No
Upgrade handling Native stream model WebSocket and HTTP upgrade handling Only where protocol requires it
Response writeback HTTP/3 stream emission HTTP/1.1 or HTTP/2 response emission No
Routing, auth, quota, overload, transport, observability Shared Shared No

QUIC Path

The QUIC path is the primary ingress model.

It owns:

  • UDP socket ingress
  • QUIC handshake and connection lifecycle
  • HTTP/3 stream handling
  • stream progression and chunk emission
  • QUIC-specific response writeback

Most of this logic lives under crates/edge/src/quic_listener/ and its forwarding/runtime modules.

Bootstrap Path

The bootstrap path is the compatibility ingress model.

It owns:

  • bootstrap listener startup
  • HTTP request intake and validation
  • websocket and upgrade follow-through
  • bootstrap-specific upstream dispatch glue
  • bootstrap response writeback

Most of this logic now lives under crates/edge/src/quic_listener/bootstrap/.

The bootstrap façade should stay thin and focused on compatibility mechanics.

Shared Layers Under Both Paths

The two ingress paths should converge on the same internal policy layers as early as possible.

That shared stack includes:

  • admission and pre-forward policy evaluation
  • route resolution and backend selection
  • load-balancing key resolution
  • external auth decision logic
  • canonical request building in bridge
  • transport execution in transport
  • canonical response normalization in bridge
  • streaming/body guardrail policy
  • retry and hedge policy
  • request/backend outcome recording
  • runtime generation and backend lifecycle state

If a new policy exists only in QUIC or only in bootstrap, that is usually a design smell unless it is truly protocol-specific.

Where They Should Differ

The paths are expected to differ in a few places.

Ingress mechanics

QUIC owns packet, connection, and HTTP/3 stream handling.

Bootstrap owns HTTP accept, request parsing, and upgrade mechanics.

Egress mechanics

QUIC writes normalized responses back through HTTP/3 stream APIs.

Bootstrap writes normalized responses back through HTTP/1.1 or HTTP/2 response handling and may need websocket upgrade follow-through.

Protocol-specific validation

Some request and response validation is protocol-specific at the edge of the ingress path. That logic should stay local to the path that owns the protocol.

Where They Should Not Differ

The following should remain shared and semantically identical:

  • auth allow/deny/challenge behavior
  • quota, rate-limit, overload, and brownout behavior
  • route matching and upstream lookup
  • backend selection semantics
  • retry and hedge eligibility
  • backend health feedback
  • outcome reason vocabularies
  • metrics and logging dimensions
  • runtime-generation and Control API views

If bootstrap and QUIC start producing different policy decisions for the same logical request, the shared layer is in the wrong place or one path has leaked local policy logic.

Code Ownership Guide

Add code to bootstrap when the concern is compatibility-path specific, such as:

  • request intake differences
  • HTTP upgrade mechanics
  • bootstrap response writeback details

Add code to shared layers when the concern is common policy or state, such as:

  • admission
  • auth decision mapping
  • routing and backend selection
  • request building
  • response normalization
  • guardrails
  • outcome recording

Add code to transport when the concern is backend protocol execution, not ingress behavior.

Design Rule

QUIC is the main data-plane path.

Bootstrap should be treated as a compatibility wrapper around the same internal policy and execution model, not as an alternate architecture with its own independent decisions.