nx_h2_stream.nx
buildroot/runtime/nx_h2_stream.nx
about
nx_h2_stream.nx -- TUTOR-BOOTSTRAP SCAFFOLD (Claude, authored under the R4-H2
HTTP/2-transport-ladder workflow), NOT credited as team self-authoring.
R4-H2-004 of the sovereign HTTP/2 transport ladder
(knowledge/specs/2026-06-13-http2-transport-ladder.md). The HTTP/2 stream
state machine (RFC 9113 §5.1). Unlike the lower rungs this organ emits no
wire bytes -- it is the BEHAVIOURAL automaton that RFC 9113 §5.1 dictates:
idle -> open -> half-closed(local|remote) -> closed, driven by the HEADERS /
DATA / RST_STREAM / END_STREAM events the frame codec produces and consumes.
The TRANSITION TABLE is the allowed internet-boundary requirement (a peer that
disagrees about the legal transitions cannot interoperate, exactly as it must
agree on the frame bytes); the IMPLEMENTATION is pure NishiLang via
nx_cc -> nxasm_x86: no gcc, no openssl, no nghttp2.
FOUNDED ON (composes, does not reinvent -- anti-orphan law):
- nx_h2_frame.nx (R4-H2-003, GREEN): we import it EXACTLY ONCE. It
transitively splices nx_hpack.nx -> nx_str.nx -> syscalls.nx, so we
inherit sys_mmap / sys_write / sys_exit / sys_openat_append / sys_close
from that single import (importing nx_hpack / nx_str / nx_syscalls
directly TOO would be the RC6 double-import landmine). The frame type
codes (DATA=0x00, HEADERS=0x01, RST_STREAM=0x03) and the END_STREAM flag
(0x01) that DRIVE this automaton are exactly the ones nx_h2_frame.nx
emits, so the SM and the codec cannot disagree (single source of truth).
No floating capability: the frame codec founds this stream machine; flow
control (R4-H2-005) founds on this next.
BACK-FILL: the team RE-AUTHORS this from the DATA spec via the
emitter-of-emitters (X-AUT-006c/e/f) -- this hand-authored scaffold is the
sanctioned one-time bootstrap only (meter-integrity, mirror
nx_frame_codec.nx:13-16 / nx_h2_frame.nx:31-34).
GATE (main): asserts the RFC 9113 §5.1 transition table is the "known answer".
The canonical client-GET no-body trajectory: new(1)==IDLE,
send_headers(IDLE, END_STREAM)==HC_LOCAL (open transited instantaneously per
the "immediately half-closed" rule), recv_headers(HC_LOCAL)==HC_LOCAL,
recv_data(HC_LOCAL, END_STREAM)==CLOSED. The with-body branch:
send_headers(IDLE, no-END_STREAM)==OPEN, send_data(OPEN, END_STREAM)==HC_LOCAL.
RST from any non-idle state -> CLOSED. Stream-id parity: 1/3/0x7FFFFFFF are
client (odd, nonzero, <=2^31-1), 0/2 are not. PLUS TAMPER / illegal-
transition cases on a SEPARATE state value (the canonical KAT states are never
dependencies 1 imports · 1 importers
imports: nx_h2_frame.nx
imported by: nx_h2_conformance.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| none |
functions
| 67 | func h2_stream_state_is_valid(state: i64) -> i64 |
| 79 | func h2_stream_id_is_client(stream_id: i64) -> i64 |
| 88 | func h2_stream_new(stream_id: i64) -> i64 |
| 99 | func h2_stream_send_headers(state: i64, end_stream: i64) -> i64 |
| 113 | func h2_stream_recv_headers(state: i64, end_stream: i64) -> i64 |
| 134 | func h2_stream_send_data(state: i64, end_stream: i64) -> i64 called by 1: main |
| 148 | func h2_stream_recv_data(state: i64, end_stream: i64) -> i64 |
| 167 | func h2_stream_recv_end_stream(state: i64) -> i64 called by 1: main |
| 175 | func h2_stream_send_rst(state: i64) -> i64 |
| 185 | func st_puts(s: *u8) -> i64 |
| 191 | func st_putn(v: i64) -> i64 |
| 206 | func st_fdn(fd: i64, v: i64) -> i64 called by 1: main |
| 220 | func st_check(name: *u8, got: i64, exp: i64) -> i64 |
| 232 | func main() -> i64 |