mirror of
https://github.com/nostr-protocol/nips.git
synced 2026-07-22 07:48:25 +00:00
C1: expand to any event kind, add d+a tag requirements, client backlink verification
This commit is contained in:
101
C1.md
101
C1.md
@@ -6,7 +6,7 @@ Collaborative Ownership
|
||||
|
||||
`draft` `optional`
|
||||
|
||||
This NIP defines a mechanism for multiple pubkeys to collaboratively maintain addressable events while preserving backwards compatibility.
|
||||
This NIP defines a mechanism for multiple pubkeys to collaboratively maintain events.
|
||||
|
||||
## Motivation
|
||||
|
||||
@@ -20,14 +20,14 @@ Certain applications require shared ownership where:
|
||||
|
||||
### Collaborative Pointer Event
|
||||
|
||||
A new addressable event kind `39382` serves as a pointer to collaboratively-owned content:
|
||||
An addressable event kind `39382` serves as a pointer to collaboratively-owned content:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"kind": 39382,
|
||||
"pubkey": "<creator-pubkey>",
|
||||
"tags": [
|
||||
["d", "<slug>"],
|
||||
["d", "<identifier>"],
|
||||
["k", "<target-kind>"],
|
||||
["p", "<owner-1-pubkey>"],
|
||||
["p", "<owner-2-pubkey>"],
|
||||
@@ -42,35 +42,65 @@ A new addressable event kind `39382` serves as a pointer to collaboratively-owne
|
||||
|
||||
| Tag | Required | Description |
|
||||
|-----|----------|-------------|
|
||||
| `d` | Yes | `<slug> |`
|
||||
| `k` | Yes | Target event kind |
|
||||
| `d` | Yes | Shared identifier for the collaborative content |
|
||||
| `k` | Yes | Target event kind (any kind) |
|
||||
| `p` | Yes | Owner pubkeys (one or more) |
|
||||
|
||||
The creator's pubkey is implicitly an owner and SHOULD NOT appear in `p` tags.
|
||||
|
||||
### Target Events
|
||||
|
||||
Any event kind MAY be a target of collaborative ownership. All target events:
|
||||
|
||||
- MUST include a `d` tag matching the pointer's `d` tag
|
||||
- MUST include an `a` tag referencing the `39382` pointer event
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"kind": <target-kind>,
|
||||
"pubkey": "<owner-pubkey>",
|
||||
"tags": [
|
||||
["d", "<identifier>"],
|
||||
["a", "39382:<pointer-creator-pubkey>:<identifier>"]
|
||||
],
|
||||
"content": "..."
|
||||
}
|
||||
```
|
||||
|
||||
The `d` tag is required regardless of whether the target kind is normally addressable. For addressable event kinds (30000-39999), the `d` tag serves its usual role. For all other kinds, the `d` tag enables grouping and correlation with the pointer.
|
||||
|
||||
### Resolution Algorithm
|
||||
|
||||
To resolve the current state of collaboratively-owned content:
|
||||
|
||||
1. Parse the `39382` pointer event to extract owners (`p` tags) and target kind (`k` tag)
|
||||
2. Extract the slug from the `d` tag (everything after the first `-`)
|
||||
3. Query: `{"kinds": [<target-kind>], "authors": [<all-owners>], "#d": ["<slug>"], "limit": 1}`
|
||||
2. Extract the identifier from the `d` tag
|
||||
3. Query: `{"kinds": [<target-kind>], "authors": [<all-owners>], "#d": ["<identifier>"]}`
|
||||
4. For addressable target kinds: return the event with the highest `created_at`
|
||||
5. For non-addressable target kinds: return all matching events that contain a valid `a` tag backlinking to the pointer
|
||||
|
||||
### Back-Reference
|
||||
### Initial Discovery
|
||||
|
||||
Target events MUST include an `a` tag pointing to the `39382` pointer:
|
||||
Clients that do not yet have any version of the event MUST query by `#d` tag alone or by known owner pubkeys.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"kind": 30023,
|
||||
"tags": [
|
||||
["d", "my-article"],
|
||||
["a", "39382:<pointer-creator-pubkey>:30023-my-article"]
|
||||
]
|
||||
}
|
||||
```
|
||||
## Client Behavior
|
||||
|
||||
This allows clients to discover collaborative ownership from either direction: pointer → content or content → pointer.
|
||||
### Co-Author Attribution
|
||||
|
||||
## Example
|
||||
Clients SHOULD NOT display co-author attribution for a target event unless:
|
||||
|
||||
1. The event contains an `a` tag referencing a `39382` pointer event, **and**
|
||||
2. The event's author pubkey appears in that pointer's `p` tags (or is the pointer's creator)
|
||||
|
||||
An event without a verifiable `a` tag backlink to a `39382` pointer MUST NOT be presented as collaboratively authored. This prevents spoofed co-authorship claims.
|
||||
|
||||
### Display Recommendations
|
||||
|
||||
- Clients SHOULD display which pubkey signed each version
|
||||
- Clients SHOULD indicate when an event is part of a collaborative set
|
||||
- Clients MAY show the full owner set from the pointer event alongside the signing pubkey
|
||||
|
||||
## Examples
|
||||
|
||||
### Pointer Event
|
||||
|
||||
@@ -81,7 +111,6 @@ This allows clients to discover collaborative ownership from either direction: p
|
||||
"tags": [
|
||||
["d", "collaborative-guide"],
|
||||
["k", "30023"],
|
||||
["p", "alice-pubkey"],
|
||||
["p", "bob-pubkey"],
|
||||
["p", "carol-pubkey"]
|
||||
],
|
||||
@@ -89,7 +118,7 @@ This allows clients to discover collaborative ownership from either direction: p
|
||||
}
|
||||
```
|
||||
|
||||
### Target Article (by any owner)
|
||||
### Addressable Target (kind 30023)
|
||||
|
||||
```jsonc
|
||||
{
|
||||
@@ -98,7 +127,21 @@ This allows clients to discover collaborative ownership from either direction: p
|
||||
"tags": [
|
||||
["d", "collaborative-guide"],
|
||||
["title", "A Collaborative Guide"],
|
||||
["a", "39382:alice-pubkey:30023-collaborative-guide"]
|
||||
["a", "39382:alice-pubkey:collaborative-guide"]
|
||||
],
|
||||
"content": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### Non-Addressable Target (kind 4199)
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"kind": 4199,
|
||||
"pubkey": "carol-pubkey",
|
||||
"tags": [
|
||||
["d", "collaborative-guide"],
|
||||
["a", "39382:alice-pubkey:collaborative-guide"]
|
||||
],
|
||||
"content": "..."
|
||||
}
|
||||
@@ -107,7 +150,13 @@ This allows clients to discover collaborative ownership from either direction: p
|
||||
### Client Resolution
|
||||
|
||||
1. Client receives `naddr` for the `39382` pointer
|
||||
2. Parses owners: `[alice, bob, carol]`
|
||||
3. Queries: `{"kinds": [30023], "authors": ["alice", "bob", "carol"], "#d": ["collaborative-guide"], "limit": 1}`
|
||||
4. Returns most recent version regardless of which owner published it
|
||||
2. Parses owners: `[alice, bob, carol]`, target kind: `30023`
|
||||
3. Queries: `{"kinds": [30023], "authors": ["alice", "bob", "carol"], "#d": ["collaborative-guide"]}`
|
||||
4. Filters results: only events with `["a", "39382:alice-pubkey:collaborative-guide"]` are considered collaborative
|
||||
5. Returns most recent version (for addressable kinds) or full set (for non-addressable kinds)
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- Owners can unilaterally modify content
|
||||
- An `a` tag backlink alone is insufficient — clients MUST verify the referenced pointer event includes the author in its `p` tags
|
||||
- Owner changes on the pointer event take effect immediately; old target events from removed owners are no longer authoritative
|
||||
|
||||
Reference in New Issue
Block a user