fix(gateway): secure control and terminal ownership
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-30
|
||||
@@ -0,0 +1,29 @@
|
||||
## Context
|
||||
|
||||
The native Apollo session and production QUIC gateway already quiesce media before terminal delivery. A public independent-client test proved that immediate `CloseWithError` can overtake the queued reliable stream frame, while waiting for client connection closure leaves tunnel ownership unbounded.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Deliver one terminal event before gateway-owned closure.
|
||||
- Bound closure when a client remains open or omits the receipt.
|
||||
- Preserve cleanup, input release, reservation, and durable state behavior.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- A generic acknowledgement or lifecycle framework.
|
||||
- Any Apollo protocol, media, Server authority, or dependency change.
|
||||
|
||||
## Decisions
|
||||
|
||||
- Reuse Protocol `control.ack.v1` type `0x03` as an empty terminal receipt.
|
||||
- Hold the receipt-state lock across the terminal write, arm one receipt slot only after a successful write, and consume it in the gateway rather than provider feedback.
|
||||
- Wait at most two seconds for receipt, then close and clean up regardless.
|
||||
- Serialize the bounded native event queue and evict one older feedback item only when necessary to retain a terminal event.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Client omits receipt] → Close at the two-second bound and retain durable cleanup behavior.
|
||||
- [Feedback queue is saturated] → Sacrifice one older nonterminal feedback event rather than lose terminal ownership.
|
||||
- [Receipt is malformed, duplicate, or early] → Fail the session closed without provider mutation.
|
||||
@@ -0,0 +1,24 @@
|
||||
## Why
|
||||
|
||||
P3C-018, P3C-019, P3C-021, and P3C-027 require terminal feedback, bounded cleanup, durable state, and explicit input release. A public independent-client regression proved that immediate QUIC closure loses the terminal event, while the old behavior left the tunnel open until the client closed it.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Consume the Protocol-owned terminal receipt on `control.ack.v1` inside the gateway rather than forwarding it to Apollo.
|
||||
- Quiesce media before terminal delivery and close the gateway-owned tunnel after receipt or a bounded receipt deadline.
|
||||
- Guarantee a terminal event survives saturation of the bounded native feedback queue.
|
||||
- Preserve provider cleanup, reservation release, reconnectable disconnect reporting, and `cleanup_pending`.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
None.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `provider-session-lifecycle`: Make terminal delivery and gateway-owned bounded closure executable rather than dependent on client connection closure.
|
||||
|
||||
## Impact
|
||||
|
||||
The pure-Go GPLv3 gateway control and native Apollo session paths change. The Protocol repository remains the wire-contract owner; the Server remains the durable authority. No cgo, sidecar, direct provider route, decode/transcode path, dependency, or proprietary source is introduced. Failure to receive a valid receipt before the bound is a hard session close, not a fallback.
|
||||
@@ -0,0 +1,23 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Provider terminal events end forwarding
|
||||
Encrypted provider termination and unexpected provider disconnect SHALL quiesce provider ingestion and queued/new media forwarding before the existing reliable typed terminal event is delivered. The client SHALL return the Protocol-owned terminal receipt after decoding that event. The gateway SHALL close the Verse tunnel after that receipt or a bounded receipt deadline even when the client keeps the connection open, release the session reservation, and report the appropriate durable provider/session state. The receipt MUST be consumed by the gateway and MUST NOT be forwarded to the provider. A fixed drain delay MUST NOT stand in for reliable control delivery.
|
||||
|
||||
#### Scenario: Host termination closes the tunnel
|
||||
- **WHEN** the native provider emits an authenticated termination event and an independent client returns its terminal receipt
|
||||
- **THEN** queued and newly injected media cannot cross the Verse transport after observation, and the gateway closes the tunnel, releases the reservation, and completes the durable lifecycle transition
|
||||
|
||||
#### Scenario: Unexpected provider disconnect is reconnectable
|
||||
- **WHEN** required provider transport disconnects without acknowledged provider termination
|
||||
- **THEN** forwarding stops, the final typed disconnect reaches the client, and the Server receives the existing reconnectable lifecycle state rather than a termination claim
|
||||
|
||||
#### Scenario: Client omits terminal receipt
|
||||
- **WHEN** the terminal event is written but the client remains open without returning a valid receipt
|
||||
- **THEN** the gateway closes the tunnel at the bounded receipt deadline and continues cleanup without restoring media forwarding
|
||||
|
||||
### Requirement: Cleanup failure remains durable
|
||||
Gateway cleanup MUST preserve `cleanup_pending` when provider input release, transport cleanup, authorized cancellation, or durable reporting fails.
|
||||
|
||||
#### Scenario: Terminal cleanup fails
|
||||
- **WHEN** a provider terminal event is handled but required cleanup cannot complete
|
||||
- **THEN** the session is not reported reusable and durable state remains cleanup pending
|
||||
@@ -0,0 +1,16 @@
|
||||
## 1. Regressions
|
||||
|
||||
- [x] 1.1 Reproduce terminal event loss with an independent QUIC client and immediate gateway closure
|
||||
- [x] 1.2 Reproduce terminal loss behind a saturated native feedback queue
|
||||
|
||||
## 2. Lifecycle repair
|
||||
|
||||
- [x] 2.1 Consume the scoped terminal receipt without provider forwarding
|
||||
- [x] 2.2 Close acknowledged and non-acknowledged terminal tunnels within bounds
|
||||
- [x] 2.3 Preserve media quiescence, reservation release, durable state, and cleanup-pending
|
||||
|
||||
## 3. Verification
|
||||
|
||||
- [x] 3.1 Pin the final immutable Protocol version and pass focused lifecycle/race/resource checks
|
||||
- [ ] 3.2 Pass complete Data Plane verification and the frozen normative Section 7 qualification
|
||||
- [ ] 3.3 Record that deterministic fixtures do not prove live Apollo, macOS-client, or physical-firewall interoperability
|
||||
Reference in New Issue
Block a user