Umbrella tracker — splitting #195 into 9 child PRs
#195 is the canonical 'mesh security hardening' PR (77 files changed, +15,965/-216, 213 review threads, 24 R-rounds). It is correct as a single piece of work but operationally hostile to review. Splitting it into 9 dependency-ordered child PRs lets reviewers focus on one subsystem at a time, lets CI signal stay sharp, and keeps git bisect useful in the future.
The full split plan with dependency graph, file mappings, and reviewer focus per slice lives in PR_LIST.md on my fork. This issue is the live tracker.
Threat surface (recap from #195)
11 attack vectors across 3 attacker tiers (LAN device, stolen IoT cert, prompt injection): unauth /cmd publish, replay, fake policy_host, dual-path double-exec, prompt-injected emergency_stop, audit tampering, camera URL capture, command-after-Estop, presence spoofing, /cmd flood, CA-substitution MITM.
Solution architecture (recap)
Defence-in-depth in three layers:
- Wire layer (Zenoh built-ins) — mTLS, per-key-expr ACL, downsampling rate caps, low_pass_filter byte caps, namespace isolation, gossip-only scouting, session-count bound, safety-topic caps.
- Payload layer (
mesh/security.py, ~786 LOC) — action allowlist + bounds, VLA host allowlist, HF repo gate, policy class registry gate.
- LLM tool layer (
tools/robot_mesh.py) — HITL via tool_context.interrupt, per-action rate limit, declined-doesn't-consume.
- Audit (
mesh/audit.py) — per-record HMAC + per-peer monotonic seq + bounded rotation + tamper-aware cursor + symlink-resistant inode writes.
Child PRs (in landing order)
Dependency graph
PR-1 (#220, test infra) ──┐
├──► PR-2 (#223 security) ───────────────┐
├──► PR-3 (#224 wire) ──┐ ├──► PR-6 (#225 core) ──► PR-7 (#227 tools) ─────┐
├──► PR-4 (#221 audit) ──┤ ├──► PR-9 (#226 docs)
│ ├──► PR-8 (#228 iot) ────────────────────────────────┘
└──► PR-5 (#222 bridge) ──┘
PR-1 (#220) → 2/3/4/5 can land in parallel after #220.
PR-6 (#225) needs all of #223 / #224 / #221 / #222 merged.
PR-7 (#227) needs #223 + #225.
PR-8 (#228) needs #223 + #221 (parallel with #225 / #227).
PR-9 (#226) lands last.
Note: GitHub assigned PR numbers in API call order, not slot order — hence the apparent jumble (#226=docs, #227=tools, #228=iot). The slot-to-PR-number mapping above is the source of truth.
Closing condition
This issue closes when PR-9 (#226) lands and #195 is closed with a redirect comment.
Review-thread bookkeeping
The 213 review threads on #195 stay open until the corresponding child PR closes them; child PRs cite the original #195 thread URL when resolving. The R-round changelog table on #195 is the forensic source of truth.
CI expectations
- PR-1 / PR-2 / PR-3 / PR-4 / PR-5 — CI green standalone after each one merges (or against
main).
- PR-6 / PR-7 / PR-8 / PR-9 — CI red in isolation. They will go green as their dependencies land. This is intentional: the diffs are reviewable now, but the integration only compiles once the leaves are in.
Tracking child of #195. Generated by DevDuck 2026-05-25.
Umbrella tracker — splitting #195 into 9 child PRs
#195 is the canonical 'mesh security hardening' PR (77 files changed, +15,965/-216, 213 review threads, 24 R-rounds). It is correct as a single piece of work but operationally hostile to review. Splitting it into 9 dependency-ordered child PRs lets reviewers focus on one subsystem at a time, lets CI signal stay sharp, and keeps
git bisectuseful in the future.The full split plan with dependency graph, file mappings, and reviewer focus per slice lives in
PR_LIST.mdon my fork. This issue is the live tracker.Threat surface (recap from #195)
11 attack vectors across 3 attacker tiers (LAN device, stolen IoT cert, prompt injection): unauth
/cmdpublish, replay, fake policy_host, dual-path double-exec, prompt-injected emergency_stop, audit tampering, camera URL capture, command-after-Estop, presence spoofing,/cmdflood, CA-substitution MITM.Solution architecture (recap)
Defence-in-depth in three layers:
mesh/security.py, ~786 LOC) — action allowlist + bounds, VLA host allowlist, HF repo gate, policy class registry gate.tools/robot_mesh.py) — HITL viatool_context.interrupt, per-action rate limit, declined-doesn't-consume.mesh/audit.py) — per-record HMAC + per-peer monotonic seq + bounded rotation + tamper-aware cursor + symlink-resistant inode writes.Child PRs (in landing order)
test(mesh): test PKI helpers + shared conftest— ~155 LOC · 0 threads · ships firstmesh(security): payload validation module— ~786 src + ~1,710 test LOC · ~12 threads (R10/R11/R23/R24-B)mesh(wire): Zenoh + ACL config builders— ~1,120 src + ~2,440 test LOC · ~30 threads (R7/R14/R15/R18/R21/R23/R24-C/R25-d)mesh(audit): tamper-evident audit log— ~1,152 src + ~1,830 test LOC · ~28 threads (R6/R8/R18/R20/R21/R23/R25)mesh(transport): bridge cross-transport dedup— ~267 src + ~325 test LOC · ~10 threads (R12/R15/R20)mesh(core): replay caches + override-resume + safety topic handlers— ~1,713 src + ~1,420 test LOC · ~50 threads (R9/R13/R17/R19/R23/R24-A/R25-source-zid)mesh(tools): robot_mesh HITL via tool_context.interrupt— ~324 src + ~325 test LOC · ~12 threads (R11/R16/R24)mesh(iot): AWS IoT provisioning hardening— ~437 src + ~896 test LOC · ~20 threadsdocs(mesh): README env-var matrix + CHANGELOG entry— ~409 LOC · 0 threads · lands lastDependency graph
PR-1 (#220) → 2/3/4/5 can land in parallel after #220.
PR-6 (#225) needs all of #223 / #224 / #221 / #222 merged.
PR-7 (#227) needs #223 + #225.
PR-8 (#228) needs #223 + #221 (parallel with #225 / #227).
PR-9 (#226) lands last.
Note: GitHub assigned PR numbers in API call order, not slot order — hence the apparent jumble (#226=docs, #227=tools, #228=iot). The slot-to-PR-number mapping above is the source of truth.
Closing condition
This issue closes when PR-9 (#226) lands and #195 is closed with a redirect comment.
Review-thread bookkeeping
The 213 review threads on #195 stay open until the corresponding child PR closes them; child PRs cite the original #195 thread URL when resolving. The R-round changelog table on #195 is the forensic source of truth.
CI expectations
main).Tracking child of #195. Generated by DevDuck 2026-05-25.