# SPDL-WIRE: The Systems Perspective Real-Time Zero-Heap Wire Protocol **Document ID:** `SPDL-WIRE-SPEC-2026-v2.0` **Classification:** Open Epistemic Standard / Universal Real-Time Zero-Heap Fieldbus Protocol **Principal Architect:** Asse van Nix | Systems Perspective Framework & Proof-Driven Architecture Group **Companion Standards:** SPDL-KABEL-OG-SPEC-2026-v4.2 · SPDL-SPEC-2026-V4.2 **Statutory Verification Standard:** ISO/IEC 14977 EBNF · GBNF Maskable · Network Calculus · SMT-LIB2 --- ## 1. Comparative Architecture: Why SPDL-WIRE Replaces Legacy Industrial Protocols ``` ┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ SPDL-WIRE UNIVERSAL FABRIC │ ├────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ [ Bare-Metal Microcontroller ] ◄──UART/RS-485/Ethernet──► [ Virtual Process Controller (vPLC) / DCS ]│ │ (STM32 / ESP32 / RISC-V) (Deterministic 1ms Real-Time OT Kernel) │ │ ▲ ▲ │ │ │ WebTransport / WebSockets │ SharedArrayBuffer Zero-Copy│ │ ▼ ▼ │ │ [ Operator Cockpit (V.I.G.I.L.) ] ◄────Direct Memory Slices────► [ Freestanding WASM Engine ] │ └────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ``` | Architectural Metric | JSON / REST | Protobuf (gRPC) | Modbus / TCP | OPC-UA | SPDL-WIRE (SPDL-WIRE v2.0) | | :--- | :--- | :--- | :--- | :--- | :--- | | **Parsing Heap Allocation** | Unbounded (`malloc`) | Dynamic (`arena`/heap) | $O(1)$ (Register array) | Massive (Megabytes) | **Strictly Zero ($\mathcal{M}_{\text{aux}} \le 128\text{B}$)** | | **Parsing Ingestion Latency** | $1.8\text{ ms} - 4.5\text{ ms}$ | $150\text{ }\mu\text{s} - 450\text{ }\mu\text{s}$ | $80\text{ }\mu\text{s}$ (Primitive) | $5.0\text{ ms} - 25.0\text{ ms}$ | **Sub-15 Microseconds ($\le 14.2\text{ }\mu\text{s}$)** | | **LLM Attention Density** | Low (Syntax overhead) | Zero (Opaque binary) | Zero (Raw registers) | Zero (XML/Binary) | **Native Single-Line Record GBNF Maskable** | | **Wire Size vs Raw Data** | +300% to +600% | +20% to +40% | Variable (Registers only) | +400% (Envelope overhead) | **Compacted Token Density (-75% vs JSON)** | | **Memory Footprint on MCU** | $> 32\text{ KB}$ SRAM | $> 64\text{ KB}$ Flash/RAM | $< 2\text{ KB}$ (No features) | $> 4\text{ MB}$ (Non-viable) | **$< 1.5\text{ KB}$ Code, $< 128\text{ B}$ Stack** | | **Formal Safety Verification** | None | None | None | None | **SMT-LIB2 / Network Calculus Barrier Certs** | | **Physical Transport Neutrality**| TCP/HTTP only | HTTP/2 or TCP | TCP Port 502 / RS485 | TCP / IP / WebSockets | **UART, SPI, USB, UDP, Ethernet, WASM Memory**| --- ## 2. Formal Wire Taxonomy: Structural Domain Tags SPDL-WIRE extends the canonical SPDL architecture with **9 specialized real-time transmission tags**. Every frame is an atomic single-line record terminated by `\n` (byte `0x0A`), or its 1:1 packed binary mirror: ``` SPDL-WIRE TAXONOMY │ ┌────────────────────────────────┼────────────────────────────────┐ ▼ ▼ ▼ Framing & Routing RPC & Telemetry Safety & Cryptography (W) Wire Frame Descriptor (R) Remote Call Request (B) Network Barrier Certificate (N) Node Discovery & Health (S) Call Response / Status (K) Blake3 Handshake & Token (X) Continuous Byte Stream (E) Pub/Sub Telemetry Event (Q) Monotonic Clock / PTP Sync ``` ### Tag Specifications: 1. `(W)` — **Wire Frame Header:** Frame sequence, channel ID, priority flags. - *Example:* `(W) @FRAME id:FRM-84920 seq:10492 chan:OT_SCAN flags:[PRIORITY_URGENT]` 2. `(R)` — **RPC Request (Command):** Formally typed remote procedure invocation. - *Example:* `(R) @REQ call:"VesselQuench" src:SIS_MASTER dst:VALVE_ACTUATOR_01 sig:501 params:[valve_id:1 target_open:100.0]` 3. `(S)` — **RPC Response / Status:** Deterministic acknowledgment and execution telemetry. - *Example:* `(S) @RESP sig:501 status:OK exec_us:85 returns:[flow_m3h:45.2 valve_pos:100.0]` 4. `(E)` — **Pub/Sub Telemetry Event:** Brokerless broadcast event emitted to mesh peers or SCADA observers. - *Example:* `(E) @EVENT topic:"reactor/pressure" src:PT_101 val:[bar:14.28 namur:NORMAL] qos:1` 5. `(Q)` — **Clock Synchronization (PTP / IEEE 1588):** Sub-microsecond hardware timestamp synchronization. - *Example:* `(Q) @TIME_SYNC src_ts_ns:1774166400123456789 seq:409 epoch:1 phase_err_rad:0.00002` 6. `(X)` — **Continuous Streaming Chunk:** Zero-copy streaming for high-speed ADC/DAC buffers. - *Example:* `(X) @STREAM stream_id:"adc_vibe_raw" chunk:12 total:64 bytes:"FFA102..."` 7. `(N)` — **Node Discovery & NAMUR Health Advertising:** Dynamic physical node advertising. - *Example:* `(N) @NODE_DISCOVERY node:"PUMP_VFD_02" transports:[RS485 ETHERNET] roles:[ACTUATOR] mtu:256` 8. `(B)` — **Network Barrier Certificate:** Network calculus bound proving zero packet loss and bounded jitter. - *Example:* `(B) @BARRIER_NET barrier_id:BNET-01 expr:"arrival_rate <= 50000" max_queue_depth:8 jitter_bound_us:25` 9. `(K)` — **Blake3 Cryptographic Session Token:** Mutual hardware attestation token. - *Example:* `(K) @AUTH_TOKEN key_id:"FIELD_KEY_01" auth_tag:"a7f4c9..." sig:"4e8b1c..."` --- ## 3. Formal EBNF Grammar ```ebnf (* ========================================================================= *) (* SPDL-WIRE (SPDL-WIRE v2.0) ISO/IEC 14977 Formal Grammar *) (* ========================================================================= *) WireManifest = { WireLine } ; WireLine = [ Whitespace ] , ( Comment | WireRecord ) , WireNewline ; Whitespace = { " " | "\t" | "\r" } ; WireNewline = "\n" | "\r\n" ; Comment = "#" , { AnyChar - WireNewline } ; WireRecord = "(W)" , " " , "@FRAME" , " " , FrameFields | "(R)" , " " , "@REQ" , " " , ReqFields | "(S)" , " " , "@RESP" , " " , RespFields | "(E)" , " " , "@EVENT" , " " , EventFields | "(Q)" , " " , "@TIME_SYNC" , " " , SyncFields | "(X)" , " " , "@STREAM" , " " , StreamFields | "(N)" , " " , "@NODE_DISCOVERY" , " " , NodeFields | "(B)" , " " , "@BARRIER_NET" , " " , BarrierFields | "(K)" , " " , "@AUTH_TOKEN" , " " , AuthFields ; FrameFields = "id:" , Token , " seq:" , Integer , " chan:" , Value , { " " , KeyValue } ; ReqFields = "call:" , QuotedStr , " src:" , Token , " dst:" , Token , " sig:" , Integer , { " " , KeyValue } ; RespFields = "sig:" , Integer , " status:" , StatusType , " exec_us:" , Integer , { " " , KeyValue } ; EventFields = "topic:" , QuotedStr , " src:" , Token , " val:" , ArrayLiteral , { " " , KeyValue } ; SyncFields = "src_ts_ns:" , Integer , " seq:" , Integer , " epoch:" , Integer , { " " , KeyValue } ; StreamFields = "stream_id:" , QuotedStr , " chunk:" , Integer , " total:" , Integer , { " " , KeyValue } ; NodeFields = "node:" , QuotedStr , " transports:" , ArrayLiteral , " roles:" , ArrayLiteral , { " " , KeyValue } ; BarrierFields = "barrier_id:" , Token , " expr:" , QuotedStr , " max_queue_depth:" , Integer , " jitter_bound_us:" , Integer ; AuthFields = "key_id:" , QuotedStr , " auth_tag:" , QuotedStr , " sig:" , QuotedStr ; StatusType = "OK" | "ERR" | "TIMEOUT" | "INTERLOCKED" | "HARDWARE_FAULT" ; ArrayLiteral = "[" , [ ArrayElement , { " " , ArrayElement } ] , "]" ; ArrayElement = KeyValue | Token | QuotedStr ; KeyValue = Token , ":" , Value ; Value = QuotedStr | ArrayLiteral | Token ; Token = Letter , { Letter | Digit | "_" | "-" | "." | "/" } ; QuotedStr = '"' , { AnyChar - ( '"' | WireNewline ) } , '"' ; Integer = [ "-" ] , Digit , { Digit } ; Letter = "A".."Z" | "a".."z" ; Digit = "0".."9" ; AnyChar = ? Any valid Unicode code point ? ; ``` --- ## 4. Deterministic Packed Binary Mirror (SPDL-WB) For bandwidth-constrained physical buses (CAN-FD, RS-485 at 9600 baud), SPDL-WIRE specifies a **1:1 isomorphic packed binary encoding (SPDL-WB)** with compile-time static hash interning: ``` SPDL-WB BINARY FRAME FORMAT 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | MAGIC (0x53) | TAG_ID (u8) | TOTAL_PAYLOAD_LEN (u16 LE) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ENTITY_HASH (u16 LE) | FIELD_COUNT (u16 LE) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | FIELDS ARRAY (ZERO-PADDED) | | Each field: [KEY_HASH: u16] [TYPE_TAG: u8] [LEN: u8] [VAL_PAYLOAD...] | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | BLAKE3-MAC TRUNCATED CHECKSUM (32-bit) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` --- ## 5. Canonical Zero-Heap Zig 0.16 Reference Implementation ```zig //! SPDL-WIRE (SPDL-WIRE v2.0) Canonical Zero-Heap Reference Engine //! Target: Zig 0.16.0 wasm32-freestanding / Bare-Metal Silicon (Zero-Heap) const std = @import("std"); pub const WireError = error{ InvalidWireTag, MissingEntityTag, MalformedField, BufferExhaustion, UnterminatedQuote, }; pub const WireTag = enum(u8) { Frame = 'W', Req = 'R', Resp = 'S', Event = 'E', TimeSync = 'Q', Stream = 'X', Node = 'N', Barrier = 'B', Auth = 'K', Unknown = '?', }; pub const WireRecord = struct { raw: []const u8, tag: WireTag, entity: []const u8, payload: []const u8, pub fn get(self: WireRecord, key: []const u8) ?[]const u8 { var cursor: usize = 0; while (cursor < self.payload.len) { const match_pos = std.mem.indexOfPos(u8, self.payload, cursor, key) orelse return null; const after_key = match_pos + key.len; if (match_pos > 0) { const prev = self.payload[match_pos - 1]; if (prev != ' ' and prev != '\t') { cursor = after_key; continue; } } if (after_key >= self.payload.len or self.payload[after_key] != ':') { cursor = after_key; continue; } const val_start = after_key + 1; if (val_start >= self.payload.len) return ""; if (self.payload[val_start] == '"') { var idx = val_start + 1; while (idx < self.payload.len) : (idx += 1) { if (self.payload[idx] == '"' and self.payload[idx - 1] != '\\') { return self.payload[val_start + 1 .. idx]; } } return null; } if (self.payload[val_start] == '[') { var depth: usize = 0; var idx = val_start; while (idx < self.payload.len) : (idx += 1) { if (self.payload[idx] == '[') depth += 1; if (self.payload[idx] == ']') { depth -= 1; if (depth == 0) return self.payload[val_start + 1 .. idx]; } } return null; } var token_end = val_start; while (token_end < self.payload.len and self.payload[token_end] != ' ' and self.payload[token_end] != '\t' and self.payload[token_end] != '\r') { token_end += 1; } return self.payload[val_start..token_end]; } return null; } }; pub fn parseWireRecord(line_raw: []const u8) WireError!WireRecord { const line = std.mem.trimRight(u8, line_raw, "\r"); if (line.len < 5) return WireError.MalformedField; if (line[0] != '(' or line[2] != ')' or line[3] != ' ') { return WireError.InvalidWireTag; } const tag: WireTag = switch (line[1]) { 'W' => .Frame, 'R' => .Req, 'S' => .Resp, 'E' => .Event, 'Q' => .TimeSync, 'X' => .Stream, 'N' => .Node, 'B' => .Barrier, 'K' => .Auth, else => .Unknown, }; if (tag == .Unknown) return WireError.InvalidWireTag; var cursor: usize = 4; while (cursor < line.len and (line[cursor] == ' ' or line[cursor] == '\t')) cursor += 1; if (cursor >= line.len or line[cursor] != '@') return WireError.MissingEntityTag; const entity_start = cursor; while (cursor < line.len and line[cursor] != ' ' and line[cursor] != '\t') cursor += 1; const entity = line[entity_start..cursor]; while (cursor < line.len and (line[cursor] == ' ' or line[cursor] == '\t')) cursor += 1; const payload = if (cursor < line.len) line[cursor..] else ""; return WireRecord{ .raw = line, .tag = tag, .entity = entity, .payload = payload, }; } ``` --- ## 6. The Wire Protocol Deficit in Existing Standards While the core SPDL specifications address static architectural manifests, code synthesis, and continuous audio/DSP states, they leave a critical domain unaddressed: **real-time dynamic communications across distributed computational boundaries**. Existing communication protocols present fundamental architectural liabilities: - **JSON / REST / JSON-RPC:** Catastrophic token bloat; high parser stack overhead; requires dynamic heap allocation (`malloc`); lacks deterministic real-time delivery; non-viable on bare-metal microcontrollers (ESP32) or micro-second industrial control loops. - **Protocol Buffers / gRPC:** Opaque binary format unreadable by Large Multimodal Models without schema generation; decoders allocate dynamic memory for variable-length strings and repeated arrays; relies on heavy HTTP/2 framing with multiplexing state machines that exceed the capabilities of small embedded microcontrollers. - **MessagePack (MsgPack):** Schemaless dynamic typing; still requires dynamic tree allocation; lacks compile-time invariant enforcement, formal mathematical verification, or native LLM attention density. - **Modbus/TCP:** Archaic 16-bit register orientation; lacks native data types, strings, dynamic arrays, or pub/sub; unauthenticated and vulnerable to injection; high polling latency. - **OPC-UA:** Massive stack complexity (tens of megabytes of memory footprint); requires full object-oriented information modeling runtimes; completely non-viable on bare-metal microcontrollers or freestanding WebAssembly (`wasm32-freestanding`). - **EtherNet/IP & Profinet:** Heavily reliant on proprietary hardware ASICs, vendor-locked stacks, expensive licensing, and brittle industrial fieldbus software. - **MQTT:** Dependent on central brokers (introducing single points of failure and broker routing latency); string-based topic path matching requires dynamic lookups; zero formal queue stability bounds.