Feature request: allowlist a new event kind (7373, audit-trail) for NIP-OA owner-attestation clients
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
Research direction
Start with CONTRIBUTING.md’s “How to Add a New Event Kind” recipe, then inspect crates/buzz-core/src/kind.rs and required_scope_for_kind() in crates/buzz-relay/src/handlers/ingest.rs. Follow the existing rejection test when adding coverage for kind 7373. Done means the constant and MessagesWrite scope are registered, the unit test passes, and the relay accepts and serves the event without persistence or indexing changes.
Written by the indexing model from the issue text.
Description
Motivation
NIP-OA (Owner Attestation) has no revocation primitive — an auth tag (["auth", owner_pubkey, conditions, sig]) is the only evidence that an owner authorized a pubkey, and today that evidence only survives as long as the authorized party keeps including it somewhere (e.g. embedded in their own kind:0 profile, as Buzz's own managed-agent flow does). If the authorized party never publishes it, or later drops it from a newer profile, nothing shows the grant ever happened — except the owner's own local client state, which isn't independently verifiable or portable across devices.
Anyone building a NIP-OA owner-attestation client that wants a durable, owner-controlled authorization history runs into this: they need to publish their own signed record of each mint/renew action, independent of whether the authorized party cooperates. That's what we're building in an external NIP-OA client, vouchd. Publishing this record against a buzz-relay instance currently fails:
OK false "restricted: unknown event kind"
required_scope_for_kind() in crates/buzz-relay/src/handlers/ingest.rs is a fixed match over known KIND_* constants with _ => Err("restricted: unknown event kind") as the catch-all — the audit kind we're using (7373) isn't among the matched constants, so the write is rejected regardless of correct signing/AUTH.
Proposed solution
Register the kind's required scope, following the existing "How to Add a New Event Kind" recipe in CONTRIBUTING.md — specifically just step 3:
// crates/buzz-core/src/kind.rs
pub const KIND_AUDIT_LOG: u32 = 7373;
// crates/buzz-relay/src/handlers/ingest.rs, required_scope_for_kind()
KIND_AUDIT_LOG => Ok(Scope::MessagesWrite),
7373 doesn't collide with anything currently in ALL_KINDS. This is intentionally scoped to step 3 only — no change requested to Buzz's own persistence, search indexing, or side-effect handling (steps 4–6); the event's payload and consumption logic live entirely client-side. The relay just needs to accept, store, and serve it back like any other regular event, the same way it already does for KIND_REPORT or other MessagesWrite-scoped kinds. Step 7 (audit) is already automatic per CONTRIBUTING.md, so no additional work there either.
Happy to submit the PR (with a unit test for required_scope_for_kind(7373, ...) alongside the existing rejection test) once the approach is confirmed. Also open to a different kind number if 7373 conflicts with an internal reservation we can't see from outside.
Alternatives considered
- Repurpose an already-allowlisted kind instead of a new one. Rejected — overloading an existing kind's semantics with unrelated audit-record content is exactly the kind of interop confusion NIP-31's
alt-tag guidance exists to avoid, and it'd make the audit events indistinguishable from whatever that kind normally means. - Keep the audit trail purely client-side (local browser storage), never publish to any relay. Avoids touching Buzz at all, but gives up the two properties we actually need — independent verifiability by a third party, and portability across the owner's own devices/clients. The record's existence would depend entirely on one browser's local state.
- Fork
buzz-relayand carry a local patch. Considered and set aside. The change is small and generic — it isn't tied to any vouchd-specific product logic, it's the same "add a new kind" pattern already merged repeatedly (kind:30179,kind:30621,kind:30178, etc.), andbuzzis a very actively developed monorepo (~20 commits/day) — maintaining a fork just to carry a one-linematcharm indefinitely seemed like a worse trade-off than asking upstream for something the project's own contribution docs already anticipate.
Additional context
- Relevant source:
crates/buzz-relay/src/handlers/ingest.rs(required_scope_for_kind),crates/buzz-core/src/kind.rs(KIND_*constants,ALL_KINDS),CONTRIBUTING.md§ "How to Add a New Event Kind". - The client this is blocking: github.com/mxx/vouchd — a browser-only NIP-OA owner-attestation panel that talks to a relay directly over WebSocket.
- Prior art for this exact shape of change:
feat(relay): accept kind:30179 private managed-agent events at ingest (#5133),feat(relay): accept kind:30621 multi-repo projects at ingest (#3171),feat(relay): gate kind 30178 team-catalog reads behind the shared tag (#3358). - Open question for maintainers: would you rather review this as a one-off kind addition (matching the precedent above), or is it more useful to define a small reserved sub-range for external/ecosystem-defined kinds, so future NIP-OA-adjacent tools don't need a fresh issue each time? No strong preference either way — happy to follow whichever fits Buzz's own conventions.
Before opening: searched open issues and PRs for event kind, required_scope_for_kind, ingest.rs, restricted: unknown event kind, audit trail / audit log, NIP-OA + audit, and add support for kind / accept kind. No open duplicate found. The one loosely-related open issue is #4937 ("relay: on closed relays, a direct-member agent loses its NIP-OA identity") — it also touches NIP-OA handling in buzz-relay, but it's a different bug (rate-limiting/owner-context loss for direct members), not about kind allowlisting or an audit trail, so not linking it as a duplicate.
- Dominant language
- Rust
- Stars
- 33.7k
- Forks
- 4.4k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 239
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from block/buzz
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
workflow_sink's mention parser never masks code regions — @name inside a code span wakes the agent Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 Half a day Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100