# Filter policy playground Build a forwarding policy, see its readable definition, and simulate how a repeater handles a packet. Rules match received packet facts, then apply actions such as dropping, scoping, rate-limiting, or retrying a flood. Everything runs locally in this browser. Channel keys, packet facts, and policy drafts are not uploaded anywhere.
Policy design preview

The phases and core conditions model current FPF7 behavior, including its forward rows, scope rewrites, and shared blacklist. The readable policy language, JSON, and Base64 bundle are still a prototype: current firmware is configured with set flood.* commands and cannot install a bundle from this page.

## Build a policy Start with an example or build a rule, then test the draft against packet facts in the simulator below. The examples draw from [Flood Filtering and Moderation](flood_filtering.md).
Remote login and direct routes

This policy only decides whether a relay retransmits a flood. Direct packets and local delivery are unaffected. Rules matching the login/admin family can still reduce multi-hop remote-login reach, so the analyzer flags them.

Example policies Choose one to load its full rules into the builder and draft.

Read each summary as when all conditions match, do the actions. A match alone does not stop forwarding.

Payload selectors
type= valueMatches
grp_dataOnly the named payload type; see every exact type below
anyEvery payload type
class:groupGRP_TXT and GRP_DATA
class:loginREQ, RESPONSE, TXT_MSG, ANON_REQ, and PATH
class:otherEvery remaining payload type that is not group or login
Other conditions and actions
FieldMeaning
hops=Received hop count: all, 3+, 2-6, or 3
channel=* means no channel condition; a name or key authenticates one group channel
rx.scope=Original incoming transport scope
path=Path prefix, blacklist, bucket, or loop match
tempradio=Temporary-radio state
do dropDo not retransmit
do scope=Set the outgoing transport scope
do rate=Apply a per-minute rate and burst
do timing=Select fast, normal, or slow scheduling

There is no class:txt. Use type=grp_txt for channel text or type=txt_msg for peer text.

Rule builder

Create a policy rule

Common match settings

Common actions

Choosing a phase-specific action automatically selects a compatible phase and ACL owner. Open the advanced section to inspect or override those choices.

Advanced execution, ownership, and flood route

Direct packets already carry a supplied path and are intentionally outside this engine. The route condition below only distinguishes unscoped floods from transport-scoped floods.

Readable policy definition

Policy draft

Rules in execution order

Rules match the same immutable packet facts. Ordering is phase, then descending priority, then stable rule ID. Drop decisions are sticky.

Add a rule or load an example to start exploring.

    Immutable packet simulator

    Explain an evaluation

    Read a raw MeshCore packet

    Paste an on-air packet as hexadecimal. The decoder follows the MeshCore wire format, displays its header, route, pbyte path, and clear payload envelope, then loads only facts actually present on the wire into the simulator.

    Runs locally

    Import and explain

    Paste readable policy or a saved draft

    Accepts one-line policy set ... when ... do ... definitions, playground JSON, or a playground Base64 bundle.

    Export

    Move or save this design

    Proposed human-readable definition. Current firmware does not accept it yet.

    ## Payload type reference Use an exact `type=` value when a rule should match only one payload type. The class column shows which broader selector also matches it. | `type=` value | Payload | Class | | --- | --- | --- | | `req` | Request | `class:login` | | `response` | Response | `class:login` | | `txt_msg` | Peer text message | `class:login` | | `ack` | Acknowledgment | `class:other` | | `advert` | Node advertisement | `class:other` | | `grp_txt` | Group-channel text | `class:group` | | `grp_data` | Group-channel datagram | `class:group` | | `anon_req` | Anonymous request | `class:login` | | `path` | Returned path | `class:login` | | `trace` | Path trace | `class:other` | | `multipart` | One frame in a multipart sequence | `class:other` | | `control` | Control or discovery data | `class:other` | | `ota` | OTA-over-LoRa data | `class:other` | | `13` | Reserved payload type 13 | `class:other` | | `14` | Reserved payload type 14 | `class:other` | | `raw_custom` | Application-defined raw data | `class:other` | ## Current FPF7 command mapping | Firmware command | FPF7 role | | --- | --- | | `flood.rule` / `flood.filter` | Forward-phase match and action rows | | `flood.channel.data` | Compatibility view over one visible `type=grp_data` forward drop row | | `flood.channel.scope` | Scope-rewrite phase rows | | `flood.filter.blacklist` | One shared unordered path-ID set referenced by `path=blacklist` rows | Generalized repeaters expose 63 forward rows and commit those sections together. The blacklist is useful for refusing to retransmit floods associated with internet gateways dumping bulk traffic, but a path ID is truncated and unauthenticated; it identifies a routing pattern, not a person. ## Proposed evaluation contract The simulator uses these rules: 1. Only flood retransmission enters the policy. Direct routing and local packet delivery remain outside it. 2. Every matcher reads the same immutable receive-time packet facts. 3. Rules run by phase, descending priority, then stable rule ID. 4. A drop decision is sticky and cannot be undone by a later rule. 5. The first matching scope, timing, queue, and retry action in execution order wins. 6. All matching token-bucket rate constraints remain attached to the decision. 7. `stop=phase` skips later rules in that phase. `stop=policy` skips later configurable rules, but never mandatory packet validation or radio safety. 8. Shadow rules report what they would do without changing the decision or stopping other rules. 9. Expensive facts such as channel-key matching, decryption, and path-table lookup are resolved once per packet and reused by every matching rule. The byte-budget display is deliberately approximate until the packed firmware codec exists. It demonstrates why simple mappings should not reserve a maximum- sized structure for every possible condition and action.