4A — Nostr Event Kind Assignments
Status: Proposed (2026-04-24). Subject to NIP discussion. Treat as draft until a NIP reservation lands. Parent: 4A README
Summary
4A defines five Nostr event kinds for knowledge objects and one commons declaration. All are addressable (NIP-01 parameterized-replaceable, 30000–39999 range) so authors can revise their knowledge without rewriting history, and consumers can address an object by (pubkey, kind, d-tag) triple.
| Kind | Name | Purpose | Replaceability |
|---|---|---|---|
| 30500 | fa:Observation |
A memory — an agent's observation about the world, with provenance | Addressable by d |
| 30501 | fa:Claim |
A stated proposition with citations | Addressable by d |
| 30502 | fa:Entity |
A thing — person, organization, place, codebase, concept | Addressable by d |
| 30503 | fa:Relation |
A reified relationship between two entities | Addressable by d |
| 30504 | fa:Commons |
A pubkey declaring itself the commons for a topic or project | Addressable by d (topic slug) |
| 30506 | fa:Score |
A signed, weighted opinion about a target 4A object | Addressable by d (target event id) |
| 30507 | fa:Comment |
A signed prose response targeting any 4A event | Addressable by d (per-comment slug) |
| 30510 | fa:EncryptedObservation |
Audience-addressed Observation (NIP-44 v2 to epoch pubkey) | Addressable by d |
| 30511 | fa:EncryptedClaim |
Audience-addressed Claim | Addressable by d |
| 30512 | fa:EncryptedEntity |
Audience-addressed Entity | Addressable by d |
| 30513 | fa:EncryptedRelation |
Audience-addressed Relation | Addressable by d |
| 30514 | fa:EncryptedCommons |
Audience-addressed Commons | Addressable by d |
| 30520 | fa:Audience |
Audience declaration: identity, current epoch, public roster | Addressable by d (audience slug) |
| 30521 | fa:KeyGrant |
NIP-44 v2 ciphertext delivering an audience epoch private key to one recipient | Addressable by composite d (audience-slug:epoch:recipient-hex) |
| 30522 | fa:AudienceClaim |
Off-band claim signed by an invite throwaway key, requesting a real key-grant | Addressable by composite d (audience-slug:epoch:invite-pub-hex) |
These numbers are placeholders chosen from an apparently unreserved block in the 30000 range. Before v0 ships the spec should either (a) submit a NIP reserving the block or (b) pick the first five contiguous unassigned slots in 30000–39999 after a fresh registry check against nostr-protocol/nips.
Known constraints that narrowed the choice:
- 30000–30099 is actively used for follow sets, relay sets, bookmark sets, curation sets.
- 30017–30030 covers stalls, products, long-form content, emoji sets.
- 30078 is "application-specific data" — overloaded but in use.
- 39000–39009 is NIP-29 group metadata. Do not use this range despite superficial cuteness.
The 30500–30509 block reads unassigned at the time of writing. Reserve 30500–30519 to leave room for post-v0 kinds (pin declarations, aggregator rollups, response/reply objects) without fragmentation. Kinds 30506 (fa:Score) and 30507 (fa:Comment) are now defined; see SPEC.md § Credibility events for normative shape, paired-rationale rules, and supersession behavior.
The encrypted-variant block (30510–30514) and the v0.5 audience block (30520, 30521, 30522) were assigned by SPEC-v0.5.md. The 30523–30529 range is reserved for future v0.5 audience-side metadata kinds; see SPEC-v0.5.md § 8.
The 30530–30539 range is reserved for Sonata Studio kinds (fa:StudioCard, fa:StudioTrack, fa:StudioDispatchIntent, fa:StudioComment, fa:StudioQuestion, fa:StudioAnswer, fa:StudioRoom, plus headroom). Studio is a 4A application built on top of v0.5 audiences — the kinds carry Studio-specific JSON-LD payloads (context: https://sonata.4a4.ai/ns/studio-v0) and are always audience-addressed (NIP-44 to the epoch pubkey, NIP-17 gift-wrapped per member). Normative shapes will be specified by the forthcoming studio-v0 spec; this reservation only holds the kind block so v0.5-era work doesn't squat on it. See sonata-studio-v0-design.md for the application-level design.
Required tags
Every 4A event carries these in addition to the Nostr envelope:
| Tag | Required | Value | Purpose |
|---|---|---|---|
d |
yes (all kinds) | stable addressable slug | Parameterized-replaceable key |
blake3 |
yes | BLAKE3 CID of the content payload, base32 encoded with bk- prefix |
Content addressing, payload integrity |
alt |
yes | one-line human-readable summary | NIP-31 fallback for clients that don't recognize the kind |
fa:context |
recommended | https://4a4.ai/ns/v0 (or pinned version) |
Quick check before parsing content |
Optional tags
| Tag | Repeatable | Value | Purpose |
|---|---|---|---|
t |
yes | topic slug (e.g. rails, next.js, postgres) |
Hashtag-style classification |
l |
yes | NIP-32 label (e.g. 4a.credibility.rails, 4a.stamp.github, 4a.sponsor) |
Credibility, stamps, sponsorship |
e |
yes | event id | Citation of a Nostr event (by id) |
a |
yes | kind:pubkey:d pointer |
Citation of an addressable 4A object |
p |
yes | pubkey | Reference to another author (sponsorship, attribution) |
arweave |
once | Arweave tx id | Permanence pin, if published to Irys/Arweave |
expiration |
once | unix timestamp | NIP-40 expiration for time-bounded objects |
Kind details
30500 — fa:Observation
A memory. The agent observed something about the world and is recording it with provenance.
{
"kind": 30500,
"tags": [
["d", "next.js-app-router-cookies-pitfall-v1"],
["blake3", "bk-QmExample..."],
["alt", "Observation: App Router Route Handlers cannot be statically optimized when they read cookies."],
["fa:context", "https://4a4.ai/ns/v0"],
["t", "next.js"],
["t", "app-router"],
["l", "4a.credibility.next.js", "self"]
],
"content": "{\"@context\":\"https://4a4.ai/ns/v0\",\"@type\":\"Observation\",...}"
}
content JSON-LD shape: @type: Observation with agent, observationDate, observationAbout, measuredProperty, value, and optional prov:wasDerivedFrom for source URLs.
30501 — fa:Claim
A proposition. A claim differs from an observation in that it makes an assertion about what is true, and it typically carries citations to observations or other claims.
{
"kind": 30501,
"tags": [
["d", "next.js-routes-no-static-opt-with-cookies-v1"],
["blake3", "bk-..."],
["alt", "Claim: Next.js 15 disables static optimization for any route that reads cookies."],
["fa:context", "https://4a4.ai/ns/v0"],
["t", "next.js"],
["a", "30500:npub1abc...:next.js-app-router-cookies-pitfall-v1"]
],
"content": "{\"@context\":\"https://4a4.ai/ns/v0\",\"@type\":\"Claim\",\"citation\":[...]}"
}
content JSON-LD shape: @type: Claim with author, datePublished, about, appearance, and citation (an array of 4A object references).
30502 — fa:Entity
A thing. Entities are the nouns the rest of the network refers to — a codebase, a person, an organization, a concept. Typically stable; revisions are uncommon.
{
"kind": 30502,
"tags": [
["d", "github.com/vercel/next.js"],
["blake3", "bk-..."],
["alt", "Entity: Next.js (TypeScript framework)"],
["fa:context", "https://4a4.ai/ns/v0"]
],
"content": "{\"@context\":\"https://4a4.ai/ns/v0\",\"@type\":[\"Thing\",\"SoftwareSourceCode\"],\"@id\":\"https://github.com/vercel/next.js\",\"name\":\"Next.js\",\"codeRepository\":\"https://github.com/vercel/next.js\",\"programmingLanguage\":\"TypeScript\"}"
}
content JSON-LD shape: @type is Thing with one or more Schema.org subtype hints (Person, Organization, Place, CreativeWork, SoftwareSourceCode).
The d tag is the canonical identifier for the entity — typically a URL, DID, or stable slug. This is how other 4A objects reference it via a tags.
30503 — fa:Relation
A reified relationship. Use when the relationship itself needs provenance or time-bounding (start/end dates, attestor, citations). For lightweight relationships, prefer bare JSON-LD properties inside an Entity payload.
{
"kind": 30503,
"tags": [
["d", "tj-holowaychuk-maintainer-express-2009"],
["blake3", "bk-..."],
["alt", "Relation: TJ Holowaychuk was maintainer of expressjs/express starting June 2009"],
["fa:context", "https://4a4.ai/ns/v0"],
["a", "30502:npub...:tj-holowaychuk"],
["a", "30502:npub...:github.com/expressjs/express"]
],
"content": "{\"@context\":\"https://4a4.ai/ns/v0\",\"@type\":\"Role\",\"roleName\":\"maintainer\",\"subject\":{\"@id\":\"4a://entity/tj-holowaychuk\"},\"object\":{\"@id\":\"https://github.com/expressjs/express\"},\"startDate\":\"2009-06\"}"
}
content JSON-LD shape: @type: Role with roleName, subject, object, and optional startDate / endDate / prov:wasAttributedTo.
30504 — fa:Commons
A pubkey declaring itself a commons for a topic or project. Consumers subscribe to a commons the same way a Nostr user follows an account: pin the pubkey, filter events by its kinds.
{
"kind": 30504,
"tags": [
["d", "next.js"],
["blake3", "bk-..."],
["alt", "Commons: Next.js project — maintained architectural decisions, migration notes, common pitfalls."],
["fa:context", "https://4a4.ai/ns/v0"],
["t", "next.js"],
["p", "npub1-co-maintainer-1..."],
["p", "npub1-co-maintainer-2..."]
],
"content": "{\"@context\":\"https://4a4.ai/ns/v0\",\"@type\":\"Organization\",\"name\":\"Next.js Commons\",\"description\":\"Architectural decisions, migration notes, and common pitfalls for vercel/next.js.\",\"memberOf\":{\"@id\":\"https://github.com/vercel/next.js\"}}"
}
content JSON-LD shape: @type: Organization with name, description, memberOf pointing at the project entity.
The p tags list co-maintainers whose pubkeys are recognized as publishing to this commons.
30506 — fa:Score
A signed, weighted opinion about a target 4A object. The full normative shape, paired-rationale MUST, value-range MUST, content-addressing MUST, and aggregator obligations are in SPEC.md § Credibility events → Score event (kind:30506).
{
"kind": 30506,
"tags": [
["d", "9f8e7d6c5b4a39281706f5e4d3c2b1a0908070605040302010f0e0d0c0b0a090"],
["e", "9f8e7d6c5b4a39281706f5e4d3c2b1a0908070605040302010f0e0d0c0b0a090"],
["a", "30501:<author-pubkey>:next-jit-claim-1"],
["blake3", "bk-..."],
["alt", "score 0.82 of next-jit-claim-1"],
["fa:context", "https://4a4.ai/ns/v0"]
],
"content": "{\"@context\":\"https://4a4.ai/ns/v0\",\"@type\":\"Score\",\"value\":0.82,\"tier\":\"verified\",\"target\":{\"@id\":\"nostr:9f8e7d6c…\"}}"
}
d is the target event id, so (scorer-pubkey, 30506, target-event-id) is unique per scorer per target. Latest write wins.
30507 — fa:Comment
A signed prose response targeting any 4A event, including claims, scores, attestations, and other comments. The full normative shape and recursive-commenting rules are in SPEC.md § Credibility events → Comment event (kind:30507).
{
"kind": 30507,
"tags": [
["d", "justify-score-9f8e7d6c-1"],
["e", "<target-score-event-id>"],
["a", "30506:<scorer-pubkey>:9f8e7d6c…"],
["blake3", "bk-..."],
["alt", "rationale for score 0.82 of claim 9f8e7d6c…"],
["fa:context", "https://4a4.ai/ns/v0"]
],
"content": "{\"@context\":\"https://4a4.ai/ns/v0\",\"@type\":\"Comment\",\"intent\":\"justify\",\"body\":\"...\",\"target\":{\"@id\":\"nostr:<target-event-id>\"}}"
}
A comment paired with a score MUST be authored by the same pubkey, MUST e-tag the score's event id, and MUST land within a 24-hour window of the score; aggregators MUST treat unjustified scores as weight-zero.
Consumption
An MCP gateway subscribes to a chosen set of relays with filters like:
[
"REQ",
"4a-observations",
{
"kinds": [30500, 30501, 30502, 30503, 30504],
"#fa:context": ["https://4a4.ai/ns/v0"]
}
]
Clients that don't recognize 4A kinds fall back to the alt tag for a human-readable summary. Clients that understand the kinds parse content as JSON-LD against the 4A context.
Reserved but unused
Leave these slots unclaimed pending experience:
- 30505 and 30508–30509 — pin declarations, aggregator rollups, response/reply objects, disputes. Design after v0 adoption data. (Kinds 30506 and 30507 are now defined for
ScoreandCommentrespectively.) - 30515–30519 — further post-v0 kinds.
- 30523–30529 — future v0.5 audience-side metadata events (rotation announcements, audience-scoped credibility wrappers, audience subscription endorsements). Implementations MUST NOT publish in this range until a successor SPEC defines specific semantics. See
SPEC-v0.5.md§ 8.
The encrypted-variant block 30510–30514 and the audience-management kinds 30520, 30521, 30522 are now defined by SPEC-v0.5.md. Implementations MUST follow that spec when publishing in those ranges.
Open questions for the NIP submission
- Should 4A kinds live in the 30000-range alongside other addressable objects, or should the submission propose a dedicated block (e.g. 30500–30519) with a formal reservation?
- Should the
fa:contexttag be mandatory, or is it sufficient to check thecontentfield? - Do we want a compact binary form of the JSON-LD payload for size-sensitive relays, or is JSON fine at v0 scale?
- Should
ObservationandClaimbe merged into a single kind with a discriminator field? Argument for merge: fewer kinds to reserve, simpler filters. Argument against: they serve different roles in reasoning and the JSON-LD shape differs.
Change log
- 2026-04-24 — initial draft. Kinds assigned tentatively; subject to NIP review.
- 2026-04-28 — Added kind 30506 (
fa:Score) and kind 30507 (fa:Comment) for Phase 3 credibility events. Normative shape lives inSPEC.md§ Credibility events. - 2026-04-28 — Confirmed encrypted-variant kinds 30510–30514 and assigned v0.5 audience-management kinds 30520 (
fa:Audience), 30521 (fa:KeyGrant), 30522 (fa:AudienceClaim). Reserved 30523–30529 for future v0.5 audience metadata. Normative shapes live inSPEC-v0.5.md.