diff --git a/_javascript/filter_tool.js b/_javascript/filter_tool.js index 629297fa..f0f1e2e7 100644 --- a/_javascript/filter_tool.js +++ b/_javascript/filter_tool.js @@ -139,7 +139,7 @@ const channel = clean(value); if (!channel) { if (optional) return ""; - throw new FilterToolError("Authenticated channel is required."); + throw new FilterToolError("Channel is required."); } if (channel.toLowerCase() === "public") return "public"; if (channel[0] === "#") { @@ -279,7 +279,7 @@ } } if (rule.channel && !["any", "class:group", "grp_txt", "grp_data"].includes(rule.type)) { - throw new FilterToolError("Authenticated channel matching requires a group-capable payload type or class."); + throw new FilterToolError("Channel matching requires a group-capable payload type or class."); } if (rule.targetKind === "scope") rule.target = normalizeScopeName(input.target); if (rule.targetKind === "region") rule.target = normalizeRegionName(input.target); @@ -523,9 +523,9 @@ } function channelDescription(channel) { - if (channel === "public") return "authenticated Public channel"; - if (channel.startsWith("#")) return `authenticated ${channel}`; - return `authenticated key ${channel.slice(0, 8)}...`; + if (channel === "public") return "the Public channel"; + if (channel.startsWith("#")) return `the ${channel} channel`; + return `channel key ${channel.slice(0, 8)}...`; } function actionPhrases(rule) { @@ -595,7 +595,7 @@ : "Remote-management reach warning: this rule intentionally limits relayed login/admin floods at its hop or path condition. Direct routes and local delivery stay outside this policy."); } if (rule.type === "class:other") warnings.push("class:other intentionally includes current and future types outside group and login classes, including OTA."); - if (rule.channel && rule.type === "any") warnings.push("A channel condition narrows type=any to authenticated group text/data packets."); + if (rule.channel && rule.type === "any") warnings.push("A channel condition narrows type=any to group text/data packets on that channel."); if (rule.sender) warnings.push("Displayed sender names are spoofable and are moderation signals, not identities."); if (rule.pathKind !== "none") warnings.push("Pbyte and path-table matches use truncated routing hints, not authenticated identities."); if (rule.pathKind.startsWith("bucket:")) warnings.push("The selected bucket must exist on the target node; the policy stores a reference, not its IDs."); @@ -892,7 +892,7 @@ notes.push("Transport codes are on the wire, but a local region/scope table is required to resolve their names and allow status."); } if (GROUP_TYPES.includes(type)) { - notes.push("The raw channel hash does not authenticate a channel; the matching channel key is required."); + notes.push("A raw channel hash alone is insufficient to identify a channel; the matching channel key is required."); } if (["req", "response", "txt_msg", "path", "grp_txt", "grp_data", "anon_req"].includes(type)) { notes.push("Encrypted content, including a displayed sender, cannot be recovered without the appropriate key."); @@ -934,7 +934,7 @@ const channel = clean(input.channel) ? normalizeChannel(input.channel, false) : ""; const sender = clean(input.sender); if (channel && !GROUP_TYPES.includes(type)) { - throw new FilterToolError("Only group text/data packet facts can include an authenticated channel."); + throw new FilterToolError("Only group text/data packet facts can include a channel."); } if (sender && type !== "grp_txt") { throw new FilterToolError("Only a decrypted group-text packet can include a displayed sender."); @@ -990,7 +990,7 @@ if (!typeMatches(rule.type, packet.type)) misses.push(`payload type ${packet.type} is outside ${rule.type}`); const [minimum, maximum] = hopBounds(rule.hops); if (packet.hops < minimum || packet.hops > maximum) misses.push(`hop ${packet.hops} is outside ${rule.hops}`); - if (rule.channel && rule.channel !== packet.channel) misses.push("authenticated channel differs or is unavailable"); + if (rule.channel && rule.channel !== packet.channel) misses.push("channel differs or is unavailable"); if (!incomingMatches(rule.incoming, packet)) misses.push(`original scope does not satisfy ${rule.incoming}`); if (rule.pathKind === "prefix") { const wanted = rule.pathPrefix.split(","); @@ -1125,9 +1125,9 @@ ]), blackhole: Object.freeze([ { - ...defaultRule("blackhole-after-hop-3"), + ...defaultRule("blackhole-unscoped-rgdata"), type: "grp_data", - hops: "4+", + hops: "all", channel: "#rgdata", incoming: "none", priority: 100, @@ -1152,14 +1152,6 @@ burst: 10, }, ]), - channel_stop: Object.freeze([ - { - ...documentedDropRule("rgdata-short-hop-stop", "grp_data", "0-2", 200), - channel: "#rgdata", - verdict: "continue", - stop: "policy", - }, - ]), high_traffic: Object.freeze([ documentedDropRule("limit-req", "req", "3+"), documentedDropRule("limit-response", "response", "9+"), diff --git a/_stylesheets/filter_tool.css b/_stylesheets/filter_tool.css index 85067dd6..a4203eea 100644 --- a/_stylesheets/filter_tool.css +++ b/_stylesheets/filter_tool.css @@ -75,6 +75,24 @@ font-size: 0.72rem; } +.filter-example-primer { + flex: 1 0 100%; + padding: 0.6rem 0.7rem; + border-radius: 0.4rem; + background: var(--filter-soft); +} + +.filter-example-primer p { + margin: 0; + color: color-mix(in srgb, var(--md-default-fg-color) 76%, transparent); + font-size: 0.72rem; + line-height: 1.45; +} + +.filter-example-primer p + p { + margin-top: 0.35rem; +} + .filter-example-grid { display: grid; flex: 1 0 100%; diff --git a/filter_tool/index.html b/filter_tool/index.html index 4910a14a..961100c4 100644 --- a/filter_tool/index.html +++ b/filter_tool/index.html @@ -1041,10 +1041,9 @@

Filter policy playground

-

Design and test policies for the proposed ground-up MeshCore forwarding engine. -The playground models phased evaluation, immutable receive-time matches, -explicit priority and stop behavior, ACL ownership, compact typed conditions, -and accumulated forwarding decisions.

+

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.

@@ -1058,67 +1057,82 @@ drafts are not uploaded anywhere.

Build a policy

-

The presets below reproduce common examples from -Flood Filtering and Moderation in the proposed rule model.

+

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.

Remote login and direct routes

- This policy controls flood retransmission only. Direct packets carry a - supplied route and stay outside the filter, matching today's firmware. - Local packet delivery also happens independently of the relay decision. - Rules that can limit relayed REQ, RESPONSE, TXT_MSG, ANON_REQ, or PATH - traffic receive a prominent warning because they can still reduce - multi-hop remote-login reach. The analyzer warns instead of silently - exempting those floods, because an exemption would make the documented - high-traffic rules behave differently. + 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.

- Drop-in replacements for documented settings - Choose one to load its proposed-engine equivalent. + 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. + hops=3+ means the rule applies at a received hop count of + three or more. +

+

+ type=grp_data matches one payload type. + type=any matches every payload. + type=class:group matches group text and data; + type=class:login matches REQ, RESPONSE, TXT_MSG, ANON_REQ, + and PATH; type=class:other matches everything else. +

+

+ channel=, rx.scope=, path=, and + tempradio= further narrow a match. After do, + drop prevents retransmission, scope= sets the + outgoing transport scope, rate= limits matches per minute, + and timing= selects the schedule. +

-
@@ -1165,7 +1179,7 @@ drafts are not uploaded anywhere.