fix: MeshCore spec compliance audit and packet quality warnings

Audited against meshcore-spec and fixed all compliance gaps:

- Fix trace hash size encoding: use 1<<(flags&3) not (flags&3)+1
- Reject reserved path hash_size_code 3 per spec Section 3
- Minimum packet size 3 bytes (was 2)
- Add MAX_PACKET_PAYLOAD (184) and min payload (1) validation
- Tighten payload minimums: ANON_REQ≥51, encrypted≥20, group≥19,
  multipart≥2
- Add node_type 0 ("none") to NODE_TYPES
- Fix node_type fallback display (was "node=type=14", now "node=0x0e")

Add packet quality warnings for likely-corrupt frames:
- decode_meshcore_packet returns (str, list[str]) with quality warnings
- ADVERT: flag bad node_type, bad UTF-8 in name, future/bad timestamps
- Combine content warnings with low-SNR signal at display layer
- Warnings stack: one flag = maybe, multiple = high confidence corrupt

Update test corpus and generators for tightened validation rules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
swaitsandClaude Opus 4.6 committed 2026-04-01 11:57:32 -06:00
1 parent d551095f3f
commit d01de9d14d
10 files changed
+198 -82

No files matched your search

@@ -1,11 +1,11 @@
{
"description": "TXT_MSG flood, path_len claims 33 hops (4B hash) but data is too short",
"description": "TXT_MSG flood, path_len claims 33 hops (2B hash) but data is too short",
"tags": [
"invalid",
"bad_framing",
"path"
],
"packet_hex": "09e1000000000000000000000000000000000000000000000000",
"packet_hex": "0961000000000000000000000000000000000000000000000000",
"valid": false,
"expected": {
"route_type": "flood",
@@ -0,0 +1,16 @@
{
"description": "TXT_MSG flood, path_len has reserved hash_size_code 3",
"tags": [
"invalid",
"bad_framing",
"path",
"reserved_hash_size"
],
"packet_hex": "09c1000000000000000000000000000000000000000000000000",
"valid": false,
"expected": {
"route_type": "flood",
"payload_type": "TXT_MSG",
"error": "bad_framing"
}
}
@@ -1,29 +1,17 @@
{
"description": "PATH flood, 1 hop with 4-byte hash",
"description": "PATH flood, 4-byte hash (reserved hash_size_code 3, invalid)",
"tags": [
"invalid",
"path",
"flood",
"4byte_hash",
"encrypted"
"reserved_hash_size"
],
"packet_hex": "21c1aabbccdde6e92e4700000000000000000000000000000000",
"valid": true,
"valid": false,
"expected": {
"route_type": "flood",
"payload_type": "PATH",
"payload_ver": 0,
"transport_codes": null,
"path": {
"hash_size": 4,
"hops": [
"aabbccdd"
]
},
"payload": {
"dst": "e6",
"src": "e9",
"mac": "2e47",
"ciphertext_len": 16
}
"error": "bad_framing"
}
}
@@ -0,0 +1,14 @@
{
"description": "Packet too short (2 bytes, need >= 3)",
"tags": [
"invalid",
"too_short"
],
"packet_hex": "1100",
"valid": false,
"expected": {
"route_type": "flood",
"payload_type": "ADVERT",
"error": "too_short"
}
}
@@ -0,0 +1,24 @@
{
"description": "TRACE flood with 4-byte trace hashes (flags=0x02, hash_size=4)",
"tags": [
"trace",
"flood",
"4byte_hash"
],
"packet_hex": "2500ddccbbaa4433221102deadbeefcafebabe",
"valid": true,
"expected": {
"route_type": "flood",
"payload_type": "TRACE",
"payload_ver": 0,
"transport_codes": null,
"path": {
"hash_size": 1,
"hops": []
},
"payload": {
"trace_tag": 2864434397,
"trace_hops": 2
}
}
}