docs(openspec): archive gateway input feedback contract

This commit is contained in:
sechmachine
2026-07-29 23:02:19 +07:00
parent ebfe07376d
commit 59741761ce
6 changed files with 86 additions and 3 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-29
@@ -0,0 +1,50 @@
## Context
The registered `input.sequenced.v1` flow has a payload bound but no typed
payload grammar. RC5 also has no provider-to-client envelope for host
termination, rumble, or HDR feedback. The Data Plane must translate these
states to the provider without exposing Apollo packet formats or credentials.
## Goals / Non-Goals
**Goals:**
- Define fixed, bounded, endian-explicit gateway payloads for keyboard, mouse,
UTF-8 text, and controller state.
- Define a reliable control envelope for provider feedback and termination.
- Define an explicit release operation for every pressed key/button/controller.
- Keep provider packet encodings and endpoint details internal to the Data Plane.
**Non-Goals:**
- Touch, pen, motion, file transfer, binary clipboard, or provider-specific
packets.
- Changing RC5, moving an existing tag, or making the Connection Server parse
streaming input.
## Decisions
- Define a new binary payload grammar beneath the existing registered flows.
This avoids changing the authenticated tunnel header while removing the
untyped `device`/opaque-payload ambiguity. JSON was rejected because input is
latency-sensitive and fixed binary bounds are simpler to validate before
allocation.
- Input events use explicit event kinds and fixed payload lengths except UTF-8
text, which is limited to one valid Unicode scalar value. This permits exact
provider translation and deterministic cleanup.
- Provider feedback and termination use the existing bidirectional reliable
control channel with a distinct magic, direction, type, and length. A new
channel was rejected because the existing channel is already authenticated,
reliable, and versioned.
- Protocol contents and fixtures are finalized before a new immutable release
candidate is created. RC5 remains an unchanged dependency for current
consumers until they explicitly adopt the new revision.
## Risks / Trade-offs
- [New client adoption is required] -> retain RC5 unchanged and publish an
explicit capability/version mismatch before any provider allocation.
- [Provider feedback can be high rate] -> allow only termination, rumble, and
HDR payload types with fixed maximum sizes; other types reject.
- [Pressed-state loss during disconnect] -> gateway records accepted presses
and emits typed releases during cleanup before provider disconnect.
@@ -0,0 +1,40 @@
## Why
The RC5 tunnel register identifies a bounded sequenced-input flow but does not
define typed input state or provider-to-client feedback. The native Apollo
adapter cannot safely translate keyboard, mouse, UTF-8, controller, termination,
rumble, or HDR state from an untyped payload.
## What Changes
- Define a typed, versioned gateway input envelope for keyboard, mouse, UTF-8,
and controller state.
- Define bounded provider-feedback and provider-termination envelopes on the
existing reliable control direction.
- Define a separate typed clipboard envelope and Server-owned per-session
direction, size, and rate policy so the gateway can prevent reflected loops
without exposing provider management material.
- Define release semantics so gateway cleanup can emit real provider key/button
releases without a synthetic provider command.
- Preserve RC5 unchanged; this change requires a new immutable Protocol version
after its fixtures and consumers are final.
## Capabilities
### New Capabilities
- `gateway-input-feedback`: Typed Phase 3C gateway input, provider feedback,
termination, and release envelopes.
### Modified Capabilities
- None.
## Impact
- Protocol control and datagram registries, schemas, fixtures, and generated
Go/Rust/Swift bindings.
- Data Plane gateway input/clipboard translation and host-feedback forwarding.
- Connection Server mints only immutable clipboard policy in authenticated
provider work; it neither receives clipboard bytes nor inspects provider
packet payloads.
@@ -0,0 +1,79 @@
## ADDED Requirements
### Requirement: Typed sequenced input envelope
The `input.sequenced.v1` payload SHALL begin with ASCII `VGI1`, a one-byte
event kind, and one-byte payload length. It SHALL contain exactly one bounded
keyboard, mouse-button, relative-mouse, UTF-8 scalar, or controller-state
event. False keyboard/mouse state and zeroed controller state are explicit
releases. Multibyte integer fields SHALL be big-endian. Unknown kinds,
length mismatches, malformed UTF-8, unsupported controller indices, and
reserved fields SHALL be rejected before provider translation.
#### Scenario: Keyboard state change
- **WHEN** a client sends a valid keyboard press or release envelope
- **THEN** the gateway forwards the corresponding typed provider input on its
reliable keyboard channel and records the pressed state for cleanup.
#### Scenario: Invalid input envelope
- **WHEN** a client sends an envelope with an unknown event kind, invalid
length, malformed UTF-8 scalar, or nonzero reserved field
- **THEN** the gateway rejects it without sending provider input or changing
pressed state.
### Requirement: Explicit input release
The typed input envelope SHALL represent release of each keyboard key,
mouse button, and controller state. Gateway cleanup SHALL send a typed release
for every accepted pressed state before provider disconnect; it SHALL NOT use
an implementation-specific release-all provider command.
#### Scenario: Tunnel cleanup with pressed input
- **WHEN** a tunnel closes after accepted pressed keyboard, mouse, or
controller input
- **THEN** the gateway emits the corresponding individual provider release
packets reliably before starting provider disconnect.
### Requirement: Bounded provider feedback control envelope
The registered bidirectional reliable `control.ack.v1` flow SHALL define an ASCII `VGF1` envelope
with a direction byte, type byte, big-endian payload length, and exact payload
bytes. Only host termination, rumble, and HDR feedback SHALL be valid from the
gateway to the client; only IDR and FEC/loss feedback SHALL be valid from the
client to the gateway. The envelope SHALL contain no provider address,
certificate, credential, or opaque provider packet.
#### Scenario: Host termination forwarding
- **WHEN** the Apollo adapter receives an authenticated host termination
packet
- **THEN** the gateway forwards a bounded `VGF1` termination envelope over
reliable Verse control and reports the provider state separately.
#### Scenario: Unauthorized or malformed feedback
- **WHEN** feedback is disabled by policy, has an invalid direction/type/length,
or contains a forbidden provider field
- **THEN** the gateway rejects it without forwarding or provider mutation.
### Requirement: Policy-bound text clipboard envelope
The reliable `clipboard.text.v1` flow SHALL carry only a typed UTF-8 text
envelope with exact direction and a 16--128 character canonical unpadded ASCII
base64url loop token. The Server SHALL mint
the enabled directions, maximum text bytes, and maximum updates per minute in
authenticated provider work. The gateway SHALL reject disabled direction,
unknown fields, files, file URLs, client folders, binary data, malformed UTF-8,
oversized values, rates above policy, and reflected/replayed loop tokens. It
SHALL not put clipboard content, provider routes, or credentials in telemetry,
audit, state, or errors.
#### Scenario: Clipboard audit metadata
- **WHEN** the gateway successfully delivers, suppresses, or rejects a clipboard update
- **THEN** it sends an authenticated Server audit record with only direction,
bounded byte count, outcome, and a fixed reason; it never includes text or
the loop token.
#### Scenario: Clipboard delivery failure
- **WHEN** provider-to-client control delivery fails
- **THEN** the gateway does not report the update as forwarded.
#### Scenario: Reflected clipboard value
- **WHEN** a client-originated text value returns from the provider with the
matching retained token/value pair
- **THEN** the gateway suppresses the reflected update without a second
provider mutation or client delivery.
@@ -0,0 +1,29 @@
## 1. Contract and fixtures
- [x] 1.1 Define the exact typed input and provider-feedback binary layouts in
the canonical frame documentation and registries.
- [x] 1.2 Add positive and negative fixed-byte conformance fixtures for every
input, release, feedback, termination, reserved, and malformed case.
- [x] 1.3 Update only source Protocol artifacts, regenerate bindings and the
manifest, and prove no generated drift.
- [x] 1.4 Define policy-bound clipboard direction/rate/loop-token envelopes and
positive/negative deterministic conformance fixtures without adding provider
fields to a client-facing frame.
## 2. Consumer qualification
- [x] 2.1 Run Protocol validation and the Go, Rust, and Swift conformance
consumers against the new fixtures.
- [x] 2.2 Advance the Data Plane to the final immutable Protocol revision and
translate only the typed envelopes to provider control packets.
- [x] 2.3 Add deterministic host-feedback forwarding and input-release tests
without provider endpoint or credential disclosure.
- [x] 2.4 Advance the Data Plane and Connection Server to the final clipboard
contract and prove disabled direction, malformed/oversized text, rate, loop,
and file/binary rejection against the authenticated provider path.
## 3. Freeze
- [x] 3.1 Reconcile the canonical specification, OpenSpec tasks, source
provenance, and consumer fixture digest before creating a new immutable
Protocol release candidate.