Files
VerseVDI-Data-Plane/openspec/changes/truthful-fixed-frame-qualification/design.md
T
sechmachine 55afea72a1
Verify Data Plane / gateway (push) Successful in 4m14s
fix(gateway): bound Apollo video ingress
2026-08-09 19:07:22 +07:00

5.4 KiB

Context

The current harness sends one fixed 1,179-byte payload per logical sample. It reaches the production path but does not represent encoded frames at 60/120 FPS or exercise realistic fragmentation, reassembly, queue bytes, and keyframe pressure.

The complete-frame fixture also must preserve the pinned Apollo source schedule. For each frame it derives packets per millisecond from the raw UDP block size at 80% of 1 Gbps, limits source batches to both 64 KiB and 64 packets, and carries the next-send time into the following frame. Waiting is context-cancellable. This is qualification-fixture behavior only; production transport and queue behavior remain unchanged.

Because the bounded fixture uses loopback rather than a physical 1 Gbps link, v8 writes the first shard of a batch successfully, captures that actual monotonic emission start, and schedules the next batch no earlier than that start plus the current batch's raw-block serialization interval. The persistent schedule carries across frames. A delayed batch therefore remains late instead of collapsing overdue batches into a catch-up burst.

The retained v6 qualification run passed its then-current checks but is superseded because its tight-loop sender contradicted the pinned Apollo schedule. Private Linux runs 123 and 124 remain failed evidence. One local v8 sustained run passed on Darwin, but it is neither Linux proof nor normative Section 7 evidence.

The later Darwin non-sustained pre-CI invocation was not green and was not retried. Its 1440p120 profile delivered the exact 6,250,000 bytes in 120 frames plus all 6,483 source and warm-up shards with zero drops, but measured 46,973.13 kbps over an implied approximately 1.0644383 seconds and failed the 5% throughput gate. Private Linux full verification/artifact retention and the replacement v8 normative run remain open.

Private Linux run 125 at the frozen v8 harness head is retained as failed evidence. Its exact 33-datagram gap between successful fixture writes and production MediaIngress equaled the Linux socket's 33 measured kernel UDP drops. The complete-frame queue, fair pacer, QUIC fragmentation, and public decoder were downstream and did not account for the loss.

The ingress repair follows reviewed behavior rather than copying implementation source:

  • Apollo adc5c5a0bd80831ce495434bb16aee2cd4175fb8, GPL-3.0, src/stream.cpp:1463-1474,1573-1627, supplies the 80%-of-1-Gbps raw-block pacing, 64-KiB/64-packet batch cap, and cross-frame send schedule used by the fixture.
  • Moonlight common-C pin 2ea47752c3051d72a64bcca190024e8b354fa1ef, GPL-3.0, src/VideoStream.c:28-35,331-333 and src/PlatformSockets.c:364-405, supplies the reviewed 2,048-video-packet receive-buffer request and dedicated receive-thread behavior. The cited VideoStream.c blob is byte-identical at the local standalone 703a06946861ff82cd33e5e13c59c1b017f7ded9 checkout.

The native provider therefore requests 2,048 * 1,072 = 2,195,456 bytes with SetReadBuffer() on the connected video socket immediately after dialing it. A setter error aborts setup; an OS-imposed cap is accepted without privilege or getter dependence. A dedicated drain owns a fixed 2,048-slot FIFO pool. Every slot is 1,433 bytes (apolloMediaMaximumPacket + 1), so oversized datagrams remain observably invalid rather than being truncated into the accepted range; packet storage is 2,934,784 bytes (about 2.80 MiB) plus fixed index and timestamp metadata. The existing single decrypt/FEC processor consumes those slots. When every slot is occupied, the drain keeps reading into one fixed 1,433-byte scratch buffer and counts each accepted-size discard in both ingress and drop telemetry; oversized datagrams retain the existing rejection semantics. Socket close cancels the blocking read, and media channels close only after the unchanged audio reader, video drain, and video processor exit. Audio and control behavior are unchanged.

Goals / Non-Goals

Goals:

  • Deterministically generate complete variable-size frame units at exact profile frame rates and target bitrates.
  • Include bounded periodic keyframes while preserving exact aggregate bytes.
  • Measure the existing production path and independent reassembly with frame-level accounting.

Non-Goals:

  • A real encoder, codec parsing, a second simulator, or a normative run before immutable Protocol publication.

Decisions

  • Derive bytes per fixed interval from bitrate and FPS, distribute integer remainder deterministically, and shift bounded bytes into periodic keyframes while keeping the interval total exact.
  • Carry a deterministic frame index/pattern only in the generated payload bytes; no codec semantics are claimed.
  • Keep the existing path/impairment/resource driver and change its unit from datagram payload to complete frame.
  • Keep video decrypt/FEC single-threaded; only the bounded connected-socket drain is separated so crypto stalls cannot become unexplained kernel loss.

Risks / Trade-offs

  • [Keyframes can exceed queue budget] → use the reviewed 1 MiB frame ceiling and production byte-bound queue.
  • [Short smoke windows have rounding effects] → assert exact generated totals and report measured duration separately from normative ten-minute gates.
  • [A stalled video processor exhausts the user-space pool] → keep draining into one fixed scratch buffer and attribute accepted-size overflow to existing ingress/drop counters rather than kernel loss or unbounded allocation.