summaryrefslogtreecommitdiffstats
path: root/docs/FOG-WIRE.md
diff options
context:
space:
mode:
authorGab <24553253+gabrix73@users.noreply.github.com>2026-08-18 21:43:48 +0200
committerGab <24553253+gabrix73@users.noreply.github.com>2026-08-18 21:43:48 +0200
commit25356debcce4118cdfa86842029278fde1e64518 (patch)
treee2b681576fb7163ee83006a74b62013e63706c29 /docs/FOG-WIRE.md
parent6974e5459608feed48c611c76622226d2fc4fe26 (diff)
downloadfog-25356debcce4118cdfa86842029278fde1e64518.tar.gz
fog-25356debcce4118cdfa86842029278fde1e64518.tar.xz
fog-25356debcce4118cdfa86842029278fde1e64518.zip
Publish FOG design documentation and Merkle tree
Diffstat (limited to 'docs/FOG-WIRE.md')
-rw-r--r--docs/FOG-WIRE.md1246
1 files changed, 1246 insertions, 0 deletions
diff --git a/docs/FOG-WIRE.md b/docs/FOG-WIRE.md
new file mode 100644
index 0000000..1f0964a
--- /dev/null
+++ b/docs/FOG-WIRE.md
@@ -0,0 +1,1246 @@
+# FOG Wire Protocol
+
+Status: Draft 0.1
+
+Date: 2026-08-08
+
+## 1. Purpose
+
+This document defines `FOG-WIRE-1`, the authenticated transport protocol used
+between adjacent online FOG roles.
+
+It refines the following baselines:
+
+- `FOG-THREAT-MODEL.md`, especially `TM-NET-01`, `TM-NET-03`, `TM-NET-04`,
+ `TM-NET-05`, `TM-NET-06`, `TM-PKI-02`, `TM-ROLE-01`, `TM-ROLE-02`,
+ `TM-ROLE-03`, `TM-OPS-01`, `TM-CRYPTO-01`, `TM-CRYPTO-02`, and
+ `TM-AVAIL-01`;
+- `FOG-ARCHITECTURE.md`, especially `ARC-003`, `ARC-004`, `ARC-005`,
+ `ARC-006`, `ARC-007`, `ARC-008`, `ARC-009`, `IF-03`, `IF-04`, `IF-06`,
+ `IF-07`, `IF-08`, `IF-09`, `IF-10`, and `IF-11`;
+- `FOG-PKI.md`, especially consensus-authorized profiles, endpoints,
+ role-specific epoch public keys, monotonic profile state, and hard expiry.
+
+FOG is not implemented. Requirements in this document are protocol targets,
+not statements about deployed security.
+
+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-WIRE-1` owns:
+
+- the version-1 TCP carrier profile;
+- selection of one exact consensus-authorized Noise profile;
+- responder-only authentication for relay-to-entry links;
+- mutual authentication for node, authority, storage, and observer links;
+- binding of network, epoch, consensus, role, peer, key, and link context to
+ the Noise handshake;
+- handshake and transport framing;
+- fixed-size encrypted records and bounded logical-message fragmentation;
+- command allowlists by link context and direction;
+- per-record cipher-state rekey and bounded fresh handshakes;
+- epoch and profile transition behavior;
+- connection ownership, timeouts, backoff, overload, and failure behavior;
+- key lifecycle, privacy-safe diagnostics, and conformance requirements.
+
+`FOG-WIRE-1` does not own:
+
+- message-level end-to-end encryption;
+- KEMSphinx packet construction, routing, replay tags, or SURBs;
+- the entry submission capsule or return rendezvous;
+- storage capability semantics or replica durability;
+- application acknowledgments, retries, or deduplication;
+- mix delays, route selection, cover rates, or retrieval schedules;
+- consensus construction or profile authorization;
+- local administration, release updates, public mirror HTTP, or Composer
+ transfer formats.
+
+Noise protects one adjacent connection. It does not hide IP endpoints, TCP
+connection existence, timing, direction, duration, or byte volume. It does
+not replace KEMSphinx or end-to-end message encryption.
+
+## 3. Security Goals
+
+FOG-WIRE MUST provide, for one accepted connection:
+
+- authentication of every required online endpoint before application work;
+- anonymity at the Noise identity layer for a blind relay connecting to an
+ entry;
+- confidentiality and integrity of transport records after the handshake;
+- forward secrecy to the extent supplied by the selected reviewed Noise or
+ PQNoise profile and correct erasure of ephemeral state;
+- exact authorization of role adjacency and command direction;
+- authenticated agreement on the network, epoch, consensus, profile, roles,
+ node identifiers, and transport-key identifiers;
+- no silent suite, pattern, carrier, role, or version downgrade;
+- fixed ciphertext length for records within one profile;
+- bounded parsing, allocation, reassembly, cryptographic work, and queues;
+- coarse non-amplifying remote failures;
+- deterministic profile and epoch retirement.
+
+FOG-WIRE does not provide:
+
+- anonymity against an observer who can correlate connection timing or
+ volume;
+- protocol camouflage or censorship resistance;
+- authentication of a blind relay as a stable user or network identity;
+- application-message authenticity or recipient authentication;
+- KEMSphinx replay protection;
+- delivery, liveness, or availability against sustained denial of service;
+- safe operation after compromise of both endpoint processes;
+- post-quantum security merely because one profile contains a post-quantum
+ primitive.
+
+## 4. Protocol Invariants
+
+### WIRE-INV-01: One authenticated profile
+
+Every connection uses exactly one immutable wire profile authorized by the
+accepted consensus. Peers MUST NOT negotiate a list, guess a profile, or fall
+back after failure.
+
+### WIRE-INV-02: One link context
+
+Every connection has exactly one link context that fixes the initiator role,
+responder role, authentication mode, permitted direction, and command
+allowlist.
+
+### WIRE-INV-03: No early application data
+
+Every Noise handshake payload is empty in version 1. No FOG command is sent,
+accepted, buffered as trusted, or acted upon before the handshake completes
+and peer authorization succeeds. Session resumption, PSK resumption, and
+0-RTT application data are forbidden.
+
+### WIRE-INV-04: Consensus is the authority
+
+Operator configuration MAY restrict peers further, but MUST NOT add a peer,
+role, endpoint, key, context, or profile absent from the accepted consensus or
+trusted authority manifest.
+
+### WIRE-INV-05: Fixed encrypted records
+
+All post-handshake records on one connection have the exact ciphertext length
+defined by its profile. Application type and semantic body length MUST NOT
+change that record length.
+
+### WIRE-INV-06: Strict ordered state
+
+Version 1 runs over ordered TCP. Noise transport nonces and cipher-state
+rekeys advance exactly once per successfully sent or received record. A
+missing, duplicated, unauthentic, or out-of-order record terminates the
+connection.
+
+### WIRE-INV-07: Purpose-separated keys
+
+Noise static keys, node identity keys, authority vote keys, KEMSphinx keys,
+entry capsule keys, replica-envelope keys, message keys, queue-sealing keys,
+and release keys are distinct. One key MUST NOT serve two of these purposes.
+
+### WIRE-INV-08: Bounded work before trust
+
+Preface, handshake, frame, record, fragment, connection, and queue work is
+bounded before allocation proportional to attacker-controlled input. A peer
+cannot request an arbitrary algorithm, record size, or reassembly budget.
+
+### WIRE-INV-09: Failure does not widen access
+
+Failure never causes plaintext transport, direct client fallback, layer
+skipping, a new role edge, an older profile, a previous epoch, or a generic
+RPC path.
+
+### WIRE-INV-10: Traffic scheduling is external but mandatory
+
+FOG-WIRE supplies fixed records and a padding record. The authenticated cover
+profile decides when records are emitted. A local keepalive choice MUST NOT
+silently replace or modify that traffic schedule.
+
+## 5. Terminology and Byte Order
+
+Terms used in this specification:
+
+- **wire profile**: immutable mapping from one numeric profile identifier to
+ an exact carrier, Noise protocol name, record geometry, limits, timers,
+ socket behavior, and compatible command-shape registry;
+- **link context**: immutable role adjacency and directional command policy;
+- **preface**: the fixed 32-byte cleartext connection header;
+- **prologue**: the canonical byte string supplied to both Noise handshake
+ states and authenticated by the handshake transcript;
+- **record**: one fixed-size plaintext structure encrypted as one Noise
+ transport message;
+- **logical message**: one command body carried in one or more DATA records;
+- **current consensus**: the accepted consensus valid for new work at the
+ local uncertainty interval;
+- **staged consensus**: a valid future consensus that is not yet active for
+ new work.
+
+All integer fields defined directly by FOG-WIRE are unsigned and encoded in
+network byte order, most significant byte first. Byte arrays have the exact
+declared length. Reserved and padding bytes MUST be zero after decryption or
+when transmitted in cleartext.
+
+TCP is a byte stream. An implementation MUST NOT assume that one write equals
+one read, that one TCP segment equals one FOG frame, or that a partial read is
+an error.
+
+## 6. Version-1 Carrier
+
+The only version-1 carrier is TCP as specified by RFC 9293.
+
+The version-1 carrier profile:
+
+- uses one direct TCP connection between descriptor-authorized endpoints;
+- does not add TLS, DTLS, QUIC, HTTP, WebSocket, SOCKS, a service mesh, or a
+ proxy protocol header;
+- treats IPv4 and IPv6 endpoint forms only as permitted by the active profile;
+- binds the responder key through Noise rather than DNS or X.509;
+- does not trust TCP source address as a cryptographic identity;
+- uses no in-band carrier autodetection;
+- uses no TCP urgent data;
+- treats a half-close as connection termination after bounded output drain.
+
+A future carrier requires a new immutable wire profile and explicit profile
+transition. One port MUST NOT auto-detect TCP FOG-WIRE, TLS, QUIC, or any
+foreign protocol.
+
+FOG-WIRE has a visible fixed preface and does not claim to be
+indistinguishable from unrelated network traffic. Noise ephemeral public keys
+may also be fingerprintable. Deployment documentation MUST state this
+residual risk.
+
+## 7. Wire Profile Registry
+
+Every `wire_profile_id` is a non-zero unsigned 32-bit integer whose meaning is
+permanent. Reusing an identifier for changed bytes or behavior is forbidden.
+
+An exact wire profile definition contains at least:
+
+```text
+[
+ wire_profile_id,
+ wire_version,
+ carrier_id,
+ noise_protocol_name,
+ authentication_mode,
+ permitted_link_context_ids,
+ record_plaintext_size,
+ command_shape_registry_id,
+ maximum_session_records_per_direction,
+ maximum_session_ciphertext_bytes_per_direction,
+ maximum_session_age,
+ preface_timeout,
+ handshake_timeout,
+ fragment_timeout,
+ drain_timeout,
+ reconnect_backoff_profile_id,
+ socket_behavior_profile_id
+]
+```
+
+The registry definition is part of the normative protocol release and is
+identified by an immutable digest in release metadata. Consensus
+`active_profile_ids` authorizes identifiers, not operator-provided profile
+bodies. Implementations MUST reject an authorized identifier they do not
+implement exactly.
+
+The profile fixes one complete Noise protocol name. Pattern, KEM or DH,
+cipher, hash, hybrid combiner, key encoding, handshake message count, and
+handshake message sizes are not independently negotiated.
+
+The initial concrete classical or hybrid post-quantum Noise names and reviewed
+library remain a pre-PoC selection gate. FOG MUST use a published reviewed
+construction and maintained implementation. It MUST NOT create a FOG-specific
+KEM, cipher, combiner, Noise token, or handshake extension.
+
+## 8. Authentication Modes
+
+### 8.1 Entry mode
+
+`ENTRY-AUTH-1` has these semantics:
+
+- the initiator is a blind relay with no static Noise identity in the
+ handshake;
+- the responder is an entry whose exact epoch Noise public key is known from
+ accepted consensus;
+- the initiator authenticates the responder;
+- the responder learns no stable relay identity from Noise;
+- both sides use fresh handshake ephemeral state;
+- all handshake payloads are empty;
+- application work begins only after the complete handshake.
+
+A classical profile MAY realize these semantics with the Noise `NK` pattern
+while mandating an empty first handshake payload. A post-quantum or hybrid
+profile MUST name one reviewed equivalent construction explicitly. Support in
+the abstract Noise framework is not authorization to improvise a conversion.
+
+The entry authenticates each later submission capsule under
+`FOG-SPHINX-PROFILES`. A TCP address, client certificate, username, API token,
+or reusable relay key MUST NOT become a durable FOG user identity.
+
+### 8.2 Mutual node mode
+
+`NODE-MUTUAL-1` has these semantics:
+
+- initiator and responder have distinct role-local static Noise keys;
+- each endpoint knows the exact expected peer public key before connecting;
+- each endpoint proves possession of its corresponding private key;
+- both endpoints use fresh handshake ephemeral state;
+- all handshake payloads are empty;
+- application work begins only after complete mutual authentication.
+
+A classical profile MAY realize these semantics with Noise `KK`. A
+post-quantum or hybrid profile MUST name a reviewed mutually authenticated
+equivalent construction. The peer keys come from the same accepted consensus,
+except authority wire keys, which come from root-certified authority wire-key
+certificates referenced by that consensus.
+
+### 8.3 No optional authentication
+
+Version 1 has no anonymous-to-mutual upgrade, dummy identity, user password,
+bearer token, client certificate, or authentication extension inside the
+handshake. A link context determines one mode before parsing begins.
+
+## 9. Link Context Registry
+
+Version 1 reserves these link contexts:
+
+| ID | Name | Initiator | Responder | Mode | Connection use |
+| --- | --- | --- | --- | --- | --- |
+| 1 | `RELAY_ENTRY` | relay | entry | `ENTRY-AUTH-1` | submission and bounded return traffic |
+| 2 | `ENTRY_LAYER1` | entry | layer-1 mix | `NODE-MUTUAL-1` | forward and reply KEMSphinx packets |
+| 3 | `LAYER1_LAYER2` | layer-1 mix | layer-2 mix | `NODE-MUTUAL-1` | forward and reply KEMSphinx packets |
+| 4 | `LAYER2_LAYER3` | layer-2 mix | layer-3 mix | `NODE-MUTUAL-1` | forward and reply KEMSphinx packets |
+| 5 | `LAYER3_TERMINAL` | layer-3 mix | courier or authorized native service | `NODE-MUTUAL-1` | terminal request and anonymous reply |
+| 6 | `COURIER_STORE` | courier | store | `NODE-MUTUAL-1` | bounded replica operations |
+| 7 | `STORE_STORE` | lower `node_id` store | higher `node_id` store | `NODE-MUTUAL-1` | replica synchronization only |
+| 8 | `NODE_AUTHORITY` | admitted node | authority | `NODE-MUTUAL-1` | descriptor submission only |
+| 9 | `AUTHORITY_AUTHORITY` | lower `authority_id` | higher `authority_id` | `NODE-MUTUAL-1` | PKI protocol objects only |
+| 10 | `ROLE_OBSERVER` | reporting role | observer | `NODE-MUTUAL-1` | approved aggregate reports only |
+
+The numeric ordering rule gives contexts 7 and 9 one canonical connector and
+prevents persistent duplicate connections. Numeric comparison is over the
+complete identifier bytes.
+
+The reply direction MAY use an already authenticated adjacency connection in
+the reverse record direction. It does not authorize a new topology edge. The
+packet profile determines which peer is the next authorized reply hop.
+
+Adding a context or changing its role pair, direction, mode, or command set
+requires a new wire version or immutable profile transition. Operator
+configuration cannot create a custom context.
+
+## 10. Peer Authorization
+
+Before starting a mutual handshake, each side MUST derive an expected peer
+record from one accepted network view:
+
+```text
+ExpectedPeer = (
+ network_id,
+ epoch,
+ consensus_hash,
+ link_context_id,
+ local_role,
+ remote_role,
+ local_identifier,
+ remote_identifier,
+ local_wire_key_id,
+ remote_wire_key_id,
+ local_endpoint,
+ remote_endpoint
+)
+```
+
+For node links, both node descriptors MUST be valid for the selected epoch,
+their effective consensus roles and layers MUST match the link context, and
+their Noise keys MUST have the `node Noise transport` purpose.
+
+For authority links, the authority identifier and dedicated wire public key
+MUST validate through an `AuthorityWireKeyCertificate` signed by the matching
+offline authority root. An authority vote key MUST NOT be used as a Noise
+key.
+
+For `RELAY_ENTRY`, the relay identifier and key identifier are absent and are
+encoded as all-zero values in the prologue. The entry descriptor, role,
+endpoint, profile, and epoch key are still validated exactly.
+
+Authorization MUST be repeated before exposing a completed handshake to the
+role implementation. A peer removed, suspended, revoked, reassigned, expired,
+or no longer adjacent under consensus MUST NOT continue new work merely
+because an old TCP connection remains open.
+
+## 11. Cleartext Preface
+
+Every connection begins with exactly one 32-byte `WirePreface`:
+
+```text
+struct WirePreface {
+ byte magic[8]; // ASCII "FOGWIRE1"
+ uint16 wire_version; // 1
+ uint32 wire_profile_id;
+ uint16 link_context_id;
+ uint64 epoch;
+ uint16 flags; // 0
+ byte reserved[6]; // all zero
+}
+```
+
+The preface is transmitted by the initiator and is not encrypted. The
+responder MUST read all 32 bytes within the profile preface timeout and then:
+
+1. compare `magic` to the exact eight ASCII bytes `FOGWIRE1`;
+2. require `wire_version` equal to 1;
+3. require zero flags and reserved bytes;
+4. require a locally implemented profile authorized for the declared epoch;
+5. require the context to be permitted by that profile and listener;
+6. require the declared epoch to be current or explicitly staged under
+ Section 23;
+7. select exactly one handshake state without probing alternatives.
+
+The preface does not negotiate. The responder sends no selection, supported
+list, retry profile, or downgrade hint. Any failure closes the TCP connection
+without protocol bytes.
+
+## 12. Authenticated Noise Prologue
+
+Both peers construct the exact same byte string before initializing Noise:
+
+```text
+WirePrologue = EncodeFixed(
+ "FOG-WIRE-PROLOGUE-1",
+ WirePreface,
+ network_id,
+ consensus_hash,
+ initiator_role_id,
+ responder_role_id,
+ initiator_identifier,
+ responder_identifier,
+ initiator_wire_key_id,
+ responder_wire_key_id
+)
+```
+
+`EncodeFixed` is concatenation of the exact-width fields in the order shown.
+The domain string is 19 ASCII bytes without a terminator. `network_id`,
+`consensus_hash`, each identifier, and each key identifier use the hash output
+length pinned by the trusted PKI suite. Role identifiers are unsigned 16-bit
+integers. Absent relay identifier and key fields are all zero.
+
+No field is length-prefixed because every width is determined by the trusted
+PKI suite and wire version. Implementations MUST publish byte-exact prologue
+fixtures for every context.
+
+The complete `WirePrologue` is supplied as the Noise prologue input. It is
+authenticated by the resulting handshake transcript but is not secret and is
+not treated as extra key material.
+
+The implementation MUST retain the final Noise handshake hash as a
+connection-local channel-binding value until connection teardown. It MUST NOT
+log, publish, or reuse that value as a cross-session identifier.
+
+## 13. Handshake Framing and State Machine
+
+Each Noise handshake message is carried as:
+
+```text
+struct HandshakeFrame {
+ uint16 noise_message_length;
+ byte noise_message[noise_message_length];
+}
+```
+
+Rules:
+
+- `noise_message_length` MUST be non-zero and at most 65,535;
+- the profile MUST define the exact handshake message count and expected
+ length of every message;
+- a received length different from the profile expectation terminates the
+ connection before proportional allocation;
+- every Noise handshake payload is zero bytes;
+- trailing, extra, duplicated, or out-of-order handshake frames terminate the
+ connection;
+- the complete handshake MUST finish within the profile handshake timeout;
+- a Noise parse, decapsulation, DH, AEAD, key, or authentication failure
+ terminates the connection;
+- no application-specific error is sent during the handshake;
+- ephemeral private state and incomplete cipher state are erased on success,
+ failure, or timeout to the extent supported by the runtime.
+
+The initiator state machine is:
+
+```text
+TCP_CONNECTED
+ -> SEND_PREFACE
+ -> NOISE_HANDSHAKE
+ -> VERIFY_RESPONDER_OR_BOTH_PEERS
+ -> TRANSPORT
+ -> DRAIN_OR_FAIL
+ -> CLOSED
+```
+
+The responder state machine is:
+
+```text
+TCP_ACCEPTED
+ -> READ_AND_VALIDATE_PREFACE
+ -> NOISE_HANDSHAKE
+ -> VERIFY_INITIATOR_IF_REQUIRED
+ -> TRANSPORT
+ -> DRAIN_OR_FAIL
+ -> CLOSED
+```
+
+There is no resumption state and no transition from a failed state back to
+handshake on the same TCP connection.
+
+## 14. Transport Framing
+
+After a successful handshake, each record is carried as:
+
+```text
+struct TransportFrame {
+ uint16 ciphertext_length;
+ byte ciphertext[ciphertext_length];
+}
+```
+
+For one connection, `ciphertext_length` is constant and equals:
+
+```text
+record_plaintext_size + 16
+```
+
+The 16 bytes are the Noise AEAD authentication overhead. The concrete profile
+MUST use a Noise cipher function with this standard overhead.
+
+`record_plaintext_size` MUST be a multiple of 256 between 4,096 and 65,280
+bytes inclusive. Consequently every ciphertext fits the standard Noise
+65,535-byte message limit. FOG-WIRE does not adopt a larger non-standard Noise
+message limit.
+
+A receiver MUST validate the two-byte length against the one expected
+constant before allocating or reading the ciphertext. Zero, short, overlong,
+or profile-mismatched lengths terminate the connection.
+
+TCP split and coalescing are transparent to this framing. One implementation
+MUST interoperate when every framing byte arrives in a separate TCP read and
+when multiple frames arrive in one read.
+
+## 15. Record Plaintext
+
+Every decrypted record has this exact layout:
+
+```text
+struct WireRecord {
+ uint8 record_version; // 1
+ uint8 record_type;
+ uint16 flags; // 0
+ byte message_id[16];
+ uint16 command_id;
+ uint16 command_version;
+ uint32 fragment_index;
+ uint32 fragment_count;
+ uint32 total_length;
+ uint16 fragment_length;
+ uint16 reserved; // 0
+ byte fragment_and_padding[record_plaintext_size - 40];
+}
+```
+
+The 40-byte header is fixed. Version 1 defines:
+
+| `record_type` | Name | Meaning |
+| --- | --- | --- |
+| 0 | `PADDING` | traffic-schedule record, discarded after validation |
+| 1 | `DATA` | one fragment of one allowed logical command |
+| 2 | `CLOSE` | authenticated planned close or fresh-handshake rotation |
+
+Unknown versions, types, flags, commands, command versions, or non-zero
+reserved values are critical errors and terminate the connection.
+
+### 15.1 Padding record
+
+For `PADDING`, every field after `flags`, including all payload bytes, MUST be
+zero. The receiver validates and discards it. It MUST pass through the same
+Noise decrypt, length check, record rekey, accounting, and aggregate metrics
+path as DATA records before semantic discard.
+
+### 15.2 Close record
+
+For `CLOSE`, `command_id` is a coarse close class:
+
+- 0: planned normal close;
+- 1: authenticated fresh-handshake or epoch rotation.
+
+Every other header field after `flags`, except `command_id`, and all payload
+bytes MUST be zero.
+Failure, authentication, parsing, overload, or authorization errors do not
+send a CLOSE reason. They close the socket without protocol bytes.
+
+### 15.3 Data record
+
+For `DATA`:
+
+- `message_id` MUST be a fresh non-zero 16-byte value generated from the
+ operating-system CSPRNG and unique within the connection;
+- `command_id` and `command_version` MUST be allowed for the context,
+ direction, role pair, epoch, and command-shape registry;
+- `fragment_count` MUST be from 1 through 4,096;
+- `fragment_index` MUST be less than `fragment_count`;
+- `total_length` MUST be no greater than 8 MiB and within the lower
+ context-specific limit;
+- `fragment_length` MUST be no greater than
+ `record_plaintext_size - 40`;
+- every non-final fragment MUST fill the complete fragment capacity;
+- the final fragment length MUST equal the remaining declared body length;
+- `fragment_count` MUST equal the unique count implied by total length and
+ fragment capacity;
+- unused `fragment_and_padding` bytes MUST be zero.
+
+Zero-length command bodies use exactly one DATA record with zero fragment
+length and are valid only when the command registry explicitly permits them.
+
+`message_id` is a connection-local reassembly handle, not a capability,
+account, authentication token, delivery identifier, storage key, or
+cross-session replay defense. A narrower command protocol owns idempotency and
+deduplication across reconnects.
+
+## 16. Logical-Message Reassembly
+
+A receiver MAY interleave fragments from multiple logical messages only
+within all profile bounds. It MUST:
+
+1. authenticate and validate each complete record before reading its fields;
+2. reject duplicate fragment indices and inconsistent repeated metadata;
+3. avoid allocation based only on `fragment_count` or `total_length`;
+4. allocate or spool incrementally within a fixed connection budget;
+5. accept at most eight incomplete logical messages per connection;
+6. accept at most 16 MiB of incomplete reassembly state per connection;
+7. expire incomplete messages at the profile fragment timeout;
+8. erase partial bodies on timeout, connection loss, parse failure, or role
+ rejection;
+9. invoke command handling only after exact complete reassembly and final
+ shape validation.
+
+A context profile MAY lower the 8 MiB message limit, eight-message count, or
+16 MiB buffer budget. It MUST NOT raise them in wire version 1.
+
+Implementations SHOULD stream authenticated fragments into bounded
+role-local temporary storage when a command legitimately exceeds the in-memory
+budget. Temporary files MUST be private to the role account, unlinked or
+randomly named without peer identifiers, size-bounded, and deleted on every
+terminal path.
+
+## 17. Command Registry and Direction
+
+Version 1 reserves these command families:
+
+| ID | Command | Body owner |
+| --- | --- | --- |
+| 1 | `PACKET_SUBMIT` | future `FOG-ENTRY-CAPSULE` specification |
+| 2 | `PACKET_FORWARD` | `FOG-SPHINX-PROFILES` fixed KEMSphinx packet |
+| 3 | `PACKET_RETURN` | `FOG-SPHINX-PROFILES` bounded relay return object |
+| 256 | `REPLICA_REQUEST` | `FOG-STORAGE` |
+| 257 | `REPLICA_RESPONSE` | `FOG-STORAGE` |
+| 258 | `REPLICA_SYNC` | `FOG-STORAGE` |
+| 512 | `DESCRIPTOR_UPLOAD` | `FOG-PKI` |
+| 513 | `DESCRIPTOR_RESULT` | `FOG-PKI` |
+| 514 | `AUTHORITY_OBJECT` | `FOG-PKI` |
+| 768 | `AGGREGATE_REPORT` | `FOG-OBSERVABILITY` |
+
+The directional allowlist is:
+
+| Context | Initiator to responder | Responder to initiator |
+| --- | --- | --- |
+| `RELAY_ENTRY` | `PACKET_SUBMIT` | `PACKET_RETURN` |
+| `ENTRY_LAYER1` | `PACKET_FORWARD` | `PACKET_FORWARD` |
+| `LAYER1_LAYER2` | `PACKET_FORWARD` | `PACKET_FORWARD` |
+| `LAYER2_LAYER3` | `PACKET_FORWARD` | `PACKET_FORWARD` |
+| `LAYER3_TERMINAL` | `PACKET_FORWARD` | `PACKET_FORWARD` |
+| `COURIER_STORE` | `REPLICA_REQUEST` | `REPLICA_RESPONSE` |
+| `STORE_STORE` | `REPLICA_SYNC` | `REPLICA_SYNC` |
+| `NODE_AUTHORITY` | `DESCRIPTOR_UPLOAD` | `DESCRIPTOR_RESULT` |
+| `AUTHORITY_AUTHORITY` | `AUTHORITY_OBJECT` | `AUTHORITY_OBJECT` |
+| `ROLE_OBSERVER` | `AGGREGATE_REPORT` | none |
+
+`PACKET_FORWARD` in the reverse record direction is permitted only when the
+packet profile validates the receiving peer as the next hop of an anonymous
+reply. It does not allow arbitrary reverse RPC.
+
+Every narrower specification MUST define exact body bytes, version, maximum
+size, expected padded size class, request-to-response relation, idempotency,
+semantic timeout, and behavior after reconnect. Unknown commands never reach
+role code.
+
+There is no vendor, experimental, operator-private, or generic-RPC command
+range in version 1.
+
+## 18. Command Shapes and Length Privacy
+
+The active `command_shape_registry_id` maps each allowed command to:
+
+- one exact logical body length; or
+- a small ordered set of public padded length classes;
+- an exact record count for each class;
+- a context-specific maximum in-flight count;
+- whether zero-length bodies are valid.
+
+The sender pads the semantic object inside the owning protocol before passing
+it to FOG-WIRE. FOG-WIRE zero-fills only unused space in the last fixed
+record. It does not invent application padding classes.
+
+All native KEMSphinx applications use the same `PACKET_SUBMIT`,
+`PACKET_FORWARD`, and `PACKET_RETURN` shapes for an active packet profile.
+`fog-drop`, `fog-mailbox`, and `fog-im` MUST NOT select distinguishable wire
+sizes.
+
+`FOG-SPHINX-PROFILES.md` defines the exact packet and return bodies. For the
+non-active `FOG-SPHINX-CANDIDATE-MLKEM768-X25519-1`, `PACKET_FORWARD` is
+16,150 bytes and `PACKET_RETURN` is 10,204 bytes. These calculated candidate
+lengths do not authorize the suite. A wire profile paired with it must map each
+body to one deterministic fixed record count and reject any other logical
+length.
+
+The number and timing of records remain observable. A command shape is a
+declared traffic class, not perfect length hiding. The simulator and owning
+protocol MUST evaluate whether a class creates an unacceptable fingerprint.
+
+## 19. Cipher-State Rekey
+
+After encrypting and queueing each complete transport record, the sender MUST
+call Noise `CipherState.Rekey()` on the outbound cipher state exactly once.
+After successfully authenticating, decrypting, and validating the fixed
+ciphertext length of each complete record, the receiver MUST call
+`CipherState.Rekey()` on the inbound cipher state exactly once before
+processing the record semantically.
+
+If authentication fails, the receiver does not advance or retry. It destroys
+both transport cipher states and closes the connection.
+
+Noise rekey changes the current cipher key through a one-way function and does
+not reset the Noise nonce. It does not add a fresh DH or KEM secret. Therefore
+it MUST NOT be described as a replacement for a fresh authenticated
+handshake.
+
+The separate inbound and outbound cipher states are never combined and
+half-duplex Noise mode is forbidden.
+
+## 20. Fresh Handshake and Session Limits
+
+A connection MUST be replaced with a completely new TCP and Noise handshake
+at the earliest of:
+
+- the profile maximum records sent in either direction;
+- the profile maximum ciphertext bytes sent in either direction;
+- the profile maximum session age;
+- activation of a new required epoch key or wire profile;
+- peer role, topology adjacency, endpoint, key, revocation, or authorization
+ change;
+- any uncertainty about cipher-state synchronization;
+- local secret-state restoration or process restart.
+
+Version-1 absolute ceilings are:
+
+| Item | Absolute ceiling |
+| --- | --- |
+| records per direction per session | 2^32 |
+| ciphertext bytes per direction per session | 1 TiB |
+| session age | 24 hours |
+
+Every concrete profile MUST select lower exact values based on cipher bounds,
+cover rate, connection churn, epoch schedule, and measurements.
+
+The connector MAY establish one authenticated replacement in parallel. It
+MUST NOT send new logical messages on the replacement until the handshake and
+authorization complete. The old connection drains only already admitted
+messages for the profile drain timeout, then closes.
+
+Logical-message retry across the replacement belongs to the command owner. A
+transport reconnect MUST NOT silently report application success, replay an
+unknown partial command, or create a second delivery without that command's
+idempotency rule.
+
+## 21. Connection Ownership and Multiplicity
+
+There is at most one active data connection for one tuple:
+
+```text
+(
+ network_id,
+ epoch,
+ wire_profile_id,
+ link_context_id,
+ initiator_identifier,
+ responder_identifier
+)
+```
+
+`RELAY_ENTRY` uses one relay-local connection instance in place of an
+initiator identifier. A relay MAY maintain the small temporary entry set
+permitted by its authenticated cover profile, but the count MUST NOT vary
+immediately with one user message.
+
+One additional authenticated connection MAY exist only as a staged
+replacement. Any other duplicate is closed after authentication without
+moving work to it.
+
+The canonical initiator in Section 9 owns reconnect attempts. A responder
+does not open a reverse substitute connection. Nodes SHOULD maintain required
+adjacency connections independently of application queue occupancy when the
+cover profile requires it.
+
+## 22. Traffic Scheduling, Padding, and Liveness
+
+The active cover profile specifies connection maintenance and a record-emission
+schedule for each privacy-relevant context. It may choose a measured constant,
+Poisson, or other reviewed schedule, but all operators in that profile use the
+same authenticated parameters.
+
+At each scheduled emission opportunity:
+
+- the role sends one queued DATA record allowed by the scheduling policy; or
+- it sends one PADDING record when no eligible DATA record is selected.
+
+DATA arrival MUST NOT cause an undeclared immediate write that bypasses the
+schedule. PADDING MUST NOT be disabled locally while a profile claims traffic
+normalization.
+
+FOG-WIRE defines no `PING` or `PONG`. TCP itself has no sufficient application
+liveness guarantee. Health is inferred from authenticated traffic, socket
+failure, connection age, and separate coarse loop protocols. If a deployment
+enables operating-system TCP keepalive only for dead-resource cleanup, its
+exact settings MUST be profile-bound and it MUST NOT be counted as cover
+traffic or anonymity evidence.
+
+Failure of required cover generation moves the role into the degraded or stop
+state defined by the cover profile. It does not switch to activity-triggered
+records.
+
+The first matrix in `FOG-SIMULATION.md` does not select this schedule. It shows
+that high packet cover can improve simple timing and intersection proxies
+without supplying adequate local mixing at short mean delay. Exact record
+schedules still require queue, liveness, loop, polling, reply, and load models.
+
+## 23. Epoch and Profile Transitions
+
+The preface declares one epoch. The Noise prologue binds the exact consensus
+hash for that epoch. Peers MUST NOT combine a descriptor, key, topology edge,
+profile, or parameter from a different consensus body.
+
+During an authenticated transition:
+
+- a listener MAY accept the current epoch and one preannounced next epoch;
+- a next-epoch connection MAY complete and remain staged before `valid_after`;
+- no next-epoch application work is sent or accepted before `valid_after`;
+- an old profile remains usable only through its signed overlap interval;
+- minimum accepted profile state prevents rollback after promotion;
+- a previous epoch connection stops accepting new work at its exact boundary;
+- bounded draining MUST end before key or consensus hard expiry;
+- expired private keys are erased after the owning protocol's last required
+ grace window;
+- same-epoch consensus conflict freezes new connections and new work.
+
+A listener chooses the exact state directly from the preface and local
+accepted PKI state. It does not try current and old parsers in sequence.
+
+At consensus `valid_until`, new handshakes and new logical messages under that
+consensus stop. Existing connections MAY only perform an explicitly specified
+bounded drain that does not outlive key authorization.
+
+## 24. Timeouts and Reconnect Backoff
+
+Every concrete wire profile defines exact values for:
+
+- TCP connect timeout;
+- 32-byte preface timeout;
+- complete Noise handshake timeout;
+- fixed frame read and write timeout;
+- incomplete logical-message fragment timeout;
+- output drain timeout;
+- maximum session age;
+- reconnect initial delay, multiplier, ceiling, and jitter distribution.
+
+Version-1 absolute maxima are:
+
+| Timer | Maximum |
+| --- | --- |
+| preface | 30 seconds |
+| complete handshake | 60 seconds |
+| incomplete frame | 60 seconds |
+| incomplete logical message | 5 minutes |
+| drain | 30 seconds |
+| reconnect ceiling | 15 minutes |
+
+Timeouts are monotonic-duration measurements, not peer-provided wall-clock
+values. A timeout closes the connection without detailed remote error.
+
+Reconnect uses bounded exponential backoff with CSPRNG-derived full jitter.
+The attempt schedule MUST NOT use node identifiers, message identifiers,
+queue length, or application type as its random seed. Immediate deterministic
+fallback to another route, layer, or older profile is forbidden.
+
+## 25. Backpressure and Resource Limits
+
+Before the local PoC, every role profile MUST set lower operational limits
+within these version-1 absolute bounds:
+
+| Resource | Absolute bound |
+| --- | --- |
+| accepted unauthenticated connections per listener | 1,024 |
+| concurrent handshakes per listener | 256 |
+| active connections per authenticated peer/context | 1 plus 1 staged |
+| encrypted record plaintext | 65,280 bytes |
+| logical message | 8 MiB |
+| fragments per logical message | 4,096 |
+| incomplete messages per connection | 8 |
+| incomplete reassembly bytes per connection | 16 MiB |
+| queued complete logical messages per connection | 1,024 |
+| command versions accepted per command | 2 during signed transition |
+
+Implementations MUST also bound total process connections, file descriptors,
+handshake CPU, KEM decapsulations, per-source unauthenticated attempts, queue
+bytes, write backlog, temporary files, and aggregate reassembly memory.
+
+When a queue is full, the role follows the owning command's shedding policy.
+It MUST NOT allocate without bound, skip authentication, enlarge a packet,
+send an error larger than the triggering record, or route around a required
+layer.
+
+Entry-mode abuse control MAY use coarse short-lived network-source limits and
+valid entry capsules, but MUST NOT create a stable cross-entry user account.
+Safe anonymous admission and rate control remain an explicit open security
+decision.
+
+## 26. Socket Behavior
+
+The immutable socket behavior profile fixes at least:
+
+- TCP no-delay behavior;
+- keepalive enablement and exact cleanup timers if used;
+- send and receive buffer ceilings;
+- user-space write batching;
+- address-family policy;
+- dual-stack binding behavior;
+- connection and accept backlog limits;
+- maximum pending output bytes;
+- graceful close and reset behavior.
+
+Operators MUST NOT tune these settings independently when they affect record
+timing, batching, connection duration, or public traffic claims. The initial
+values require trace measurement on supported operating systems because TCP
+segmentation does not preserve FOG record boundaries.
+
+Proxy-protocol headers, transparent proxy source metadata, TLS termination,
+and service-mesh sidecars are forbidden on core FOG-WIRE listeners. A
+deployment requiring a network proxy is a separate analyzed profile and trust
+boundary.
+
+## 27. Failure Behavior
+
+| Condition | Remote behavior | Local behavior |
+| --- | --- | --- |
+| invalid or unsupported preface | close without bytes | coarse counter |
+| unauthorized epoch, profile, context, role, or endpoint | close without bytes | coarse authorization class |
+| handshake length or timeout failure | close without bytes | coarse handshake class |
+| Noise authentication or decapsulation failure | close without bytes | one aggregate crypto-failure class |
+| transport length mismatch | close without bytes | coarse frame class |
+| Noise record authentication failure | close without bytes | destroy both cipher states |
+| unknown or malformed record | close without bytes | coarse record class |
+| forbidden command or direction | close without bytes | coarse policy class |
+| reassembly bound or timeout | close without bytes | erase partial state |
+| queue saturation after authentication | owning protocol's uniform bounded outcome or close | aggregate overload class |
+| planned rotation | one fixed CLOSE record if schedule permits | bounded drain and fresh handshake |
+| TCP loss or half-close | no protocol error | erase partial state and back off |
+
+Peers never receive parser offsets, expected keys, supported profiles,
+consensus hashes, role policy, capacity, queue depth, or cryptographic error
+details.
+
+The implementation is not required to make all local computation paths
+constant-time with respect to public invalid framing. Cryptographic libraries
+MUST provide their required side-channel protections, and remotely observable
+failure behavior MUST remain non-amplifying and free of detailed oracles.
+
+## 28. Logging and Metrics
+
+FOG-WIRE MUST NOT log or export:
+
+- plaintext or ciphertext record bodies;
+- entry capsules or KEMSphinx packets;
+- `message_id`, Noise handshake hash, traffic key, ephemeral key, or private
+ key material;
+- per-record timestamps or direction traces;
+- queue contents, logical-message hashes, capabilities, or reply material;
+- source IP addresses for anonymous relay-to-entry sessions in persistent
+ application logs;
+- detailed handshake failure stages associated with one remote endpoint.
+
+Role-local debugging MAY use coarse enumerated failure classes in a protected
+short-retention log, without input bytes or secret values. Claim-bearing
+profiles disable packet and record tracing.
+
+Metrics are delayed aggregates over declared windows and minimum populations.
+Allowed examples include total completed handshakes by context, aggregate
+failure class, coarse connection age bucket, aggregate queue occupancy bucket,
+and total padding-to-data ratio. The observer interface receives aggregates,
+not event streams.
+
+## 29. Key and Secret Lifecycle
+
+| Key or secret | Generator | Authorized use | Lifetime and overlap | Compromise response | Backup |
+| --- | --- | --- | --- | --- | --- |
+| Node Noise epoch private key | owning node OS CSPRNG | one node role and authorized adjacent links | profile-bounded current key, staged next key, exact grace only | revoke key or node, stop new handshakes, rotate | no routine backup |
+| Entry Noise epoch private key | entry OS CSPRNG | authenticate `RELAY_ENTRY` and authorized node links | profile-bounded current and staged next | revoke entry key, stop sessions, rotate | no routine backup |
+| Authority wire private key | authority wire service OS CSPRNG or controlled ceremony | authority mutual links only | root-certified bounded interval, staged next key | root-signed revocation and replacement | SHOULD NOT restore into a concurrent service |
+| Handshake ephemeral private state | connection endpoint OS CSPRNG | one Noise handshake | until handshake completion or failure | close connection, erase state | none |
+| Noise transport cipher states | Noise handshake `Split()` | one direction of one connection | until close or fresh handshake | destroy connection state and reauthenticate | none |
+| Reassembly message identifier | sending role OS CSPRNG | one logical message within one connection | until completion or timeout | discard partial message | none |
+| Queue-sealing key | owning role local secret facility | local queued ciphertext at rest | deployment-rotated, independent of Noise | quarantine queue, rotate, discard unverifiable state | profile-specific encrypted backup |
+
+Static private keys MUST be readable only by the one role service that owns
+them. They MUST NOT appear in environment templates, command arguments,
+container images, shared volumes, logs, crash dumps, examples, test fixtures,
+or support bundles.
+
+Best-effort zeroization is required for ephemeral, cipher-state, and partial
+plaintext buffers. Documentation MUST NOT claim complete erasure where the
+language runtime, allocator, kernel, swap, hibernation, or hardware cannot
+guarantee it.
+
+## 30. Implementation Requirements
+
+An implementation MUST:
+
+- use a maintained reviewed Noise or PQNoise library;
+- use the operating-system CSPRNG for static keys, ephemeral state, message
+ identifiers, and jitter;
+- keep protocol framing separate from role command parsing;
+- enforce all limits before proportional allocation;
+- use checked integer arithmetic for lengths, counts, and record totals;
+- reject trailing bytes and unknown-critical values;
+- authenticate complete records before semantic parsing;
+- prevent one role package from importing another role implementation;
+- expose one typed context-specific command interface, not raw generic RPC;
+- disable core dumps and secret-bearing panic or exception output;
+- hold static private keys in the minimum role-local protected facility;
+- destroy connection state on every authentication or synchronization error;
+- keep the Composer implementation free of FOG-WIRE listeners and sockets.
+
+The protocol implementation MUST NOT:
+
+- implement cryptographic primitives or hybrid combiners locally;
+- let configuration specify an arbitrary Noise protocol string;
+- use a shared transport key for multiple nodes or roles;
+- retry decryption with old keys or profiles;
+- accept a DNS result, TCP source, or TLS certificate instead of PKI key
+ validation;
+- expose a generic byte tunnel to applications;
+- compress records or logical messages at the wire layer;
+- silently fragment an over-limit command;
+- persist session cipher state for resumption.
+
+### 30.1 Required module boundaries
+
+The future implementation keeps these responsibilities independently
+testable:
+
+```text
+role executable and role package
+ -> TCP listener or connector adapter
+ -> FOG-WIRE session state machine
+ -> profile and link-context authorization
+ -> pure preface, prologue, frame, record, and fragment codecs
+ -> reviewed Noise or PQNoise library
+```
+
+The pure codecs MUST be testable without opening a socket or starting a role.
+The session state machine owns no role database and invokes only a typed
+context-specific command boundary after complete validation. The TCP adapter
+owns socket IO but does not parse role command bodies. Role handlers own
+semantic commands but never access Noise cipher state or unvalidated record
+bytes.
+
+Profile registry, framing, session, and command-shape code MUST NOT be placed
+in a generic `utils` package. Role packages MUST NOT call each other to bypass
+the wire contract or share one transport singleton. Separate executables are
+justified by the established security and state-isolation boundaries, not by
+independent feature scaling.
+
+## 31. Conformance and Adversarial Tests
+
+Before the local PoC, FOG-WIRE MUST have tests for:
+
+- byte-exact preface encoding and every rejected field variation;
+- byte-exact prologue construction for every context and PKI hash length;
+- entry responder authentication with no relay static identity;
+- mutual node and authority authentication;
+- wrong network, consensus, epoch, context, role, node, endpoint, key, and
+ profile binding;
+- empty handshake payload enforcement and attempted early application data;
+- handshake messages at expected, short, long, zero, and 65,535-byte bounds;
+- TCP reads split at every byte boundary and coalesced across multiple frames;
+- fixed ciphertext length and standard Noise maximum enforcement;
+- every record type and zero-reserved or zero-padding rule;
+- unknown record, command, command version, close class, and direction;
+- valid single- and multi-fragment reassembly;
+- duplicate, missing, reordered, inconsistent, expired, excessive, and sparse
+ fragments;
+- exact 8 MiB, 4,096-fragment, 8-message, and 16 MiB boundaries;
+- per-record outbound and inbound rekey synchronization;
+- authentication failure before and after a rekey boundary;
+- fresh-handshake record, byte, age, epoch, topology, and profile boundaries;
+- current and next epoch staging with no early forwarding;
+- old-profile retirement and rollback refusal;
+- duplicate connection collision and one staged replacement;
+- queue saturation, slow reads, slow writes, half-close, reset, and timeout;
+- reconnect backoff and jitter bounds under repeated failure;
+- listener floods and expensive-handshake concurrency limits;
+- log and metrics schema rejection of prohibited fields;
+- parser mutation, coverage-guided fuzzing, differential framing tests, race
+ tests, and allocation tests;
+- firewall validation for every link context and forbidden role edge.
+
+Tests generate ephemeral private fixtures at runtime. Private keys MUST NOT be
+committed as example or conformance data. Public canonical framing fixtures
+MAY be committed when they contain no secret material.
+
+Independent implementations MUST consume the same public framing and
+transcript-binding corpus before interoperability is claimed.
+
+## 32. Claim Gates
+
+### 32.1 Functional PoC
+
+The local PoC MUST demonstrate:
+
+- one fixed reviewed Noise profile;
+- responder-only relay-to-entry and mutual node authentication;
+- complete traversal of entry and three mix layers;
+- fixed records, padding records, fragmentation, and strict command policy;
+- per-record rekey and bounded fresh handshakes;
+- current and next epoch transition;
+- malformed, unauthorized, flooded, and disconnected peers;
+- no multi-role key, state, account, or writable-volume sharing.
+
+This demonstrates functional correctness only. It does not demonstrate a
+production anonymity set or global-observer resistance.
+
+`FOG-LOCAL-POC.md` fixes the container and network boundary for this gate. It
+uses one internal pairwise network per permitted data-plane adjacency, no host
+ports, and no shared role state. Its current validated plan is not a FOG-WIRE
+implementation and deliberately contains no invented wire profile or port.
+
+### 32.2 Operator alpha
+
+Alpha additionally requires:
+
+- fixed reviewed hybrid post-quantum or explicitly documented classical
+ profile selection;
+- interoperability between independently built endpoints;
+- fuzz, race, load, fault, and side-channel review results;
+- measured TCP record segmentation and timing on supported systems;
+- measured handshake cost and anonymous-entry flood behavior;
+- six independently operated mixes and profile-conformant cover scheduling;
+- rehearsed key compromise, revocation, epoch transition, and rollback tests;
+- public residual-risk documentation for visible endpoints and traffic.
+
+### 32.3 Production transport claims
+
+Production claims additionally require:
+
+- independent protocol and implementation review;
+- reviewed library and dependency provenance;
+- published concrete suite, geometry, limits, and conformance results;
+- verified erasure and crash behavior within stated platform limits;
+- sustained adversarial load and resource-exhaustion testing;
+- evidence that profile rollout does not create persistent minority
+ fingerprints;
+- claim wording that distinguishes link confidentiality, forward secrecy,
+ post-quantum assumptions, and metadata privacy.
+
+## 33. Requirements Traceability
+
+| Requirement | FOG-WIRE control |
+| --- | --- |
+| `TM-NET-01` | fixed records, command shapes, profile-bound scheduling, padding records |
+| `TM-NET-03` | bounded retries, no bypass, cover-profile failure gate |
+| `TM-NET-04` | ordered Noise nonces, no resumption, command-owned cross-session deduplication |
+| `TM-NET-05` | authenticated records, strict failure, no action before validation |
+| `TM-NET-06` | immutable profiles, exact context, no negotiation or autodetection |
+| `TM-PKI-02` | epoch and consensus binding, monotonic profile transition, hard expiry |
+| `TM-ROLE-01` | anonymous relay mode, authenticated entry, no durable relay account |
+| `TM-ROLE-02` | exact layer adjacency, mutual node authentication, no layer skip |
+| `TM-ROLE-03` | courier/store contexts, command separation, fixed replica shapes |
+| `TM-OPS-01` | prohibited log fields, delayed aggregate metrics |
+| `TM-CRYPTO-01` | purpose-separated keys, lifecycle table, fresh handshakes |
+| `TM-CRYPTO-02` | consensus-authorized exact Noise name, no fallback, bounded overlap |
+| `TM-AVAIL-01` | strict frame, fragment, handshake, connection, queue, and CPU bounds |
+| `ARC-003` | no data-plane bypass or new failure edge |
+| `ARC-004` | Noise limited to adjacent transport protection |
+| `ARC-005` | peers and profiles derived from one complete accepted consensus |
+| `ARC-006` | fixed records and application-independent packet commands |
+| `ARC-007` | one private-key owner and one purpose |
+| `ARC-008` | exact versioned framing and absolute parser limits |
+| `ARC-009` | coarse non-amplifying remote failure |
+| `IF-03` | authenticated bounded descriptor command |
+| `IF-04` | authenticated authority object command |
+| `IF-06` | anonymous relay initiator, authenticated entry, fixed submission command |
+| `IF-07` | mutually authenticated exact layer adjacency |
+| `IF-08` | fixed authenticated layer-3 to terminal transport |
+| `IF-09` | dedicated courier/store and store/store contexts |
+| `IF-10` | reverse-direction packet only over authorized adjacency |
+| `IF-11` | aggregate-only observer command |
+
+## 34. Open Pre-Implementation Selections
+
+The version-1 protocol structure is fixed, but these selections block daemon
+implementation:
+
+- the exact reviewed classical or hybrid post-quantum Noise protocol names;
+- the reviewed Noise or PQNoise library and supported implementation language;
+- X-Wing is the leading KEM to evaluate, but no exact FOG entry or mutual
+ post-quantum handshake profile is selected;
+- exact `wire_profile_id` assignments and immutable registry digests;
+- record plaintext size and command-shape pairings;
+- fresh-handshake record, byte, and age thresholds;
+- concrete timeouts, reconnect distribution, and socket behavior profile;
+- lower role-specific connection, queue, CPU, and memory limits;
+- packet, PKI, and observer command body specifications, plus byte-exact
+ `FOG-STORAGE` command-to-record mappings;
+- cover-record schedules and degraded-mode thresholds from simulation;
+- safe anonymous entry admission and flood-control policy;
+- authority wire-key certificate rollout and revocation ceremony.
+
+Implementations MUST NOT resolve these selections through undocumented local
+defaults. Each selected value becomes an immutable reviewed profile with test
+vectors and a signed transition path.
+
+## 35. References
+
+- FOG threat model: `FOG-THREAT-MODEL.md`
+- FOG architecture: `FOG-ARCHITECTURE.md`
+- FOG public key infrastructure: `FOG-PKI.md`
+- FOG storage protocol: `FOG-STORAGE.md`
+- FOG cryptographic suite evaluation: `FOG-CRYPTO-SUITES.md`
+- FOG traffic and topology simulation: `FOG-SIMULATION.md`
+- FOG local Podman PoC: `FOG-LOCAL-POC.md`
+- Noise Protocol Framework:
+ <https://noiseprotocol.org/noise.html>
+- Katzenpost mix network wire protocol:
+ <https://katzenpost.network/docs/specs/wireprotocol/>
+- Post Quantum Noise:
+ <https://eprint.iacr.org/2022/539>
+- CFRG X-Wing KEM Internet-Draft:
+ <https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/>
+- RFC 9293, Transmission Control Protocol:
+ <https://www.rfc-editor.org/rfc/rfc9293.html>
+- RFC 8174, Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words:
+ <https://www.rfc-editor.org/rfc/rfc8174.html>
+
+These references inform Noise handshake semantics, standard message bounds,
+rekey behavior, TCP stream framing, post-quantum construction review, and
+adjacent mix-link experience. They do not make a concrete FOG profile secure
+without exact selection, conformance testing, operational measurement, and
+independent review.