Files
DECNET/decnet/webhook/enums.py
anti f2b3393669 chore: relicense to AGPL-3.0-or-later and add SPDX headers
Replaces LICENSE (GPLv3 -> AGPLv3) and prepends
`SPDX-License-Identifier: AGPL-3.0-or-later` to every source file
across decnet/, decnet_web/, tests/, scripts/, and tools/.

Rationale: closes the GPLv3 ASP loophole so any party operating a
modified DECNET as a network service must offer their modified
source. Personal copyright (Samuel Paschuan) + inbound=outbound
contributions make a future unilateral relicense infeasible.

- LICENSE: full AGPL-3.0 text (gnu.org/licenses/agpl-3.0.txt)
- COPYRIGHT: project copyright notice
- tools/add_spdx_headers.py: idempotent header injector
  (shebang- and PEP 263-aware)

Touches 1565 source files (.py, .ts, .tsx, .js, .jsx, .css, .sh).
No behavior change; comments only.
2026-05-22 21:04:16 -04:00

56 lines
1.9 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-or-later
"""Simple-mode event enum → bus-topic pattern expansion.
The UI's Simple mode hides the NATS-style wildcard syntax behind three
friendly choices. Storage is always the expanded pattern list — the
enum exists only at the API boundary.
"""
from __future__ import annotations
# Patterns map to the bus topic hierarchy shipped by DEBT-031's worker
# rollout (see `decnet/bus/topics.py`):
# - attacker.{observed,fingerprinted,scored,session.started,session.ended}
# - decky.{id}.{state,traffic}
# - system.{log,<worker>.health,<worker>.control,bus.health}
SIMPLE_EVENT_PATTERNS: dict[str, list[str]] = {
"AttackerDetail": ["attacker.>"],
"DeckyStatus": ["decky.*.state", "decky.*.traffic"],
"SystemStatus": ["system.>"],
}
def expand_simple_events(names: list[str]) -> list[str]:
"""Flatten a list of simple-event names into their bus patterns.
Unknown names are silently dropped — the router layer validates
against the `SimpleEvent` Literal before calling us, so a bad value
here means a programming error elsewhere, not user input.
"""
out: list[str] = []
for n in names:
out.extend(SIMPLE_EVENT_PATTERNS.get(n, []))
return out
def merge_patterns(
simple: list[str] | None, advanced: list[str] | None
) -> list[str]:
"""Combine simple-event expansions with advanced raw patterns, deduped.
Order-preserving (simple expansions first, then advanced patterns in
the order the user supplied them) so operators see deterministic
patterns in API responses.
"""
seen: set[str] = set()
out: list[str] = []
for p in expand_simple_events(simple or []):
if p not in seen:
seen.add(p)
out.append(p)
for p in advanced or []:
if isinstance(p, str) and p and p not in seen:
seen.add(p)
out.append(p)
return out