diff options
| author | fiatjaf_ <fiatjaf@gmail.com> | 2023-06-20 15:42:47 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-20 15:42:47 -0300 |
| commit | 3893fa7f7ce695a2d1cf75c556a2b4b2d0086619 (patch) | |
| tree | 50aad1568afca993e0942dee3e4bb0ebadd37f44 | |
| parent | 9ffd3638d77f278c7946ffe8f53bf0fb3d2933b2 (diff) | |
| parent | ece0dda45be1053f673216edb9d6cd8a92035757 (diff) | |
Merge pull request #532 from staab/nip-32-labeling
| -rw-r--r-- | 32.md | 126 | ||||
| -rw-r--r-- | 36.md | 9 | ||||
| -rw-r--r-- | 56.md | 15 | ||||
| -rw-r--r-- | README.md | 1 |
4 files changed, 145 insertions, 6 deletions
| @@ -0,0 +1,126 @@ | |||
| 1 | NIP-32 | ||
| 2 | ====== | ||
| 3 | |||
| 4 | Labeling | ||
| 5 | --------- | ||
| 6 | |||
| 7 | `draft` `optional` `author:staab` `author:gruruya` `author:s3x-jay` | ||
| 8 | |||
| 9 | A label is a `kind 1985` event that is used to label other entities. This supports a number of use cases, from distributed moderation and content recommendations to reviews and ratings. | ||
| 10 | |||
| 11 | Label Target | ||
| 12 | ---- | ||
| 13 | |||
| 14 | The label event MUST include one or more tags representing the object or objects being | ||
| 15 | labeled: `e`, `p`, `a`, `r`, or `t` tags. This allows for labeling of events, people, relays, | ||
| 16 | or topics respectively. As with NIP-01, a relay hint SHOULD be included when using `e` and | ||
| 17 | `p` tags. | ||
| 18 | |||
| 19 | Label Tag | ||
| 20 | ---- | ||
| 21 | |||
| 22 | This NIP introduces a new tag `l` which denotes a label, and a new `L` tag which denotes a label namespace. | ||
| 23 | A label MUST include a mark matching an `L` tag. `L` tags refer to a tag type within nostr, or a nomenclature | ||
| 24 | external to nostr defined either formally or by convention. Any string can be a namespace, but publishers SHOULD | ||
| 25 | ensure they are unambiguous by using a well-defined namespace (such as an ISO standard) or reverse domain name notation. | ||
| 26 | |||
| 27 | Namespaces starting with `#` indicate that the label target should be associated with the label's value. | ||
| 28 | This is a way of attaching standard nostr tags to events, pubkeys, relays, urls, etc. | ||
| 29 | |||
| 30 | Some examples: | ||
| 31 | |||
| 32 | - `["l", "footstr", "#t"]` - the publisher thinks the given entity should have the `footstr` topic applied. | ||
| 33 | - `["l", "<pubkey>", "#p"]` - the publisher thinks the given entity is related to `<pubkey>` | ||
| 34 | - `["l", "IT-MI", "ISO-3166-2"]` - Milano, Italy using ISO 3166-2. | ||
| 35 | - `["l", "VI-hum", "com.example.ontology"]` - Violence toward a human being as defined by ontology.example.com. | ||
| 36 | |||
| 37 | `L` tags containing the label namespaces MUST be included in order to support searching by | ||
| 38 | namespace rather than by a specific tag. The special `ugc` ("user generated content") namespace | ||
| 39 | MAY be used when the label content is provided by an end user. | ||
| 40 | |||
| 41 | `l` and `L` tags MAY be added to other event kinds to support self-reporting. For events | ||
| 42 | with a kind other than 1985, labels refer to the event itself. | ||
| 43 | |||
| 44 | Label Annotations | ||
| 45 | ----- | ||
| 46 | |||
| 47 | A label tag MAY include a 4th positional element detailing extra metadata about the label in question. This string | ||
| 48 | should be a json-encoded object. Any key MAY be used, but the following are recommended: | ||
| 49 | |||
| 50 | - `quality` may have a value of 0 to 1. This allows for an absolute, granular scale that can be represented in any way (5 stars, color scale, etc). | ||
| 51 | - `confidence` may have a value of 0 to 1. This indicates the certainty which the author has about their rating. | ||
| 52 | - `context` may be an array of urls (including NIP-21 urls) indicating other context that should be considered when interpreting labels. | ||
| 53 | |||
| 54 | Content | ||
| 55 | ------- | ||
| 56 | |||
| 57 | Labels should be short, meaningful strings. Longer discussions, such as for a review, or an | ||
| 58 | explanation of why something was labeled the way it was, should go in the event's `content` field. | ||
| 59 | |||
| 60 | Example events | ||
| 61 | -------------- | ||
| 62 | |||
| 63 | A suggestion that multiple pubkeys be associated with the `permies` topic. | ||
| 64 | |||
| 65 | ```json | ||
| 66 | { | ||
| 67 | "kind": 1985, | ||
| 68 | "tags": [ | ||
| 69 | ["L", "#t"], | ||
| 70 | ["l", "permies", "#t"], | ||
| 71 | ["p", <pubkey1>, <relay_url>], | ||
| 72 | ["p", <pubkey2>, <relay_url>] | ||
| 73 | ], | ||
| 74 | "content": "", | ||
| 75 | ... | ||
| 76 | } | ||
| 77 | ``` | ||
| 78 | |||
| 79 | A review of a relay. | ||
| 80 | |||
| 81 | ```json | ||
| 82 | { | ||
| 83 | "kind": 1985, | ||
| 84 | "tags": [ | ||
| 85 | ["L", "com.example.ontology"], | ||
| 86 | ["l", "relay/review", "com.example.ontology", "{\"quality\": 0.1}"], | ||
| 87 | ["r", <relay_url>] | ||
| 88 | ], | ||
| 89 | "content": "This relay is full of mean people.", | ||
| 90 | ... | ||
| 91 | } | ||
| 92 | ``` | ||
| 93 | |||
| 94 | Publishers can self-label by adding `l` tags to their own non-1985 events. | ||
| 95 | |||
| 96 | ```json | ||
| 97 | { | ||
| 98 | "kind": 1, | ||
| 99 | "tags": [ | ||
| 100 | ["L", "com.example.ontology"], | ||
| 101 | ["l", "IL-frd", "com.example.ontology"] | ||
| 102 | ], | ||
| 103 | "content": "Send me 100 sats and I'll send you 200 back", | ||
| 104 | ... | ||
| 105 | } | ||
| 106 | ``` | ||
| 107 | |||
| 108 | Other Notes | ||
| 109 | ----------- | ||
| 110 | |||
| 111 | When using this NIP to bulk-label many targets at once, events may be deleted and a replacement | ||
| 112 | may be published. We have opted not to use parameterizable/replaceable events for this due to the | ||
| 113 | complexity in coming up with a standard `d` tag. In order to avoid ambiguity when querying, | ||
| 114 | publishers SHOULD limit labeling events to a single namespace. | ||
| 115 | |||
| 116 | Before creating a vocabulary, explore how your use case may have already been designed and | ||
| 117 | imitate that design if possible. Reverse domain name notation is encouraged to avoid | ||
| 118 | namespace clashes, but for the sake of interoperability all namespaces should be | ||
| 119 | considered open for public use, and not proprietary. In other words, if there is a | ||
| 120 | namespace that fits your use case, use it even if it points to someone else's domain name. | ||
| 121 | |||
| 122 | Vocabularies MAY choose to fully qualify all labels within a namespace (for example, | ||
| 123 | `["l", "com.example.vocabulary:my-label"]`. This may be preferred when defining more | ||
| 124 | formal vocabularies that should not be confused with another namespace when querying | ||
| 125 | without an `L` tag. For these vocabularies, all labels SHOULD include the namespace | ||
| 126 | (rather than mixing qualified and unqualified labels). | ||
| @@ -9,12 +9,15 @@ Sensitive Content / Content Warning | |||
| 9 | The `content-warning` tag enables users to specify if the event's content needs to be approved by readers to be shown. | 9 | The `content-warning` tag enables users to specify if the event's content needs to be approved by readers to be shown. |
| 10 | Clients can hide the content until the user acts on it. | 10 | Clients can hide the content until the user acts on it. |
| 11 | 11 | ||
| 12 | `l` and `L` tags MAY be also be used as defined in [NIP-32](32.md) with the `content-warning` or other namespace to support | ||
| 13 | further qualification and querying. | ||
| 14 | |||
| 12 | #### Spec | 15 | #### Spec |
| 13 | 16 | ||
| 14 | ``` | 17 | ``` |
| 15 | tag: content-warning | 18 | tag: content-warning |
| 16 | options: | 19 | options: |
| 17 | - [reason]: optional | 20 | - [reason]: optional |
| 18 | ``` | 21 | ``` |
| 19 | 22 | ||
| 20 | #### Example | 23 | #### Example |
| @@ -26,6 +29,10 @@ options: | |||
| 26 | "kind": 1, | 29 | "kind": 1, |
| 27 | "tags": [ | 30 | "tags": [ |
| 28 | ["t", "hastag"], | 31 | ["t", "hastag"], |
| 32 | ["L", "content-warning"], | ||
| 33 | ["l", "reason", "content-warning"], | ||
| 34 | ["L", "social.nos.ontology"], | ||
| 35 | ["l", "NS-nud", "social.nos.ontology"], | ||
| 29 | ["content-warning", "reason"] /* reason is optional */ | 36 | ["content-warning", "reason"] /* reason is optional */ |
| 30 | ], | 37 | ], |
| 31 | "content": "sensitive content with #hastag\n", | 38 | "content": "sensitive content with #hastag\n", |
| @@ -32,6 +32,9 @@ being reported, which consists of the following report types: | |||
| 32 | 32 | ||
| 33 | Some report tags only make sense for profile reports, such as `impersonation` | 33 | Some report tags only make sense for profile reports, such as `impersonation` |
| 34 | 34 | ||
| 35 | `l` and `L` tags MAY be also be used as defined in [NIP-32](32.md) to support | ||
| 36 | further qualification and querying. | ||
| 37 | |||
| 35 | Example events | 38 | Example events |
| 36 | -------------- | 39 | -------------- |
| 37 | 40 | ||
| @@ -39,7 +42,9 @@ Example events | |||
| 39 | { | 42 | { |
| 40 | "kind": 1984, | 43 | "kind": 1984, |
| 41 | "tags": [ | 44 | "tags": [ |
| 42 | [ "p", <pubkey>, "nudity"] | 45 | ["p", <pubkey>, "nudity"] |
| 46 | ["L", "social.nos.ontology"], | ||
| 47 | ["l", "NS-nud", "social.nos.ontology"], | ||
| 43 | ], | 48 | ], |
| 44 | "content": "", | 49 | "content": "", |
| 45 | ... | 50 | ... |
| @@ -48,8 +53,8 @@ Example events | |||
| 48 | { | 53 | { |
| 49 | "kind": 1984, | 54 | "kind": 1984, |
| 50 | "tags": [ | 55 | "tags": [ |
| 51 | [ "e", <eventId>, "illegal"], | 56 | ["e", <eventId>, "illegal"], |
| 52 | [ "p", <pubkey>] | 57 | ["p", <pubkey>] |
| 53 | ], | 58 | ], |
| 54 | "content": "He's insulting the king!", | 59 | "content": "He's insulting the king!", |
| 55 | ... | 60 | ... |
| @@ -58,8 +63,8 @@ Example events | |||
| 58 | { | 63 | { |
| 59 | "kind": 1984, | 64 | "kind": 1984, |
| 60 | "tags": [ | 65 | "tags": [ |
| 61 | [ "p", <impersonator pubkey>, "impersonation"], | 66 | ["p", <impersonator pubkey>, "impersonation"], |
| 62 | [ "p", <victim pubkey>] | 67 | ["p", <victim pubkey>] |
| 63 | ], | 68 | ], |
| 64 | "content": "Profile is imitating #[1]", | 69 | "content": "Profile is imitating #[1]", |
| 65 | ... | 70 | ... |
| @@ -47,6 +47,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | |||
| 47 | - [NIP-28: Public Chat](28.md) | 47 | - [NIP-28: Public Chat](28.md) |
| 48 | - [NIP-30: Custom Emoji](30.md) | 48 | - [NIP-30: Custom Emoji](30.md) |
| 49 | - [NIP-31: Dealing with Unknown Events](31.md) | 49 | - [NIP-31: Dealing with Unknown Events](31.md) |
| 50 | - [NIP-32: Labeling](32.md) | ||
| 50 | - [NIP-33: Parameterized Replaceable Events](33.md) | 51 | - [NIP-33: Parameterized Replaceable Events](33.md) |
| 51 | - [NIP-36: Sensitive Content](36.md) | 52 | - [NIP-36: Sensitive Content](36.md) |
| 52 | - [NIP-39: External Identities in Profiles](39.md) | 53 | - [NIP-39: External Identities in Profiles](39.md) |