Skip to content

fix(pause): PAUSE takes the decoys off the air instead of freezing them on it - #19

Merged
Em3ritus merged 1 commit into
mainfrom
fix/pause-goes-silent-2026-10-07
Oct 8, 2026
Merged

Em3ritus merged 1 commit into
mainfrom
fix/pause-goes-silent-2026-10-07

Conversation

@Em3ritus

@Em3ritus Em3ritus commented Oct 7, 2026

Copy link
Copy Markdown
Owner

As requested: PAUSE now stops all decoy signals instead of holding the crowd as it was.

The bug

churn_tick returned before the lifecycle while paused, so the four BLE advertising slots kept transmitting the same addresses for as long as the fleet stayed paused. That's an indefinitely long-lived identifier, exactly what ADDR_MAX_ONAIR_MS exists to prevent. Meanwhile the Vigil showed DARK.

The fix

  • BLE: the first paused tick stops every advertising instance (churn_set_stop / churn_adv_stop) and forgets each slot's occupant, so resume re-applies all four. The stop runs inside churn_tick, on the task that owns the slots.
  • Lifecycle keeps running underneath, so identities still die on schedule and resume brings back a current crowd, never an address carried across the pause.
  • Wi-Fi: 2.4 GHz bursts and 5 GHz excursions are skipped while paused; agent, persona and MAC rotation keep their schedule. The standalone probe_task honours it too.
  • ESP-NOW stays up on purpose. It's how the Vigil sees a paused node (DARK) and sends RESUME. Silencing it too would make a paused fleet unrecoverable without a power cycle. Easy to change if you want it fully dark.

README and CHANGELOG updated to match.

Verification

  • On-device self-test (test_churn_pause) rewritten for the new contract. C6 CHURN_SELFTEST=1 image builds (IDF 5.4).
  • Production C5 image builds (IDF 5.5, ESPNOW + CONFIG_CTRL + FLEET_PROVISION).
  • Same checks run on the host against the real churn.c + ble_devices.c + phantom.c: stop all 4 once per pause, zero applies while paused, 0 of 8 addresses survive a >15 min pause, resume re-applies all 4 slots.
  • All host suites pass (decoy_audit 209, probe_audit 98, radar_audit 107, pcap_learn 4, tools/tests 17, web 34).
  • Not yet on hardware. Flash a decoy, PAUSE from the Vigil, and confirm with a sniffer that its BLE adverts and probe requests stop, then that RESUME brings them back.

🤖 Generated with Claude Code

…em on it

churn_tick returned before the lifecycle while paused, so the four BLE
advertising slots kept transmitting the same addresses for as long as the
fleet stayed paused: an indefinitely long-lived identifier, the exact thing
ADDR_MAX_ONAIR_MS exists to prevent. The console meanwhile said DARK.

Now PAUSE is silent:
- churn: the first paused tick stops every advertising instance (new
  churn_stop_fn, churn_adv_stop in production) and forgets each slot's
  occupant, so resume re-applies all of them. The stop runs inside
  churn_tick, on the task that owns the slots, not in the setter.
- The lifecycle keeps running underneath, so identities still die on
  schedule and the crowd that returns is a current one, never an address
  carried across the pause.
- coexist: probe bursts (2.4 GHz and the 5 GHz excursion) are skipped while
  paused; agents, personas and MAC rotation keep their schedule. The
  standalone probe_task honours it too.
- The ESP-NOW control link stays up on purpose: it is how the Vigil sees a
  paused node and sends RESUME.

Self-test rewritten for the new contract (stop all, once per pause; no
applies while paused; no address survives a >15 min pause; resume
re-applies every slot). Ran the same checks on the host against the real
churn.c/ble_devices.c: all pass. C6 self-test and C5 production images
build. Not yet run on hardware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Em3ritus
Em3ritus merged commit a14f0de into main Oct 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant