docs(openspec): archive complete frame transport
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-30
|
||||
@@ -0,0 +1,29 @@
|
||||
## Context
|
||||
|
||||
RC9 datagram-v1 uses one-byte fragment fields and caps a media unit at 16 path-MTU fragments. The reviewed Apollo assembler can recover an encoded frame up to 1,028,152 bytes, so the replacement contract must carry at least that size while rejecting proportional allocation from untrusted header claims.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Preserve datagram-v1 byte-for-byte and add explicitly negotiated datagram-v2.
|
||||
- Keep each QUIC datagram at 1,200 bytes or less.
|
||||
- Bound one complete encoded unit to 1 MiB, at most 891 fragments, four incomplete units, and a 250 ms reassembly lifetime.
|
||||
- Define duplicate, reorder, timeout, and malformed behavior for every validator.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Provider packet exposure, codec parsing, decode/transcode, retransmission, or a generic transport framework.
|
||||
|
||||
## Decisions
|
||||
|
||||
- Datagram-v2 widens fragment index and count to unsigned 16-bit network-order fields, making a 23-byte header and 1,177-byte media payload. This is the smallest header change that covers the reviewed provider maximum without unrelated sequences.
|
||||
- Sequence identifies one complete unit. All fragments must agree on channel, sequence, timestamp, count, and flags.
|
||||
- Reassembly stores only received fragment bytes, rejects conflicting duplicates, permits exact duplicates and bounded reorder, evicts oldest state above four units, and expires state after 250 ms.
|
||||
- Capability validation registers `datagram-v1` and `datagram-v2`; exact profile equality keeps downgrade behavior fail closed.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [More fragments increase per-frame overhead] → retain the 1,200-byte PMTU envelope and the 1 MiB frame ceiling.
|
||||
- [Four concurrent 1 MiB units can consume bounded memory] → allocate only received bytes and evict/expire incomplete state.
|
||||
- [RC9 peers cannot validate datagram-v2] → require a new immutable Protocol release and exact consumer pins; never mutate RC9.
|
||||
@@ -0,0 +1,24 @@
|
||||
## Why
|
||||
|
||||
The RC9 datagram contract limits one encoded media unit to 18,864 bytes, below the bounded complete frames required by the reviewed Apollo adapter and the fixed Phase 3C profiles. A new immutable Protocol release must define complete-frame transport and reassembly bounds before consumers can relay realistic encoded frames without mutation.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a versioned PMTU-safe media datagram header with wider fragment fields.
|
||||
- Bound complete encoded frames, fragments, reassembly state, duplicates, reorder, timeout, and allocation.
|
||||
- Preserve RC9 datagram-v1 unchanged and require explicit negotiation of the new framing profile.
|
||||
- Add fixed Python, Go, Rust, and Swift conformance vectors for valid and malformed framing.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `gateway-media-framing`: Versioned complete encoded-frame fragmentation and bounded reassembly contract.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
None.
|
||||
|
||||
## Impact
|
||||
|
||||
Protocol framing documentation, registries, capability schema, fixed conformance fixtures, validators, generated Go/Rust/Swift bindings, and immutable consumer versioning. Requirements: SYS-002, SYS-003, P3C-006, P3C-007, P3C-008, P3C-030, P3C-038, VER-001, VER-002, VER-028.
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Versioned complete encoded-frame datagrams
|
||||
The Protocol SHALL register `datagram-v2` with a 23-byte network-order header containing magic, version, channel, flags, sequence, timestamp, unsigned 16-bit fragment index, unsigned 16-bit fragment count, and unsigned 16-bit payload length. Media datagrams MUST remain at most 1,200 bytes with at most 1,177 payload bytes, and one sequence MUST represent exactly one complete encoded unit of at most 1,048,576 bytes and 891 fragments.
|
||||
|
||||
#### Scenario: Bounded large encoded frame
|
||||
- **WHEN** an encoded media frame is larger than the datagram-v1 18,864-byte limit but no larger than 1,048,576 bytes
|
||||
- **THEN** datagram-v2 carries it under one sequence in at most 891 independently bounded fragments
|
||||
|
||||
#### Scenario: Oversized encoded frame
|
||||
- **WHEN** a sender attempts more than 1,048,576 complete bytes or 891 fragments
|
||||
- **THEN** framing rejects the unit before sending or allocating proportional state
|
||||
|
||||
### Requirement: Bounded complete-frame reassembly
|
||||
Datagram-v2 reassembly SHALL retain at most four incomplete media units and only the bytes actually received, permit bounded fragment reorder and exact duplicate fragments, reject conflicting duplicates or inconsistent metadata, expire incomplete state after 250 milliseconds, and emit a payload only after every fragment is present exactly once.
|
||||
|
||||
#### Scenario: Reordered frame completes
|
||||
- **WHEN** every valid fragment for one unit arrives out of order within the reassembly bounds
|
||||
- **THEN** the receiver emits exactly one byte-identical complete encoded frame with its original boundary
|
||||
|
||||
#### Scenario: Malformed or stale reassembly
|
||||
- **WHEN** fragments conflict, metadata changes, an index or count is invalid, state exceeds four incomplete units, or a unit exceeds its timeout
|
||||
- **THEN** the receiver rejects or evicts that incomplete unit without proportional allocation or payload emission
|
||||
|
||||
### Requirement: Explicit framing negotiation
|
||||
`CapabilityProfile.framing` SHALL accept only registered `datagram-v1` or `datagram-v2` values. A peer MUST use datagram-v2 only after exact capability intersection and MUST NOT reinterpret datagram-v1 bytes as datagram-v2.
|
||||
|
||||
#### Scenario: Independent datagram-v2 peers overlap
|
||||
- **WHEN** both peers advertise the registered datagram-v2 framing profile
|
||||
- **THEN** generated Go, Rust, and Swift validation and fixed conformance accept the profile
|
||||
|
||||
#### Scenario: Unknown or downgraded framing
|
||||
- **WHEN** a peer advertises an unknown framing value or the peers advertise different versions
|
||||
- **THEN** capability validation or intersection rejects the session before media forwarding
|
||||
@@ -0,0 +1,20 @@
|
||||
## 1. Red conformance
|
||||
|
||||
- [x] 1.1 Add fixed datagram-v2 and capability vectors that fail current Python, Go, Rust, and Swift validators
|
||||
- [x] 1.2 Prove unknown version, malformed length, invalid fragment, and oversized complete-unit cases remain rejected
|
||||
|
||||
## 2. Contract implementation
|
||||
|
||||
- [x] 2.1 Add the versioned datagram-v2 frame grammar and registered framing values
|
||||
- [x] 2.2 Update generator/native validators and regenerate Go, Rust, and Swift bindings normally
|
||||
|
||||
## 3. Verification
|
||||
|
||||
- [x] 3.1 Run focused cross-language conformance and strict OpenSpec validation
|
||||
- [x] 3.2 Run complete `make verify` and prove a second generation has no drift
|
||||
|
||||
## 4. Immutable boundary
|
||||
|
||||
- [x] 4.1 Publish one new never-reused immutable Protocol version, resolve it
|
||||
from separate empty consumer caches, and pin the fetched checksums in both
|
||||
consumers
|
||||
Reference in New Issue
Block a user