docs(adr): ADR-086 — edge novelty gate (proposed)#434
Conversation
Pushes the ADR-084 novelty sensor down into the ESP32 sensor MCU's Layer 4 (On-device Feature Extraction) of ADR-081's 5-layer kernel: sketch + 32-slot ring bank in IRAM, suppress UDP send when novelty < CONFIG_RV_EDGE_NOVELTY_THRESHOLD (default 0.05). Wire format bumps to magic 0xC5110007 with two new fields (suppressed_since_last: u16, gate_version: u8) packed in by narrowing the existing 16-bit quality_flags to 8-bit (only 8 bits were ever defined). Frame size stays at 60 bytes; v6 receivers fall back gracefully. Stuck-gate self-heal at CONFIG_RV_EDGE_MAX_CONSEC_SUPPRESS (default 50 frames ≈ 10 s) so a wedged threshold can't silently disappear a node. Default-off Kconfig so existing deployments are unaffected. Validation commitments: - ≤ 200 µs sketch insert+score on Xtensa LX7 - ≥ 30% UDP TX-energy reduction in steady-state quiet rooms - ≤ 5 pp drop on cluster-Pi novelty top-K coverage vs unsuppressed - ≥ 50% bandwidth reduction in stable-room scenarios Six-pass implementation plan, default-off Kconfig, QEMU + COM7 hardware-in-loop validation. Honest gaps flagged: Xtensa LX7 POPCNT absence is conjecture (Pass 2 bench is the falsifier); interaction with ADR-082's Tentative→Active gate is the likeliest weak point (Open Q4). ADR-087 / ADR-088 reserved as pointer stubs at end: - ADR-087: Pass-4 mesh-exchange scope (cluster↔cluster vs sensor→Pi) - ADR-088: Firmware-release coordination policy Status: Proposed. SOTA review by goal-planner agent. Co-Authored-By: claude-flow <ruv@ruv.net>
Why this matters, in plain languageThis enables edge reflexes. Instead of sending every sensor frame upward and asking the bigger system "is this interesting?", each small device can decide locally:
or:
That is the practical shift. BeforeEvery node sends feature packets constantly: The current firmware emits one AfterThe sensor MCU does a tiny RaBitQ-style sketch locally: So the node suppresses boring frames and only transmits when the signal changes enough to matter. It still reports how many frames it suppressed, so the system knows silence was intentional, not failure. What this gives you
Why the numbers matterRadio transmission is expensive on tiny devices. At 50% suppression a node drops from ~5 packets/sec to ~2.5 packets/sec; at 90% suppression it drops to ~0.5 packets/sec. The ADR's validation targets are at least 30% UDP TX-energy reduction in quiet rooms and 50% bandwidth reduction per node. The real product meaningThis turns the sensor node from a dumb streamer into a local decision point. Not full intelligence. A reflex. That last part matters. The suppression cap prevents the device from going silent forever. The ADR sets the default Bottom lineThis enables a mesh of devices that is mostly quiet, low power, and low noise until something changes. That is exactly how an always-on sensing system should behave. It does not process everything deeply. It watches cheaply, escalates selectively, and proves when it stayed silent. |
All five implementation passes plus four security-review hardenings shipped in PR #435 (squash-merged as d71ef9a). Acceptance numbers measured on synthetic AETHER-shape data: - Compare-cost reduction: 8x-30x floor → 43-51x pair-wise (d=512), 12.4x top-K (d=128 n=1024 k=8), 7.6x full pipeline (d=128 n=4096 k=8). - Top-K coverage: ≥90% floor → 90%+ at prefilter_factor=8 (78.9% at factor=4 documented as fail; codified in test_search_prefilter_topk_coverage_meets_adr_084). - Wire envelope: 28-byte AETHER 128-d (vs 512-byte raw float; 18x compression). The third acceptance criterion (`< 1 pp end-to-end accuracy regression`) needs a real-CSI soak test against a multi-day AETHER trace; that's post-merge follow-up rather than a merge-blocker. Synthetic-data acceptance was sufficient evidence to ship. PR #434 (ADR-086 firmware-side gate) merged separately as 17509a2. Co-Authored-By: claude-flow <ruv@ruv.net>
Summary
Pushes the ADR-084 novelty sensor down into the ESP32 sensor MCU's Layer 4 (On-device Feature Extraction) of ADR-081's 5-layer kernel. When novelty falls below the gate threshold, the firmware suppresses the UDP send — saving bandwidth, RF airtime, and TX energy in steady-state quiet rooms.
What this changes (and what it does NOT)
rv_sketch.{h,c}(no_std 1-bit sketch + 32-slot IRAM ring bank), three Kconfig flags,rv_feature_state_tmagic bumps to0xC51100070xC5110007addssuppressed_since_last: u16+gate_version: u8without growing payload (narrows existing 16-bitquality_flagsto 8-bit; only 8 bits were ever defined). v6 receivers fall back gracefully.suppressed_since_last > 0, treat the gap as low-novelty contribution to the bank rather than missing dataDecision summary
CONFIG_RV_EDGE_NOVELTY_THRESHOLD(basis-point integer, default 500 = 0.05).CONFIG_RV_EDGE_MAX_CONSEC_SUPPRESS(default 50 frames ≈ 10 s at 5 Hz).CONFIG_RV_EDGE_NOVELTY_GATE_ENABLE=n) so existing deployments behave identically until opted in.Validation commitments
Six-pass implementation plan
rv_sketch.{h,c}no_std primitive — 1-bit sign quantization, packed-byte storage, 8-bit-table popcount for hamming. QEMU validation first.RV_EDGE_BANK_SIZE×RV_EDGE_VECTOR_DIM_BYTESbytes. FIFO eviction.rv_feature_state_tv7 wire format — magic + new fields, v6 fallback on receiver.suppressed_since_lastinterpolation in the novelty bank.Open questions explicitly flagged
gate_version: u8provenance — Kconfig-pinned, NVS-stored, or per-firmware-release embedded?Reserved follow-up ADR slots (pointer stubs in §"Related ADR slots")
Why this lands as its own ADR (not folded into ADR-084)
ADR-084 explicitly states "Sensor MCU is unchanged by this ADR; sketches happen at the cluster Pi." Pushing the gate down to the MCU is a different engineering decision with its own cost/benefit, its own threat model (firmware Secure-Boot V2 + signed images per ADR-028), and its own release cycle. Keeping it separate makes the cluster-Pi work shippable independently of the firmware release cycle.
Test plan
v2/andarchive/v1/(post-rename)0xC5110007, narrowedquality_flags, two new fields)🤖 Generated with claude-flow