relay event-kind allowlist rejects NIP-32 kind 1985 labels — request admission of 1985 or a CI-status kind
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Observed behaviour
The relay gates ingest on a closed event-kind allowlist. Publishing an event
whose kind is not in that list is rejected with:
```
restricted: unknown event kind
```
Concretely, against a current relay:
| Kind | Result |
|---|---|
| `1985` (NIP-32 label) | ❌ `restricted: unknown event kind` |
| `1111` (NIP-22 comment) | ❌ `restricted: unknown event kind` |
| `16` (generic repost) | ❌ `restricted: unknown event kind` |
| `1` (short text note) | ✅ accepted |
| `1617` (NIP-34 patch) | ✅ accepted |
| `1621` (NIP-34 issue) | ✅ accepted |
| `1630` / `1631` (NIP-34 status open / applied-merged) | ✅ accepted |
The allowlist is the `match` in `required_scope_for_kind` at
`crates/buzz-relay/src/handlers/ingest.rs` (the fallthrough arm returning
`"restricted: unknown event kind"` is the last arm of that match). The NIP-34
kinds are admitted a few arms above it via `KIND_GIT_PATCH`,
`KIND_GIT_PULL_REQUEST`, `KIND_GIT_ISSUE`, and `KIND_GIT_STATUS_*`, all mapped
to `Scope::MessagesWrite`.
## Use case
An external CI controller subscribes to relay-signed `kind:30618`
(`KIND_GIT_REPO_STATE`, NIP-34 repository state) events to learn when a
repository's refs have moved, runs checks against the new commits, and wants to
publish a machine-readable verdict **per commit** back to the same relay.
NIP-32 (`kind:1985`) is the natural fit: a label event carrying a namespace
(`L`) and a label value (`l`), targeting the commit id. It is exactly the
"third party asserts a typed judgement about an object" primitive, and it is
what other tooling in the ecosystem would look for.
Because 1985 is rejected, the only available workaround today is to **self-label
on `kind:1`** — publish a short text note and encode the verdict in its content
or tags. That is unsatisfying for the obvious reasons: it is not machine
readable without bespoke parsing, it cannot be filtered server-side by label
namespace, it pollutes the human-readable note timeline, and any other consumer
has to know the private convention.
The NIP-34 status kinds (`1630`–`1633`) are **not** a correct substitute. They
are defined as statuses *of a patch or issue* and expect a root `e` tag pointing
at a patch (`1617`) or issue (`1621`) event. A CI verdict about a commit that
arrived through a plain push has no patch or issue root to reference, so using
them would mean either fabricating a root event or emitting a status that is
semantically malformed. They also model a fixed open/applied/closed/draft
lifecycle rather than an extensible check namespace, so they cannot express
"check `build` reported `passing`" alongside "check `lint` reported `failing`".
## Ask
Either of:
1. **Admit `kind:1985` (NIP-32)** to the allowlist, presumably mapped to
`Scope::MessagesWrite` alongside the other NIP-34 kinds — or to a narrower
scope if labels warrant one. This is the smallest change and unlocks the
general labelling primitive for all consumers, not just CI.
2. **Define a CI / check-status kind** with explicit semantics for "an external
checker asserts a typed result about a commit", not requiring a patch or
issue root. This is more work but gives the relay a first-class concept it
can validate and index.
Option 1 is preferable if there is no appetite for a new kind, since it reuses
an existing NIP rather than inventing relay-specific vocabulary.
Happy to send a PR for whichever direction is preferred — the change to the
allowlist itself is small; the question is which scope (and whether any tag
validation) you would want attached to it.
Contributor guide
Assessment
This issue has not been assessed yet.