Tier 1 audit: `link-lxmf-tier1-rns-1.2.4-lxmf-0.9.7.md` Tier 2 vectors/verifier: link-lxmf.json, regen_link_lxmf.py, and verify_link_lxmf.py Tier 3 promotion: updated SPEC.md, flows, status, and documentation Key correction: the 319/320 boundary uses upstream’s computed LXMF content_size, not simply raw message content length. Also corrected stale flow descriptions for KEEPALIVE (0xFA) and encrypted LINKCLOSE teardown (0xFC). Verification: Deterministic vector regeneration: identical SHA-256 Portable-path and formatting checks: pass Full pinned suite: 17 passed, 0 failed
3.1 KiB
Tier 1 Audit: Link-Delivered LXMF
Question: How does upstream LXMF 0.9.7 select, emit, receive, and acknowledge DIRECT LXMF over an established RNS 1.2.4 Link?
Evidence baseline:
- RNS package:
rns==1.2.4 - LXMF package:
lxmf==0.9.7 - Sources:
LXMF/LXMessage.py,LXMF/LXMRouter.py,RNS/Packet.py,RNS/Link.py, andRNS/Resource.py - Audit date: 2026-06-08
The Tier 2 evidence is tools/verify_link_lxmf.py and the deterministic
test-vectors/link-lxmf.json. Confirmed findings are promoted into SPEC.md
and the Link-LXMF flow documents.
Confirmed Model
-
LXMessage.pack()computes:content_size = len(packed_payload) - TIMESTAMP_SIZE - STRUCT_OVERHEADDIRECT selects PACKET when
content_size <= LINK_PACKET_MAX_CONTENTand Resource otherwise (LXMessage.py:405-421). The threshold applies to this computed value, not simplylen(content)and not the complete signed LXMF body. -
With default RNS 1.2.4 / LXMF 0.9.7 parameters,
LINK_PACKET_MAX_CONTENT = 319. The deterministic boundary fixtures use empty title/fields, so their raw content lengths also happen to be 319 and 320. The PACKET fixture's complete canonical LXMF body is 431 bytes, equal toLink.MDU; after Link Token framing its complete wire packet is 499 bytes. -
DIRECT/PACKET passes the complete canonical body
destination_hash || source_hash || signature || msgpack_payloadtoRNS.Packet(link, packed)(LXMessage.py:627-635). Packet packing emits HEADER_1 DATA/LINK with context NONE and Link-derived Token encryption (Packet.py:176-219). -
DIRECT/RESOURCE passes that same complete canonical body to
RNS.Resource(packed, link, ...)(LXMessage.py:643-653). Resource then applies its own whole-stream Link encryption and fragmentation. -
On receive,
LXMRouter.delivery_packet()proves the Link DATA packet, classifiesdestination_type == LINKas DIRECT, and passes the decrypted body unchanged tolxmf_delivery()(LXMRouter.py:1822-1850). Unlike the opportunistic path, it does not prepend a destination hash. -
delivery_resource_concluded()passes the assembled Resource body tolxmf_delivery(..., method=DIRECT)(LXMRouter.py:1876-1885). -
PACKET completion is the regular Link DATA proof callback; Resource completion is the Resource callback. Both converge on
LXMessage.__mark_delivered()(LXMessage.py:471-490, 594-603).
Tier 2 Scope
tools/verify_link_lxmf.py verifies:
- Exact computed-content boundary: 319 selects PACKET, 320 selects Resource.
- Deterministic Link DATA bytes using the session key from
links.json. - DIRECT/PACKET decrypts to the complete canonical LXMF body and validates Alice's signature.
- DIRECT/RESOURCE decrypts and reassembles to the same canonical form.
- A wrong Link key cannot decrypt the DIRECT/PACKET ciphertext.
LXMRouter.delivery_packet()proves Link DATA, classifies it DIRECT, and forwards the full plaintext unchanged.
This work unit does not run a live threaded Link exchange. Link establishment, LRRTT activation, generic Link proof format, and generic Resource behavior are covered by their existing focused verifiers.