Added deterministic `resources.json` and `regen_resources.py`. Extended `verify_resource.py` with receiver assembly/proof and requested negative cases. Updated specification, audit, status, and tool documentation. Fixed an unrelated nondeterministic wrong-ticket test in verify_stamps.py. Confirmed vector regeneration is byte-identical. Confirmed no tracked reliance on specenv or user-specific paths. git diff --check: pass. Complete pinned suite: 16 passed, 0 failed.
6.1 KiB
Tier 1 Audit: Resource Fragmentation
Question: Does SPEC.md §10 accurately describe the wire-visible Resource
fragmentation behavior of upstream RNS 1.2.4?
Evidence baseline:
- RNS package:
rns==1.2.4 - Source: installed package paths
RNS/Resource.py,RNS/Packet.py,RNS/Link.py, andLXMF/LXMessage.py - Audit date: 2026-06-08
This began as a Tier 1 source-analysis report. The completed Tier 2 checks
live in tools/verify_resource.py and test-vectors/resources.json; the
confirmed F1-F6 corrections were promoted into SPEC.md §10 on 2026-06-08.
Confirmed Core Model
The central §10 model matches RNS 1.2.4:
- Resource prepends a throwaway 4-byte prefix, encrypts the complete stream
once with the Link, then slices the ciphertext into parts
(
Resource.py:404-428,453-472;Packet.py:201-204). - Advertisement
ris a distinct 4-byte salt used for the resource hash and per-part map hashes (Resource.py:440-443,505-506). - Resource integrity is
SHA256(uncompressed_segment_plaintext || r), and the expected proof isSHA256(uncompressed_segment_plaintext || resource_hash)(Resource.py:440-443,681-695,752-758). - RESOURCE_REQ may carry requested part hashes while also requesting a hashmap
continuation; the sender fulfils parts before emitting RESOURCE_HMU
(
Resource.py:994-1027,1027-1064). - RESOURCE parts are matched only within the receiver's current window, while
sender lookup is bounded by
COLLISION_GUARD_SIZE(Resource.py:863-890,999-1010).
Findings Requiring Correction or Clarification
F1 — Direct LXMF threshold is 319 bytes, not approximately 360
SPEC.md §10 introduction says Resource carries an LXMF body larger than
approximately 360 bytes. With default RNS 1.2.4 / LXMF 0.9.7 parameters:
RNS.Link.MDU = 431
LXMessage.LXMF_OVERHEAD = 112
LXMessage.LINK_PACKET_MAX_CONTENT = 319
LXMessage.pack() selects Resource representation for DIRECT delivery when
content_size > 319 (LXMF/LXMessage.py:80-89, 414-421).
Recommended Tier 3 correction: say 319 bytes with default parameters, while noting that the threshold derives from Link MDU and may vary with protocol parameters.
F2 — Resource is not the only possible way to carry larger application data
The §10 introduction calls Resource "the only way" to carry payloads exceeding
one Link packet. Resource is the standard RNS mechanism used by LXMF, Link
REQUEST/RESPONSE, and rncp, but applications can also stream or sequence data
over Channel or their own Link DATA protocol.
Recommended Tier 3 correction: replace "the only way" with "the standard RNS mechanism used by LXMF, REQUEST/RESPONSE, and file-transfer utilities".
F3 — Advertisement d is total logical-resource size
For multi-segment resources, advertisement field d is resource.total_size,
the total uncompressed logical transfer size including metadata, not the
plaintext size of the advertised segment (Resource.py:281-314,
Resource.py:1281-1283).
Each segment still has its own:
t: encrypted transfer size for this segmentn: part count for this segmenth: integrity hash for this segmentr: salt for this segment
Recommended Tier 3 correction: define d as total logical-resource size and
explicitly distinguish it from the current segment's uncompressed plaintext
length, which is not directly advertised.
F4 — RESOURCE_RCL is not a general receiver-side cancel notification
Resource.reject(advertisement_packet) sends RESOURCE_RCL
(Resource.py:154-163). A corrupt receiver also calls reject() and tears
down the Link (Resource.py:1081-1084).
However, ordinary receiver-side Resource.cancel() only removes the incoming
resource locally; it does not send RESOURCE_RCL
(Resource.py:1086-1097). The current §10.9 wording implies either side can
always notify cancellation on the wire.
Recommended Tier 3 correction: describe RESOURCE_RCL as advertisement
rejection / corrupt-resource rejection. Do not claim ordinary receiver cancel
always emits it.
F5 — Resource-part packet storage wording is imprecise
SPEC.md §10.2 says packed wire bytes are stored in parts[i]. Upstream stores
pre-packed RNS.Packet objects in parts; each packet's data is the raw
ciphertext slice and its raw field is the packed Reticulum packet
(Resource.py:450-472).
Recommended Tier 3 clarification: distinguish the stored Packet object, its
Resource body (part.data), and complete Reticulum wire packet (part.raw).
F6 — Pinned-source mismatch in §10.7 citation
The exhausted-REQ callout cites RNS 1.2.9 while this repository is pinned to
RNS 1.2.4. The behavior is already present in RNS 1.2.4
(Resource.py:994-1064).
Recommended Tier 3 correction: cite the pinned 1.2.4 behavior first; retain a later-version note only when documenting an actual version change.
Tier 2 Verifier Scope
The focused verifier is implemented in tools/verify_resource.py and avoids
a live threaded transfer. It covers:
- Construct a Resource with a deterministic fake Link encryption key, fixed
throwaway prefix, and fixed advertisement
r. - Verify whole-stream encryption occurs before slicing.
- Verify Resource-part Packet bodies are raw slices and are not packet-level re-encrypted.
- Verify advertisement dictionary fields, flags, and hashmap first segment.
- Verify
hash,truncated_hash,expected_proof, and map-hash formulas. - Verify RESOURCE_REQ parsing for both normal and exhausted-with-parts forms, including simultaneous part fulfilment and RESOURCE_HMU generation.
- Verify receiver assembly strips the throwaway prefix, decrypts once, validates the hash, and emits the expected RESOURCE_PRF bytes.
- Verify a multi-segment fixture proving
dremains total logical size whilet,n,h, andrdescribe the current segment. - Verify negative cases: malformed ADV, wrong
r, corrupt part, invalid HMU boundary, and oversized decompression.
The deterministic fixture is regenerated by tools/regen_resources.py.
Tier 2 Resource work is complete for this audit scope; confirmed claims have
been promoted into SPEC.md and the Resource flow documents.