RFC: declarative event-kind registry to replace required_scope_for_kind (behavior-preserving; hardens 3 invariants)
- Lingua principale
- Rust
- Stelle
- 32.7k
- Fork
- 4.3k
- Merge medio
- 1g 13h
- PR unite (30g)
- 253
Descrizione
**Motivation**
Adding an event kind today means editing several central chokepoints in lockstep: `required_scope_for_kind` (a large match in `buzz-relay`), two disjoint boolean allowlists (`is_global_only_kind` / `requires_h_channel_scope`), `is_relay_only_kind`, and the `P_GATED_KINDS` / `AUTHOR_ONLY_KINDS` / `RESULT_GATED_KINDS` slices in `buzz-core` — plus a coupled `search_tsv`-NULL rule in the migrations. Two of these invariants are held only by runtime tests: the disjointness of the two scoping allowlists, and the read-gate ↔ storage (`search_tsv`-NULL) coupling. Both are easy to break silently, in the relay's authorization path. It's also the hardest part of the tree for a new contributor to extend safely, since a correct new kind must touch all of the above consistently.
**Proposed solution**
A declarative `KindDescriptor` registry (a small new leaf crate) holding each kind's policy — `{ required_scope, scoping, read_gate, authorship, extension }` — plus a `KindExtension` trait for the residue that isn't declarative (per-kind `authorize` / `validate`). The relay resolves every incoming event's policy through the registry instead of the match + allowlists + slices.
Key properties:
- **Dogfooded, not a plugin path.** Built-in kinds register through the same path — there's no privileged "core vs plugin" branch — so this is a pure refactor of the existing surface, not a new extension mechanism bolted on.
- **Hardens three invariants structurally.** Global-vs-channel becomes one `Scoping` enum, so double-classification is *unrepresentable* (the runtime disjointness test becomes redundant). Unknown-kind stays fail-closed (a registry miss reproduces the existing `"restricted: unknown event kind"` reject). The read-gate ↔ `search_tsv`-NULL coupling gets a single source that a golden test checks against the migration's generated-column kind list, instead of two hand-maintained lists that can drift.
- **Behavior-preserving.** The existing authorization tests are the acceptance bar and pass unchanged; storage/retrieval is already kind-agnostic, so most kinds need no extra code.
**Alternatives considered**
- Keep the central match (status quo) — the invariant fragility and contributor friction remain, and every new kind keeps paying the multi-site "fork tax."
- Config/env-driven kind allowlist — can't express the per-kind `authorize`/`validate` logic some kinds need (e.g. envelope validation, identity gates).
- WASM / dynamically-loaded plugins — far heavier and unnecessary; this stays compiled-in and object-safe (the `Pin>` pattern already used by `buzz-workflow`'s `ActionSink`), adding no runtime plugin machinery.
**Additional context**
We have a complete working implementation of this against a fork, verified behavior-preserving against the existing relay test-suite (the `required_scope_for_kind` matrix, the disjointness test, the p-gate/author-only/result-gated read-path tests, the FTS drift test). We'd upstream it as a focused, review-sized PR series — built-in kinds only, with no downstream-specific kinds — once the approach is acknowledged. Happy to adjust the shape (crate placement, trait surface, phasing) to your preferences before writing the PR.
Searched open issues and PRs for duplicates (kind registry / `required_scope_for_kind` / authorization refactor): none found.
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Inizia leggendo required_scope_for_kind e le allowlist correlate in buzz-relay, poi esamina le sezioni delle policy in buzz-core e la regola di migrazione per search_tsv. Confronta i test esistenti di autorizzazione, percorso di lettura e drift FTS indicati nell’issue. Il lavoro è completato quando è presente un refactoring del registry delle dimensioni di una review, che preserva il comportamento e copre con test gli invarianti indicati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- rust
- Ambito
- authorization, backend
- Tipo di issue
- Refactoring
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Tranquilla
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 30/100