# FOG Simplex Transfer Status: Draft 0.1 Date: 2026-08-08 ## 1. Purpose This document defines `FOG-SX`, the bounded, medium-independent simplex transfer contract used to move one committed opaque Composer export from a physically offline Composer toward an online blind relay. It fixes: - the transfer object and frame byte layouts; - padded transfer-size classes and their leakage; - profile selection without runtime negotiation; - forward-error-correction ownership and candidate gates; - acknowledgment-free sender and receiver state machines; - parser, memory, CPU, time, and storage ceilings; - common physical-backend requirements; - candidate QR, TOSLINK Lightpipe, and MIDI DIN profiles; - process isolation, failure behavior, and conformance evidence. This document records two non-active FEC candidates and three non-active physical-backend candidates. No candidate has an active numeric profile ID. No FOG-SX transfer is release-conformant until one complete joint profile has passed the activation gates in Section 22. The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY describe normative requirements in the sense of BCP 14 when they appear in uppercase. ## 2. Scope FOG-SX owns the path: ```text committed Composer RELAY_EXPORT bundle -> sandboxed FOG-SX export encoder -> physically transmit-only backend -> one-way medium -> physically receive-only backend -> sandboxed FOG-SX transfer receiver -> bounded reconstructed Composer bundle -> blind-relay queue ``` FOG-SX version 1 carries exactly one complete Composer `RELAY_EXPORT` bundle per transfer. It does not carry a filename, directory, stream name, MIME type, URI, archive, compressed object, filesystem, document, script, executable, or device command. FOG-SX does not own: - Composer bundle semantics, record allowlists, or spool transitions; - KEMSphinx, messaging, storage, PKI, contact, update, or recovery authentication; - blind-relay acceptance or delivery evidence; - online-to-offline Composer import; - a removable-media filesystem format; - generic optical, serial, audio, or camera device control; - anonymity, cover traffic, or traffic-analysis resistance on the physical link. Online-to-offline input uses a separately controlled receive-only Composer path. It is not an FOG-SX acknowledgment channel and is not the reverse direction of the same peripheral. ## 3. Security Boundary The raw backend stream, every frame header, every symbol, every FEC parameter, and every reconstructed transfer object are attacker-controlled input. The transfer receiver is outside the blind relay's trusted protocol state. It MUST NOT hold: - relay network credentials or Noise private keys; - Composer, user identity, messaging, storage, or PKI private keys; - message plaintext, contacts, capabilities, routes, or application state; - a shell, compiler, package manager, general browser, or general writable filesystem; - a bidirectional interface to the offline Composer. The receiver outputs only one bounded byte string that still has to pass the complete `FOG-COMPOSER` bundle parser and every owning inner authentication rule. FEC recovery, CRC success, SHA-256 equality, transfer-ID equality, physical directionality, and operator observation confer no authenticity. Applicable requirements include `ARC-002`, `ARC-004`, `ARC-007`, `ARC-008`, `ARC-009`, `IF-01`, `IF-02`, `TM-ENDPOINT-01`, `TM-ENDPOINT-02`, `TM-OPS-01`, `TM-SUPPLY-01`, `TM-CRYPTO-01`, `TM-CRYPTO-02`, and `TM-AVAIL-01`. ## 4. Version-1 Invariants Every active FOG-SX version-1 profile MUST preserve all of these invariants: 1. Data flows in one physical direction during a transfer. 2. The receiver sends no automatic acknowledgment, control, clock, retry, negotiation, or completion signal to the sender. 3. One exact joint profile is configured before transfer. There is no autodetection, negotiation, opportunistic upgrade, or downgrade. 4. Frames have one fixed size within a joint profile. 5. One transfer contains one padded transfer object and one Composer bundle. 6. Exact bundle length is hidden only within a declared size class. 7. All integers use unsigned network byte order. 8. Reserved bytes and unknown flags are zero. Any other value rejects the frame or object. 9. CRC32C and SHA-256 are error-detection and reconstruction checks only. 10. The complete inner Composer bundle is validated before relay state changes. 11. Resource limits are checked before allocation or FEC work. 12. The backend cannot introduce filenames, metadata records, control messages, or an automatic return path. 13. Unknown profile, frame, size-class, and FEC identifiers fail closed. 14. Profile behavior is immutable for its numeric identifier. ## 5. Terms - `ComposerBundle`: the byte-exact object defined by `FOG-COMPOSER`. - `TransferObject`: the 128-byte FOG-SX object header, one ComposerBundle, and zero padding to an exact size-class capacity. - `source symbol`: one fixed-length slice used by the selected FEC. - `repair symbol`: one FEC-generated symbol that is not an original source symbol. - `source block`: one independently recoverable group of source symbols. - `frame`: one 96-byte FOG-SX header, one symbol payload, and one trailing CRC32C. - `joint profile`: the immutable tuple of format, backend, FEC, size, scheduling, and resource parameters accepted by both endpoints. - `receive window`: one explicit local operator action that permits the receiver to admit a new transfer. - `completion indication`: local human-visible receiver output. It is not a protocol message. ## 6. Profile Registry ### 6.1 Joint profile An `sx_profile_id` identifies one complete immutable registry entry containing at least: - FOG-SX format version; - permitted transfer direction and Composer bundle kind; - backend profile ID and hardware assurance level; - FEC profile ID, exact algorithm revision, and implementation constraints; - allowed size-class IDs; - symbol payload length; - object partitioning into source blocks and symbols; - encoding-symbol-ID range and mapping; - systematic, repair, interleaving, and repetition schedule; - physical framing, modulation, bitrate, clock recovery, and timeout; - CRC32C representation; - sender cycle and duration ceilings; - receiver frame, memory, storage, CPU, conflict, and decode-attempt budgets; - release, dependency, and test-vector identity. The separately encoded backend, FEC, and size-class IDs let the receiver reject inconsistent headers early. They do not permit the sender to assemble a new tuple. Every field MUST equal the configured joint-profile entry. ### 6.2 Distribution and activation The registry ships as immutable release data. It is not learned from the raw stream. Numeric ID zero is invalid. Candidate names in this document are symbolic and MUST NOT be placed on the wire as numeric IDs. Changing an algorithm, parameter, schedule, dependency, hardware assumption, or parser limit requires a new joint profile ID. An implementation MUST NOT reinterpret an old ID after an update. The operator selects one backend and one joint profile before opening a receive window. A decoder MUST NOT scan multiple frame formats, CRC variants, FEC schemes, or physical modulations to discover what the sender meant. ## 7. Padded Size Classes ### 7.1 Class definition A size class fixes `bundle_capacity`, the maximum number of ComposerBundle bytes carried in its TransferObject. The exact FEC source length is: ```text transfer_object_length = 128 + bundle_capacity ``` The TransferObject is: ```text 128-byte TransferObjectHeader composer_bundle_length bytes of ComposerBundle bundle_capacity - composer_bundle_length zero bytes ``` The sender selects the smallest class permitted by the joint profile whose capacity is at least the exact committed bundle length. The sender MUST NOT repack, reorder, compress, split, or semantically modify the committed bundle to obtain another class. ### 7.2 Version-1 structural class table The structural registry reserves these capacities. A joint profile activates only an explicit subset. | Symbolic class | `bundle_capacity` | Intended use | | --- | ---: | --- | | `SX-C16K-1` | 16 KiB | small fixtures and constrained visual trials | | `SX-C64K-1` | 64 KiB | small relay batches | | `SX-C256K-1` | 256 KiB | ordinary relay batches | | `SX-C1M-1` | 1 MiB | large relay batches | | `SX-C4M-1` | 4 MiB | optical-only candidate | | `SX-C16M-1` | 16 MiB | optical-only candidate | | `SX-C64M-1` | 64 MiB | Composer relay parser ceiling | `KiB` and `MiB` mean powers of 1024. No version-1 FOG-SX class exceeds 64 MiB of bundle capacity. Update, recovery, contact, and import bundles are outside the version-1 FOG-SX direction even when their Composer limits would fit. ### 7.3 Leakage Padding hides only the exact bundle length inside the selected class. A physical observer and the receiver can observe at least the backend, timing, class, frame count, losses, repetition duration, and operator behavior. The systematic source symbols of the same committed Composer bundle remain correlatable across retransfers even when the transfer ID changes. FOG-SX does not claim rerandomization or unlinkability. A future authenticated and encrypted local Composer-relay envelope would be a separate Composer profile, not an implicit property of FOG-SX. ## 8. TransferObject Header ### 8.1 Exact 128-byte layout ```text offset length field 0 8 magic 8 2 sx_format_version 10 1 object_kind 11 1 flags 12 4 sx_profile_id 16 4 backend_profile_id 20 4 fec_profile_id 24 4 size_class_id 28 32 transfer_id 60 8 composer_bundle_length 68 8 transfer_object_length 76 32 composer_bundle_digest 108 16 reserved 124 4 header_checksum ``` `magic` is the eight ASCII octets `FOGSXO1` followed by line feed, with hex value `46 4f 47 53 58 4f 31 0a`. `sx_format_version` is 1. `object_kind` is 1 for `RELAY_EXPORT`. `flags` is zero. `reserved` is sixteen zero octets. `transfer_id` is exactly 32 bytes sampled from the operating system CSPRNG for one new transfer attempt. It is not a user identity, authenticity value, nonce for encryption, replay token, or receipt. `composer_bundle_length` is the exact byte length of the committed bundle. It MUST be at least the 128-byte Composer outer header and no greater than the selected `bundle_capacity` or the Composer `RELAY_EXPORT` limit. `transfer_object_length` MUST equal `128 + bundle_capacity` for the selected class. It is redundant by design and MUST match the registry before the receiver allocates object storage. `composer_bundle_digest` is SHA-256 over the exact ComposerBundle bytes only, not over TransferObject padding. It detects reconstruction and storage errors and supports local duplicate handling. Because it is unkeyed and sent with the object, an attacker can replace it. It provides no authenticity. ### 8.2 Header checksum `header_checksum` is CRC32C using the algorithm and wire representation of RFC 3309. For calculation, the four header-checksum octets are zero. The CRC covers all 128 header octets and does not cover the bundle or padding. The decoded header is not trusted merely because its CRC is correct. The receiver validates it against frame fields and the configured registry before using lengths or counts. ### 8.3 Canonical padding Every byte after the exact ComposerBundle and before the end of the selected TransferObject MUST be zero. Non-zero padding rejects the complete object. Trailing data beyond `transfer_object_length` is not part of the object and cannot be delivered to the relay. ## 9. SXFrame ### 9.1 Exact 96-byte header ```text offset length field 0 8 magic 8 2 sx_format_version 10 1 frame_kind 11 1 flags 12 4 sx_profile_id 16 4 backend_profile_id 20 4 fec_profile_id 24 4 size_class_id 28 32 transfer_id 60 4 source_block_number 64 4 source_block_count 68 4 source_symbol_count 72 4 encoding_symbol_id 76 4 symbol_length 80 12 reserved 92 4 header_checksum ``` The fixed frame is: ```text 96-byte SXFrameHeader symbol_length bytes of symbol_payload 4-byte frame_checksum ``` `magic` is the eight ASCII octets `FOGSXF1` followed by line feed, with hex value `46 4f 47 53 58 46 31 0a`. `sx_format_version` is 1. `frame_kind` is 1 for `SYMBOL`. No `END`, `ACK`, `NAK`, negotiation, capability, metadata, filename, or control frame exists in version 1. Backend idle and acquisition patterns remain outside SXFrame and carry no transfer data. `flags` and `reserved` are zero. `symbol_length` equals the joint profile's fixed symbol payload length. Every frame in the profile therefore has exactly `100 + symbol_length` bytes. ### 9.2 Block and symbol fields `source_block_count` and `source_symbol_count` are redundant values derived from the size class and FEC profile. They MUST match the registry calculation. `source_block_number` is less than `source_block_count`. `encoding_symbol_id` is interpreted only by the configured FEC profile and MUST be inside that profile's declared range for the block. The tuple: ```text (sx_profile_id, transfer_id, source_block_number, encoding_symbol_id) ``` identifies one candidate symbol. It is not authenticated. Two byte-identical copies are duplicates. Two different payloads for the same tuple are a conflict and trigger the bounded conflict policy in Section 15. ### 9.3 Checksums `header_checksum` is CRC32C over the complete 96-byte header with that field zero. It permits early rejection before symbol allocation. `frame_checksum` is CRC32C over the transmitted 96-byte header, including its filled header checksum, followed by the exact symbol payload. The trailing frame-checksum field is excluded from its own calculation. Both CRC values use RFC 3309 CRC32C. A mismatch silently discards the frame. A matching CRC does not authenticate the sender or symbol. ## 10. FEC Contract ### 10.1 Ownership The FEC profile, not the raw stream, fixes: - exact standard and revision; - source-object partition algorithm; - symbol alignment and length; - minimum and maximum source symbols per block; - source-block count calculation; - source and repair encoding-symbol-ID mapping; - maximum accepted ESI; - repair-symbol generation; - decoder input-selection and conflict rules; - decode-attempt thresholds and maximum attempts; - per-block memory, operation, and wall-time budgets; - exact implementation and license evidence accepted for release; - deterministic positive and negative vectors. FEC parameters MUST NOT be inferred from attacker-selected counts. The frame counts are checked copies of values derived from the configured profile and size class. ### 10.2 Source partition The complete padded TransferObject is the FEC source object. The profile partitions it into ordered source blocks and fixed-length source symbols. Only the last source symbol of the last block may require FEC-internal zero fill, and the profile must make this fill byte-exact and distinguish it from TransferObject padding. Each source block decodes independently. Receiver code MUST NOT allocate the entire candidate FEC matrix when one block is being decoded unless the active profile's reviewed memory bound explicitly permits it. ### 10.3 Corruption and injection FEC corrects erasures and some physical errors after failed frames are discarded. It does not provide integrity against a malicious sender. One forged but CRC-consistent encoding symbol may poison a decode. After all blocks decode, the receiver therefore validates, in order: 1. exact TransferObject length; 2. exact 128-byte header and header CRC32C; 3. all profile, transfer, length, kind, reserved, and padding fields; 4. SHA-256 over the exact ComposerBundle; 5. exact Composer outer structure and direction; 6. owning inner authentication in the relay or Composer processing path. A failure at any step discards the reconstructed candidate and makes no relay state change. ## 11. Non-Active FEC Candidates ### 11.1 RaptorQ candidate `FOG-SX-CANDIDATE-RAPTORQ-RFC6330-1` evaluates the fully specified RaptorQ scheme in RFC 6330. Potential advantages: - systematic source symbols; - repair symbols generated as needed without a fixed transmitted total; - good fit for acknowledgment-free repeated emission; - substantially larger source blocks than GF(256) Reed-Solomon. Required review items: - exact RFC parameter derivation and ESI mapping; - decoder CPU and memory behavior on malformed or adversarial symbols; - constant parser ceilings far below RFC maximums where appropriate; - maintained implementation quality, unsafe-language containment, fuzzing, and cross-implementation vectors; - dependency license and the IETF RaptorQ IPR disclosures, including the conditions and defensive-assertion language of disclosure 2554; - full-object corruption and injection handling before relay delivery. No implementation may claim that the RFC's large theoretical object limit is a FOG-SX permission to allocate or process that amount. ### 11.2 Reed-Solomon candidate `FOG-SX-CANDIDATE-RS-GF256-RFC5510-1` evaluates systematic Reed-Solomon over GF(2^8) using the fully specified construction in RFC 5510. Potential advantages: - mature, deterministic block-code behavior; - recovery of `k` source symbols from any `k` valid encoding symbols for the specified MDS construction; - simpler finite redundancy and decode scheduling for small blocks. Constraints: - GF(2^8) provides at most 255 encoding symbols per source block; - the profile must fix `k`, `n`, redundancy, block partitioning, and the behavior after all `n` symbols have been emitted; - additional repetition cannot create new repair symbols beyond the fixed codeword and therefore handles burst losses less flexibly than a fountain schedule; - poisoned CRC-consistent symbols can still corrupt a decoded block. ### 11.3 Selection rule Neither candidate is selected by this draft. Selection requires measured results for all activated size and backend classes, complete license review, dependency maintenance evidence, bounded hostile-input tests, independent vectors, and reproducible resource measurements. An implementation MAY build isolated experimental adapters for both candidates. It MUST NOT assign a production numeric ID or silently choose one at runtime. ## 12. Sender State Machine The sender uses these states: ```text IDLE -> PREPARED -> EMITTING -> STOPPED PREPARED or EMITTING -> FAILED ``` ### 12.1 Prepare To enter `PREPARED`, the export encoder: 1. receives read-only access to one immutable committed Composer spool item; 2. verifies exact bundle length and the selected size class; 3. samples a fresh 32-byte transfer ID from the OS CSPRNG; 4. creates the canonical TransferObject header; 5. streams the bundle and zero padding into the FEC encoder; 6. derives every block and schedule parameter from the configured registry; 7. confirms sender memory, time, frame, and output-device budgets; 8. closes every input not required for emission. It does not parse message contents or query Composer state. Failure creates no partial success indication and does not mutate the committed Composer bundle. ### 12.2 Emit The joint profile defines one deterministic cycle containing systematic and repair symbols interleaved across source blocks. The schedule SHOULD disperse adjacent source data and block repair across time so that one physical burst does not erase a contiguous object region. The exact schedule, repair quota, block permutation, and ESI sequence are profile inputs, not operator options. The sender repeats complete cycles until one of: - the human explicitly stops after observing receiver completion; - the configured maximum cycle count is reached; - the configured monotonic-duration ceiling is reached; - the backend or resource monitor fails closed. The sender never waits for receiver data and never changes its schedule based on light, sound, serial input, network input, USB control input, or timing purportedly supplied by the receiver. ### 12.3 Stop and retry Stopping emission does not mean the relay accepted, queued, or delivered the bundle. It records only a local transmitter event. A new manual transfer attempt uses a fresh transfer ID. It MAY reuse the exact committed ComposerBundle while its spool-retention policy permits. It MUST NOT rewind message, ratchet, storage, packet, or Composer state merely because the physical transfer was stopped or failed. ## 13. Receiver State Machine The receiver uses: ```text CLOSED -> ARMED -> COLLECTING -> RECONSTRUCTING -> COMPLETE ARMED, COLLECTING, or RECONSTRUCTING -> FAILED COMPLETE or FAILED -> CLOSED ``` ### 13.1 Arm `CLOSED` admits no new transfer. An explicit local operator action chooses the backend, joint profile, and allowed size classes and opens one bounded receive window. The high-assurance receiver admits at most one active transfer. It creates no state from idle patterns, CRC-failed data, unknown IDs, or a frame that does not match the configured profile. ### 13.2 Collect The first valid frame may establish the candidate transfer ID and size class only after all fixed header, CRC, profile, and derived-count checks pass. Later frames with another transfer ID are silently dropped while the slot is occupied. For one symbol tuple, the receiver: - stores the first CRC-valid payload within budget; - ignores an exact byte-identical duplicate; - counts a different CRC-valid payload as a conflict; - never lets a conflicting later payload silently replace an earlier one; - aborts the transfer when the profile conflict ceiling is exceeded. Symbols are stored in bounded per-block structures. Raw physical frames and failed frames are not retained after the minimal counters needed for the local status display. ### 13.3 Reconstruct The decoder attempts one block only at profile-defined unique-symbol thresholds and intervals. Receipt of duplicates, conflicts, bad CRCs, or arbitrary ESIs MUST NOT trigger unbounded repeated matrix work. Decoded blocks are staged in their exact object offsets. The receiver cannot publish a partial object. After every block is present, it performs the full validation sequence in Section 10.3 and streams the exact ComposerBundle into one exclusively created bounded relay-ingress object. ### 13.4 Complete `COMPLETE` means only that one byte-exact candidate passed FOG-SX structural validation and was durably handed to the bounded relay-ingress queue. It does not mean inner authentication, network submission, storage commit, or final delivery succeeded. The receiver MAY show a local light, fixed icon, or coarse text indication to the human. It MUST NOT send a frame, network callback, sound, optical flash, USB control transfer, or other automatic completion signal to the sender. ## 14. Validation Order Before Allocation For each backend-delivered candidate frame, the receiver performs: 1. enforce the exact backend unit length; 2. locate the one profile-defined frame boundary without format scanning; 3. validate magic and version; 4. require `frame_kind = SYMBOL`, zero flags, and zero reserved bytes; 5. compare all profile IDs with the configured joint profile; 6. require the exact fixed symbol length; 7. validate the header CRC32C; 8. validate the complete frame CRC32C; 9. derive and compare size, block, source-symbol, and ESI bounds; 10. enforce active-transfer, duplicate, conflict, storage, and work budgets; 11. only then copy the symbol into bounded FEC storage. All additions and multiplications involving untrusted fields use checked integer arithmetic. A decoder MUST NOT cast an untrusted 32-bit count to a smaller type, allocate from it, or multiply it before checking the profile- derived expected value. ## 15. Version-1 Absolute Ceilings These are implementation ceilings. Active profiles MUST be equal or stricter. | Resource | Absolute ceiling | | --- | ---: | | Frame header | exactly 96 bytes | | Symbol payload | 4096 bytes | | Complete frame | 4196 bytes | | TransferObject header | exactly 128 bytes | | Composer bundle capacity | 64 MiB | | TransferObject length | 64 MiB + 128 bytes | | Active transfer IDs, high assurance | 1 | | Active transfer IDs, lower assurance | 2 | | Source blocks per transfer | 65536 | | Source symbols per block | 4096 | | Accepted unique symbols per block | 8192 | | Conflicting tuples per block | 16 | | FEC decode attempts per block | 32 | | Simultaneous block decoders | 2 | | Staged decoded object bytes | one selected TransferObject | | Retained failed raw frames | 0 | | Receive window | 24 monotonic hours | | Sender cycles | 65535 | | Parser nesting | forbidden | | Decompression | forbidden | The active profile defines lower backend-appropriate duration, cycle, block, symbol, memory, disk, and CPU budgets. The receiver stops accepting symbols while a block decode consumes its quota. A timeout, disk-full condition, memory-pressure event, excessive conflict rate, dependency panic, or budget exhaustion aborts the candidate and returns to a safe closed state. Counters used only for resource enforcement saturate rather than wrap. They are reset when the receive window closes and are not exported as telemetry. ## 16. Duplicate, Replay, and Injection Behavior FOG-SX has no authenticated replay protection. A malicious source can copy or recreate all of its public fields and checksums. The receiver MAY maintain a bounded local cache of recently completed tuples: ```text (sx_profile_id, transfer_id, composer_bundle_digest, composer_bundle_length, size_class_id) ``` An exact completed duplicate can be discarded before a second relay-ingress write. The cache is a local availability control, not proof that another transfer with the same ID or digest is authentic. Composer and the owning inner protocols retain final deduplication and replay authority. A new transfer ID does not authorize a duplicate message, receipt, storage write, or state transition. ## 17. Common Physical-Backend Contract Every backend profile fixes: - one direction and one physical transmitter/receiver role; - exact connector, module class, and electrical or optical assumptions; - raw carrier framing and acquisition pattern; - modulation, line coding, symbol rate, bitrate, and clock tolerance; - mapping from one complete SXFrame to carrier units; - acquisition, frame, idle, loss, and end-of-window timeouts; - maximum supported size classes and expected transfer duration; - device-open flags, driver allowlist, and prohibited device capabilities; - physical teardown, continuity, and direction tests; - emitted-light, sound, electromagnetic, and human-visible safety constraints; - deterministic vectors captured above and below the backend boundary. Backend code transports exact SXFrame bytes. It MUST NOT reinterpret a frame as text, Base64, a file, MIDI music, audio content, a URL, or a document unless the specific profile defines one fixed byte mapping solely as carrier coding. The high-assurance profile requires separate unidirectional components whose physical construction enforces direction. Software configuration, a disabled receive API, driver policy, or a supposedly unused bidirectional transceiver is insufficient. The offline side exposes only a transmitter data input. The online side exposes only a receiver data output. No common USB controller, shared debug UART, management bus, network interface, storage controller, radio, or bidirectional data cable may bridge the trust domains. ## 18. QR Candidate `FOG-SX-CANDIDATE-QR-MODEL2-1` uses fixed-version QR Code Model 2 symbols as a visual carrier from an offline display to an online camera. Before activation it must fix: - the ISO/IEC 18004 edition; - QR version, byte mode, mask selection rule, and error-correction level; - one exact binary mapping with one complete SXFrame per QR symbol and no QR structured append or backend-level SXFrame fragmentation; - quiet zone, module size, contrast, display refresh, dwell, and blanking; - camera resolution, frame rate, exposure, focus, decoder, and timeout; - maximum FOG-SX size classes and operator ergonomics; - rejection of URLs, text actions, structured append outside the exact profile, and general barcode dispatch. QR Code has its own Reed-Solomon error correction. That layer improves visual recovery but does not authenticate FOG-SX or replace the frame CRC, object digest, FEC profile, or inner Composer authentication. The camera is an attack surface. The online receiver uses a dedicated camera or capture path with no microphone, speaker, storage automount, network, vendor cloud service, or automatic barcode action. An online display used for separate Composer import is not an acknowledgment and must not be driven by FOG-SX receive state. ## 19. FOG Lightpipe Candidate `FOG-SX-CANDIDATE-LIGHTPIPE-NRZ-1` is the preferred high-throughput candidate. It uses a discrete optical transmitting module on the offline side, one fiber, and a discrete optical receiving module on the online side. The high-assurance construction requires: - a transmitter-only module, such as the TOSLINK `TOTX` class; - a receiver-only module, such as the TOSLINK `TORX` class; - no `TODX` transceiver, duplex module, second fiber, or receiver on the offline board; - no transmitter, display-controlled return light, or software-controlled emitter on the online board; - galvanically separated power and no data-bearing ground or debug path between boards; - a simple allowlisted hardware interface whose offline driver can only emit and whose online driver can only receive; - schematics, bill of materials, board photographs, continuity tests, optical direction tests, and teardown evidence for the exact hardware revision. FOG does not assume that a PC provides a native TOSLINK port. The intended high-assurance profile uses dedicated offline `TOTX` and online `TORX` boards with narrowly allowlisted local interfaces. A consumer optical audio port or adapter may support a functional experiment but does not establish physical directionality. The optical diode constrains data flow through the selected fiber only. It cannot stop a compromised offline Composer from placing plaintext, keys, or a covert signal into the permitted offline-to-online output, and it cannot protect unlocked Composer state from compromised local firmware, drivers, peripherals, or host software. TOSLINK defines optical transmitter and receiver device classes, not the complete FOG-SX modulation. Before activation the candidate must fix the exact NRZ or self-clocking line code, bitrate, transition density, preamble, clock recovery, frame delimiter, escaping, idle pattern, light polarity, optical module, fiber, distance, jitter, and error tests. Consumer S/PDIF or USB audio adapters are lower assurance. They may contain bidirectional USB control, opaque firmware, audio clocks, mixers, microphones, or unexpected device functions. They MUST NOT satisfy the high-assurance Lightpipe profile merely because their payload leaves through an optical jack. A second online-to-offline optical system, if ever deployed for Composer import, is a separately powered, separately controlled path with its own receive-only offline hardware. It is not simultaneously active, is not connected to FOG-SX state, and does not turn the export construction into a duplex protocol. ## 20. MIDI DIN Candidate `FOG-SX-CANDIDATE-MIDI-DIN-1` uses one MIDI DIN OUT circuit to one optically isolated MIDI DIN IN circuit as a lower-throughput experimental carrier. The MIDI 1.0 electrical specification defines a 31.25 kbaud asynchronous 8-N-1 interface, a 5 mA current loop, and receiver opto-isolation. The active candidate must use that electrical direction, not a bidirectional USB MIDI device. Before activation it must fix: - exact byte transparency and framing above the MIDI serial byte; - handling or prohibition of status-byte semantics and running status; - escaping, preamble, frame delimiter, resynchronization, and idle behavior; - maximum frame payload and size class consistent with transfer duration; - compliant OUT, IN, cable, shield, grounding, and opto-isolator circuits; - absence of MIDI THRU or any offline input path; - hostile jitter, disconnect, stuck-bit, burst-loss, and opto-isolator tests. The carrier must not expose FOG-SX bytes to a general music application, synthesizer plugin, device-discovery service, or cloud-connected MIDI stack. ## 21. Other Backends Visible LED, screen-to-photodiode, audible modem, opto-isolated TX-only serial, and punched paper tape remain architectural possibilities. None is specified by this document and none may reuse a QR, Lightpipe, or MIDI backend ID. Each future backend needs its own threat analysis, exact physical and byte mapping, hardware-direction proof, resource profile, conformance vectors, and release gate. A generic runtime driver or modulation plugin system is not a substitute for separately reviewed profiles. ## 22. Candidate Activation Gates A joint FOG-SX profile receives a numeric ID only after all of these are complete: 1. byte-exact frame, object, size, FEC, schedule, and backend parameters; 2. two independent encoders and decoders or one implementation plus an independent vector generator; 3. known-answer vectors for every size class and boundary value; 4. dependency, license, IPR, maintenance, and supply-chain review; 5. parser fuzzing with malformed headers, lengths, IDs, CRCs, padding, and trailing data; 6. hostile FEC corpus covering duplicates, conflicts, poisoned symbols, excessive ESIs, singular decode inputs, and resource exhaustion; 7. reproducible CPU, memory, disk, frame, time, and energy measurements; 8. crash, interruption, power-loss, disk-full, and restart testing; 9. physical directionality inspection and tests for the exact hardware; 10. confirmation that no automatic sender-visible completion path exists; 11. complete Composer and relay integration with inner authentication before state change; 12. independent security review of parser, FEC, hardware, and claims. A local loopback, virtual QR camera, paired serial ports, audio adapter, or single board can provide functional evidence only. It cannot establish a physical data-diode or production endpoint-security claim. ## 23. Implementation Shape The protocol implementation should preserve these logical modules: ```text protocol/sx/ frame/ fixed header parsing, serialization, and CRC object/ TransferObject construction, padding, and validation profile/ immutable registry and derived parameter checks fec/ narrow profile-specific encoder and decoder interfaces schedule/ deterministic sender schedule receiver/ bounded collection and reconstruction state machine backend/ qr/ exact visual carrier edge lightpipe/ exact optical carrier edge midi/ exact current-loop carrier edge ``` The process boundary is: ```text offline: fog-compose -> sealed spool -> fog-sx-send -> TX-only device online: RX-only device -> fog-sx-receive -> bounded relay ingress ``` `frame`, `object`, and profile validation are pure protocol code and do not open devices or files. FEC implementations receive already bounded slices and profile constants. Backend modules do not parse Composer bundles or implement FEC. The transfer receiver is a separate executable from `fog-client-relay`. There is no generic plugin loader, dynamic library selected by wire input, universal device daemon, or in-process backend autodetection. Candidate FEC libraries written in an unsafe language run behind the narrowest practical sandbox and process boundary with fixed memory and CPU limits. ## 24. State, Retention, and Logging The offline sender may read only the selected immutable spool item and its public transfer profile. It stores no new long-term secret. Transfer IDs are public ephemeral metadata and follow the spool attempt's bounded lifetime. The online receiver retains: - one bounded active symbol set during a receive window; - one staged decoded TransferObject until complete validation; - one exact ComposerBundle until durable relay-ingress handoff; - a bounded recent-completion cache if enabled; - coarse saturating error counters for the current local session. It deletes failed symbols, failed objects, padding, and raw frames after the owning failure or completion path. Deletion is best effort on flash and other journaled storage and is not claimed as forensic erasure. Logs and support output MUST NOT contain raw frames, symbols, transfer IDs, bundle digests, Composer bytes, frame timing traces, device serial numbers, camera images, audio captures, filesystem paths, or host identity. Local status may show coarse progress, current class, and a generic failure category without exporting telemetry. ## 25. Conformance Tests Before the local PoC, deterministic tests must cover: - exact 128-byte object and 96-byte frame headers; - both magic values, version, kind, zero flags, and reserved bytes; - big-endian integers and checked arithmetic; - every boundary around each size class and the 64 MiB ceiling; - exact zero padding and rejection of non-zero or trailing bytes; - SHA-256 and both CRC32C calculation domains and wire values; - wrong profile tuple, symbol length, counts, block number, and ESI; - exact duplicate and conflicting symbols; - all FEC success, insufficient-symbol, poisoned-symbol, and abort paths; - deterministic schedule and interleaving across cycles; - receiver window, transfer-slot, decode-attempt, time, memory, disk, and CPU limits; - no partial output after any frame, block, object, or Composer failure; - exact one-bundle relay-ingress handoff and duplicate suppression; - sender stop and retry without state rewind; - absence of ACK, reverse device access, network callback, and adaptive sender behavior; - each physical backend's acquisition, loss, jitter, disconnect, and directionality fixtures; - mutation, coverage-guided fuzz, property, race, crash, and fault-injection testing at every parser and process boundary. Cross-implementation vectors include exact TransferObject bytes, every source and repair symbol, frame bytes, CRCs, schedule order, reconstructed bytes, and expected rejection reason class. Rejection classes are test outputs, not remote protocol responses. ## 26. Failure Behavior Malformed, unknown, inconsistent, oversized, stale, conflicting, timed-out, or resource-exhausting input fails closed. The receiver sends nothing toward the transmitter and publishes no partial Composer bundle. The local UI distinguishes only coarse states such as waiting, collecting, checking, complete, timed out, incompatible profile, and failed. Detailed parser positions, CRC values, FEC matrices, raw input, transfer IDs, and digests are unavailable to the physical sender and excluded from ordinary logs. If completion is uncertain, the human may stop and later restart a fresh transfer attempt. Neither endpoint treats uncertainty as permission to bypass Composer deduplication, inner authentication, or protocol state rules. ## 27. Threat and Architecture Traceability | Requirement | Primary controls | | --- | --- | | `ARC-002` | networkless Composer, TX-only export, no automatic reverse path | | `ARC-004` | transfer receiver has no relay, user, messaging, or storage keys | | `ARC-007` | no FOG-SX secret; explicit ephemeral transfer-ID ownership | | `ARC-008` | exact headers, fixed frames, derived counts, absolute ceilings | | `ARC-009` | unknown profile, corruption, ambiguity, and exhaustion fail closed | | `IF-01` | one committed opaque export, sandboxed encoder and receiver | | `IF-02` | import remains a separate controlled direction, never an ACK path | | `TM-ENDPOINT-01` | dedicated offline process and directional hardware assumptions | | `TM-ENDPOINT-02` | bounded binary format, parser sandbox, no archive or filesystem | | `TM-OPS-01` | no raw transfer logging, device identity, telemetry, or support dump | | `TM-SUPPLY-01` | exact dependencies, hardware revision, license and release gates | | `TM-CRYPTO-01` | CSPRNG transfer IDs, SHA-256 limited to error detection | | `TM-CRYPTO-02` | immutable release registry, no negotiation or downgrade | | `TM-AVAIL-01` | receive windows, one slot, conflict and FEC work budgets | ## 28. Claims Deliberately Withheld FOG-SX does not yet establish: - an active FEC algorithm, implementation, or numeric profile; - an active physical backend, bitrate, symbol size, or hardware design; - physical one-way assurance from software configuration alone; - authenticity, confidentiality, replay protection, or non-repudiation at the FOG-SX layer; - unlinkability of retransferred Composer bundles; - concealment of transfer occurrence, timing, size class, frame count, or physical location; - resistance to a compromised offline Composer, online receiver, firmware, camera, USB controller, optical module, or supply chain; - elimination of optical, acoustic, electromagnetic, thermal, power, or human-mediated covert channels; - production security from a loopback, animated QR demo, consumer TOSLINK adapter, USB MIDI adapter, or local PoC; - successful network delivery merely because local reconstruction completed. ## 29. Open Dependencies The structural FOG-SX contract is fixed, but these remain open: - selection between the RaptorQ and Reed-Solomon candidates or a separately reviewed replacement; - exact FEC parameters, implementation, dependency version, and license decision; - byte-exact joint profile IDs and size-class subsets; - exact QR geometry, decoder, frame mapping, and transfer-duration limits; - exact Lightpipe modules, board, line code, bitrate, clock recovery, and hardware-direction evidence; - exact MIDI byte mapping, circuit, frame size, and practical size classes; - concrete per-profile CPU, memory, disk, cycle, time, and energy limits; - Composer pairing-envelope decision if rerandomized local transport is later required; - conformance corpus, fault fixtures, benchmark results, and independent review. No implementation convenience may silently resolve these dependencies. ## 30. Primary References - FOG threat model: `FOG-THREAT-MODEL.md` - FOG architecture: `FOG-ARCHITECTURE.md` - FOG Composer: `FOG-COMPOSER.md` - RFC 6330, RaptorQ Forward Error Correction Scheme for Object Delivery: - IETF IPR disclosure 2554 related to RFC 6330: - RFC 5510, Reed-Solomon Forward Error Correction Schemes: - RFC 3309, SCTP Checksum Change, including CRC32C definition: - FIPS PUB 180-4, Secure Hash Standard: - ISO/IEC 18004:2024, QR code symbology specification: - DENSO WAVE QR Code error-correction overview: - MIDI 1.0 Electrical Specification Update: - Toshiba TOSLINK transmitter, receiver, transceiver, and directivity naming: