- Sashité for Developers
- Nostr
- NIPs
- Adjudication Request
NIP-XX
Adjudication Request
draft optional
This NIP defines a Nostr event kind for invoking the designated arbiter of a chess-family session to issue a ruling. The Adjudication Request is signed by one of the two players of the session and triggers the arbiter to examine the natural state of relevant events and produce an Adjudication (defined separately).
Abstract
Defines kind: 3424, a regular event by which one of the two players in a session formally asks the designated arbiter to render a verdict on the session. The event references the Game Session (kind 3422) and the arbiter. The arbiter examines the natural state of events and responds with an Adjudication.
The Adjudication Request carries no claims or accusations. The arbiter rules on what is signed and published, not on what the invoker asserts.
Motivation
A session in the chess family terminates when the designated arbiter renders a binding ruling. Players cannot self-judge: a “checkmate” is a position recognized by the rule system, not a claim made by a player; a “timeout” is the elapsed time according to the time-control accounting, not an accusation.
The Adjudication Request is the mechanism by which a player asks the arbiter to look at the session and produce an Adjudication. The request is intentionally minimal: it carries the session identity and the arbiter’s pubkey. The arbiter, having received the request, examines the natural state of the session (Game Session plus the chain of Ply events) and renders a verdict.
Representative use cases
The Adjudication Request mechanism addresses several distinct lifecycle situations in arbitered sessions:
- Natural termination ratification: a player believes the rule system has terminated the session (checkmate, stalemate, repetition, etc.) and asks the arbiter to formalize the verdict.
- Timeout recognition: a player believes the opponent has exceeded their time-control budget and asks the arbiter to rule a timeout.
- Resignation formalization: a player wishes to resign and invokes the arbiter; the arbiter’s ruling reflects the resignation per the rule system’s termination conventions.
- Abandonment recovery: when one player stops responding (whether by accident, network failure, deliberate refusal, or any other reason), the other player can invoke the arbiter to rule on the session. The arbiter’s ruling — typically a
timeout, or such other status as the arbiter deems appropriate per the rule system — terminates the session and unblocks the active player. This is the principal protocol-level mechanism for resolving abandonment. - Disputed move recognition: the arbiter’s ruling resolves a disputed position (e.g., a contested claim of threefold repetition).
In all cases, the request is informational from the arbiter’s perspective: the arbiter rules on the natural state of the events, not on the invoker’s claims about that state.
Preconditions
An Adjudication Request references the session’s Game Session (kind 3422) directly. This structurally enforces the precondition that the session is initialized: a request that cannot reference a valid Game Session is non-conforming per constraint 2 (§Semantic constraints) and MUST be ignored. See kind 3422 §Handling a silent arbiter for the recommended client behavior when no Game Session has been published.
Specification
Event kind
kind: 3424
Adjudication Request events are regular events per NIP-01: immutable once signed and broadcast.
Operating mode
Every session has a designated arbiter (per the session’s founding context — kind 3422 §Signing party). This NIP defines the mechanism by which a player invokes that arbiter to issue a ruling. The Adjudication Request references the session’s Game Session (kind 3422). The arbiter — the signer of that Game Session — is identified by matching the p tag’s pubkey against the Game Session’s pubkey field.
Attestation by the designated timestamper (attested mode)
This section applies in attested mode. In self-timed mode the Adjudication Request’s canonical timing is its own created_at, established by acceptance at one of the session’s designated timing relays (Canonical Timing §Canonical timing of an event).
The designated timestamper publishes an Event Timestamp Attestation (kind 3410) referencing this Adjudication Request via the required attests-marked e tag. Its created_at is then the Request’s canonical timing for any consumer reasoning about invocation order (e.g., distinguishing which of two competing Requests came first).
The structure of the Adjudication Request Attestation is:
["e", "<adjudication_request_event_id>", "<relay_hint>", "attests"]
["e", "<game_session_event_id>", "<relay_hint>", "<app>:session"]
The second e tag carries an application-namespaced discovery marker <app>:session referencing the Game Session (the reference timestamper uses sashite:session), mirroring the pattern used for per-Ply attestations — and, as there, the designated timestamper MUST include it (kind 3423 §Time accounting). NIP-26-delegated signatures from the timestamper are NOT accepted as authoritative.
Note: this NIP does not subject the Adjudication Request to race resolution. The protocol explicitly allows multiple Adjudication Requests per session. The arbiter MAY select any conforming Request as the triggered_by reference of their Adjudication (kind 3425); canonical timing provides authoritative ordering but no canonical “winner” — the Request defines no slot in the sense of Canonical Timing §Meta-resolution.
This selection is verdict-relevant — the chosen Request fixes the natural-state cutoff (kind 3425 §Natural state of events at adjudication), and two Requests can yield different verdicts — so arbiters SHOULD publish a deterministic selection policy (e.g., the earliest canonically timed conforming Request first — the reference arbiter’s rule). The selection is not a conformance condition of the resulting Adjudication.
The Adjudication Request’s own created_at is informational only and MUST NOT be used for any timing-dependent decision.
Tags
Reference tags
| Tag | Cardinality | Value | Description |
|---|---|---|---|
e game_session |
exactly one | event id, optional relay hint, marker | reference to the Game Session (kind 3422) for this session |
The e tag MUST be differentiated by a marker as the fourth element:
["e", "<game_session_event_id>", "<relay_hint>", "game_session"]— the Game Session event (kind3422) for this session. Exactly one such tag is required.
The relay hint (third element) is OPTIONAL but SHOULD be present.
Player tag
| Tag | Cardinality | Value | Description |
|---|---|---|---|
p |
exactly one | pubkey, optional relay hint, role marker | the designated arbiter, with role marker arbiter |
The p tag MUST carry the arbiter role marker as its fourth element:
["p", "<arbiter_pubkey>", "<relay_hint>", "arbiter"]
The relay hint (third element) is OPTIONAL but SHOULD be present. When omitted, an empty string MAY be used in its position.
The p tag serves a dual purpose: semantic (identifying the arbiter) and structural (notification routing via standard Nostr #p filters).
Lifecycle tag
| Tag | Cardinality | Value | Description |
|---|---|---|---|
nonce |
exactly one | nonce + difficulty | NIP-13 proof of work |
The nonce tag follows NIP-13.
Content
The content field MUST be the empty string ("").
The Adjudication Request carries no narrative payload: the arbiter rules on what is signed and published, not on what the invoker asserts. Any non-empty content would either be ignored (creating a misleading impression of relevance) or, if a future client parsed it, introduce a side channel for claims that have no normative weight. Forcing the empty string removes this ambiguity.
The empty invocation forces a corresponding requirement on the arbiter: since an invocation asserts nothing, the arbiter’s status vocabulary MUST be decidable from the published events alone — every verdict the arbiter can reach is a function of the natural state and the session’s public events, never of who invoked, why, or of any out-of-band claim. A vocabulary satisfying this requirement makes every conforming, canonically timed invocation interpretable without application-specific context (the reference rule system’s supporting document, Statuses — Sanki, is one conforming vocabulary; its residual-resignation rule guarantees that such an invocation always yields a verdict).
Players who wish to communicate context to the arbiter SHOULD do so out of band; this NIP intentionally provides no in-band channel for such communication.
Semantic constraints
A conforming Adjudication Request event MUST satisfy all of the following:
- The event contains exactly one
game_session-markedetag. - The
game_sessionetag references a retrievable, signature-valid, conforming Game Session event (kind3422, per its §Semantic constraints) that is the canonical Game Session for its founding (kind3422§Idempotence and race resolution). - The event’s
pubkey(the invoker) MUST match the pubkey of one of theplayer-markedptags in the referenced Game Session (i.e., the invoker is one of the session’s players). - The event’s
ptag (carrying thearbiterrole marker as its fourth element) MUST be exactly one, and its pubkey MUST match thepubkeyof the referenced Game Session (the arbiter who signed it). - Exactly one
noncetag is present, carries its committed difficulty as its third element, and the event id satisfies NIP-13 against that committed difficulty — never against a relay’s advertised minimum (an ingestion policy, not conformance). - The
contentfield is the empty string ("").
Constraints 1, 5, and 6 are checkable from the event alone. Constraints 2–4 require cross-event validation against the referenced Game Session.
Validation responsibility
Validation of an Adjudication Request against the semantic constraints (§Semantic constraints) is the responsibility of the client, the relay, and the arbiter. A relay additionally enforces its advertised NIP-13 minimum difficulty at ingestion — a relay policy, distinct from conformance.
The arbiter MAY refuse to act on an Adjudication Request that fails the semantic constraints. Such refusal is communicated by the arbiter not publishing a corresponding Adjudication. This NIP does not define an explicit refusal event.
Examples
The examples below use placeholder pubkeys, event IDs, relay URLs, and timestamps for illustration.
Example 1 — Invocation by the challenged player
Bob (the challenged player) requests adjudication:
{
"kind": 3424,
"pubkey": "<bob_pubkey>",
"created_at": 1700005000,
"tags": [
["e", "<game_session_event_id>", "wss://relay.example.com", "game_session"],
["p", "<carol_pubkey>", "wss://relay.example.com", "arbiter"],
["nonce", "73219", "16"]
],
"content": "",
"id": "...",
"sig": "..."
}
The arbiter, on receiving this request, examines the natural state of events and produces an Adjudication.
Example 2 — Invocation by the challenger
Alice (the challenger) requests adjudication:
{
"kind": 3424,
"pubkey": "<alice_pubkey>",
"created_at": 1700001000,
"tags": [
["e", "<game_session_event_id>", "wss://relay.example.com", "game_session"],
["p", "<carol_pubkey>", "wss://relay.example.com", "arbiter"],
["nonce", "11337", "16"]
],
"content": "",
"id": "...",
"sig": "..."
}
The arbiter examines the natural state of events and rules accordingly.
Client guidelines
Clients implementing kind: 3424 SHOULD:
- Subscribe to kind
3424events with a#pfilter on the user’s pubkey to receive Adjudication Requests addressed to the user as arbiter. - Subscribe to kind
3424events with an#efilter on the user’s Game Session event IDs to receive notifications of invocations on the user’s own sessions. - Validate received Adjudication Request events against the semantic constraints (§Semantic constraints) before treating them as actionable. In particular, reject any event whose
contentis non-empty. - Set the
contentfield to the empty string when publishing a request; do not offer a UI affordance for attaching a message.
Security considerations
-
Signatures: Adjudication Request events are signed by the invoker. The arbiter MUST verify signatures per NIP-01 before treating the request as actionable.
-
Proof of work: The
noncetag follows NIP-13 and protects the arbiter from spam invocations. Relays SHOULD enforce a minimum difficulty appropriate to their policy. The nonce values shown in this NIP’s examples are illustrative placeholders; real implementations compute the nonce via proof-of-work brute force until the event ID achieves the target leading-zero-bit difficulty. -
Cross-event validation: An Adjudication Request is meaningful only in conjunction with its referenced Game Session (kind
3422). The arbiter MUST retrieve and validate this reference before issuing a ruling. -
No claims, no accusations: The Adjudication Request carries no claims, accusations, or asserted outcomes. The arbiter rules based on the natural state of signed and published events. The
contentfield is forced to the empty string (§Content) to remove any in-band channel that could be mistaken for a structured claim. -
Multiple invocations: A session MAY receive multiple Adjudication Request events (e.g., both players invoke independently, or one player invokes from multiple client instances). The arbiter selects one as the
triggered_byof their verdict and rules on the natural state of events at that Request’s cutoff. The selection is verdict-relevant; arbiters SHOULD publish a deterministic policy (see §Attestation by the designated timestamper). -
Arbiter availability: This NIP does not provide a mechanism for the arbiter to acknowledge receipt of a request. An invocation that receives no corresponding Adjudication may be due to an arbiter that is offline, overloaded, or has rejected the request as malformed.
-
Invocation timing: In attested mode, the Adjudication Request’s own
created_atis the invoker’s claim and is not authoritative; the arbiter relies on the Request’s canonical timing — the Event Timestamp Attestation (kind3410) signed by the designated timestamper. In self-timed mode, the canonical timing IS the Request’s owncreated_at, made non-backdatable by the designated timing relay. Either way, the arbiter’s observation of the request’s arrival is implicit in the Verdict (via thetriggered_byreference). -
Arbitration scope: This NIP does not define the ruling itself. The arbiter’s response — including the result format and finality semantics — is defined in the Adjudication NIP (kind
3425).
References
- NIP-01 — Basic protocol flow description
- NIP-13 — Proof of Work
- Kind
3422— Game Session (the session being adjudicated) - Kind
3425— Adjudication (the arbiter’s verdict, triggered by this Request) - Event Timestamp Attestation — primitive for the Adjudication Request’s attestation (attested mode)
- Canonical Timing — canonical timing and meta-resolution (kind
3424is timed but defines no slot)
