Ingestor transmits a daily activity announcement by default — RX_ONLY is the only opt-out, and the README doesn't mention it #229

Closed
opened 2026-10-04 23:04:49 +02:00 by adam · 2 comments
Owner

What happens

A stock Meshtastic ingestor broadcasts one line per 24 h on CHANNEL_INDEX:

Meshtastic activity in the last 24h: <N> active nodes, <M> packets/hour. <INSTANCE_DOMAIN>

This is mesh_ingestor/announce.py (SPEC MA6–MA9). The only gate is RX_ONLY, and it defaults to off:

# config.py
RX_ONLY = os.environ.get("RX_ONLY") == "1"

So transmitting is the default, and per MA7 there is deliberately no separate enable switch — an operator who just wants to feed a map is opted into RF traffic on the shared default channel.

Why this is a problem

I run a Meshtastic-only instance purely as a map ingestor. After an image update the announcements started going out, and I got a complaint from another operator on the regional channel for posting bot spam — entirely fair, and I hadn't knowingly enabled anything. The default channel is a shared, human, low-bandwidth medium; local communities differ a lot in what they consider acceptable automated traffic, and some ban bots outright. A default that makes every new node talk unprompted puts operators in that position without their knowledge.

The single opt-out compounds it: RX_ONLY=1 also silences the MeshCore contact telemetry/status polls, so "ingest, but stay quiet on the air" is not expressible today.

The docs gap makes it worse

The README env table does list RX_ONLY, but describes it as:

Set to 1 to forbid every ingestor-initiated mesh transmission (receive-only listening post). Currently disables the MeshCore contact telemetry/status polls; local companion-link reads (self telemetry, roster, channels) continue.

The Meshtastic activity announcement is not mentioned there, or anywhere else in the README. So even an operator who reads the whole env table has no way to learn that their ingestor speaks on their channel. The code's own docstring is accurate ("…and the periodic activity announcement (SPEC MA7)"); the README is behind it.

Suggested fix

  1. Add a dedicated ANNOUNCE boolean, default off — opt-in, so operators choose to put their instance on the air. RX_ONLY=1 keeps overriding everything as the global TX kill switch.
  2. Document the announcement in the README env table and in the RX_ONLY row either way.

I understand MA7 explicitly decided against a separate enable env; this issue is the argument for revisiting that, since the field consequence is that new operators become unwitting spammers. Happy to keep the default at 1 (granular opt-out only, no behaviour change) if you prefer — the flag is useful either way.

A PR implementing (1) with SPEC/ACCEPTANCE amendments and unit tests follows.

**What happens** A stock Meshtastic ingestor broadcasts one line per 24 h on `CHANNEL_INDEX`: ``` Meshtastic activity in the last 24h: <N> active nodes, <M> packets/hour. <INSTANCE_DOMAIN> ``` This is `mesh_ingestor/announce.py` (SPEC MA6–MA9). The only gate is `RX_ONLY`, and it defaults to off: ```python # config.py RX_ONLY = os.environ.get("RX_ONLY") == "1" ``` So transmitting is the default, and per MA7 there is deliberately no separate enable switch — an operator who just wants to feed a map is opted into RF traffic on the shared default channel. **Why this is a problem** I run a Meshtastic-only instance purely as a map ingestor. After an image update the announcements started going out, and I got a complaint from another operator on the regional channel for posting bot spam — entirely fair, and I hadn't knowingly enabled anything. The default channel is a shared, human, low-bandwidth medium; local communities differ a lot in what they consider acceptable automated traffic, and some ban bots outright. A default that makes every new node talk unprompted puts operators in that position without their knowledge. The single opt-out compounds it: `RX_ONLY=1` also silences the MeshCore contact telemetry/status polls, so "ingest, but stay quiet on the air" is not expressible today. **The docs gap makes it worse** The README env table does list `RX_ONLY`, but describes it as: > Set to `1` to forbid every ingestor-initiated mesh transmission (receive-only listening post). Currently disables the MeshCore contact telemetry/status polls; local companion-link reads (self telemetry, roster, channels) continue. The Meshtastic activity announcement is not mentioned there, or anywhere else in the README. So even an operator who reads the whole env table has no way to learn that their ingestor speaks on their channel. The code's own docstring is accurate ("…and the periodic activity announcement (SPEC MA7)"); the README is behind it. **Suggested fix** 1. Add a dedicated `ANNOUNCE` boolean, **default off** — opt-in, so operators choose to put their instance on the air. `RX_ONLY=1` keeps overriding everything as the global TX kill switch. 2. Document the announcement in the README env table and in the `RX_ONLY` row either way. I understand MA7 explicitly decided against a separate enable env; this issue is the argument for revisiting that, since the field consequence is that new operators become unwitting spammers. Happy to keep the default at `1` (granular opt-out only, no behaviour change) if you prefer — the flag is useful either way. A PR implementing (1) with SPEC/ACCEPTANCE amendments and unit tests follows. <!-- github-sync-id:5075243754 -->
adam closed this issue 2026-10-04 23:04:50 +02:00
Author
Owner

Correction to my own report: v0.7.4's release notes did mention this — "all ingestors announce stats to the mesh every 24 hours. can be disabled by setting RX_ONLY = 1". My "not documented anywhere" was wrong and I apologise.

The README gap stands (neither the env table nor the RX_ONLY row mentions the announcement), and so does the substance: for an operator tracking :latest, one line in a 20-entry release note is not consent, and RX_ONLY remains an all-or-nothing opt-out.

Correction to my own report: v0.7.4's release notes did mention this — *"all ingestors announce stats to the mesh every 24 hours. can be disabled by setting `RX_ONLY = 1`"*. My "not documented anywhere" was wrong and I apologise. The README gap stands (neither the env table nor the `RX_ONLY` row mentions the announcement), and so does the substance: for an operator tracking `:latest`, one line in a 20-entry release note is not consent, and `RX_ONLY` remains an all-or-nothing opt-out. <!-- github-comment-id:5197478935 -->
Author
Owner

I'm sorry for that. I wanted to ship the release before I go on vacation and I should have deferred this specific feature.

Please run with RX_ONLY=1 for now to mitigate and I'll make sure to carefully review this in the coming days. Will also take a look at #886

I'm sorry for that. I wanted to ship the release before I go on vacation and I should have deferred this specific feature. Please run with `RX_ONLY=1` for now to mitigate and I'll make sure to carefully review this in the coming days. Will also take a look at #886 <!-- github-comment-id:5315569753 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/potato-mesh#229