Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-68 & NIP-69 - defined vocabulary for content warning & reporting (NIP-36 and NIP-56) #457

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
187 changes: 187 additions & 0 deletions 68.md
@@ -0,0 +1,187 @@
NIP-68
======

Content Labeling (including Reviews & Recommendations)
------------------------------------------------------

`draft` `optional` `author:s3x-jay` `author:rabble`

### Purpose

To provide a standardized way for content to be labeled both when it is published (by the author) or after the fact (by third parties or the original author).

## Labeling System

The labeling system defined here accommodates structured labeling from _any_ defined vocabulary, as well as free-form unstructured labeling.

### Structured labeling

Structured labels are made up of two parts:
- The code indicating which defined vocabulary is being used (referred to as `vocab` below)
- The code from the defined vocabulary (referred to as `code` below)

Both `vocab` and `code` must be short strings with no spaces. If the common name of a vocabulary has a space in it (e.g. ISO 3166-2) it shall be the convention to replace the space with a dash.

The value of the structured label would be "`vocab`>`code`"

Three `vocab` values are reserved:
- MOD (for the moderation vocabulary defined in NIP-69)
- X-MOD (for experiments in moderation and moderating regional issues, defined in NIP-69)
- \# (for adding hashtags)

_Examples:_
- "MeSH>D005528" would add the label ["Foot"](https://meshb.nlm.nih.gov/record/ui?ui=D005528) from NIH's Medical Subject Headings vocabulary
- "#>footster" would allow fans of Footster to add the hashtag #footster to someone's post
- "GeoNames>3173435" would add a label specifying [Milan, Italy](https://www.geonames.org/3173435/milan.html) using the GeoNames coding system
- "ISO-3166-2>IT-MI" would add a label specifying Milano, Italy using ISO 3166-2.

#### Proprietary structured vocabularies

Organizations may label events with their own proprietary coding systems. They should use care selecting their unique `vocab` value to ensure it doesn't conflict with values used by others or the values for well-known defined vocabularies. Organizations who publish events with proprietary vocabularies are encouraged to publish those vocabularies to Nostr so they can be used by others. The process for publishing the vocabulary will be defined in a subsequent NIP.

Repeated, intentional use of `vocab` values that conflict with the common names of well-known defined vocabularies will be considered spam.

#### Accommodating bots & advanced users

It is expected that bots will, in time, contribute to the labeling process, as will advanced users (e.g. scientists, moderators). These groups will require additional relevant information not required by regular users. Some features they will need supported are:

- `quality` is a real number between 0 and 1 which expresses how good of an example the item being labeled is of that label.
- `degree` is a real number between 0 and 1 which expresses where the item falls on a range if the label refers to a range.
- `confidence` is a real number between 0 and 1 which expresses how certain the entity publishing the label is that the label is accurate. It will mostly be used by bots.
- `support` is an array of URLs and/or Nostr ids with information to justify the labeling.
- `appliesto` is an array of element names and is used when `content` is a JSON encoded string and the labeling applies to only certain elements in `content`.

The features above are optional. With the possible exception of `appliesto` it is not expected that client apps aimed at regular users will make use of these features.

### Unstructured labeling

While defined vocabularies may be used heavily by automated systems, regular users may need the ability to add free-form labels. Unstructured labels are handled separately, as discussed below.

_Example:_
- "Sandals from Milan"

### Labeling when a note at the time it is published

Any event of _any kind_ may include labels relevant to its `content`. It shall do this using the following tags:
- `l` for structured labels
- `label` for unstructured labels

Clients MUST use one `l` tag for each structured label (which may result in multiple `l` tags). There may also be multiple `label` tags per event. Client apps should encourage users not to combine multiple concepts in the same `label` tag, but rather use multiple `label` tags.

A value of "#" for `vocab` SHOULD NOT be used when content is originally being published as it would be redundant with the `t` tag.

`l` and `label` tags may be extended using an optional, JSON-encoded parameter.

_Examples:_

Labeling of a kind 1 event…
```json
{
"pubkey": "<pubkey>",
"created_at": "<unix timestamp in seconds>",
"kind": 1,
"tags": [
["t", "Footster"],
["l", "MeSH>D005528"],
["l", "GeoNames>3173435", "{\"confidence\":1,\"quality\":1}"],
["l", "ISO-3166-2>IT-MI", "{\"confidence\":1,\"quality\":1}"],
["label", "Sandals from Milan", "{\"confidence\":1,\"quality\":0.9}"]
],
"content": "Look at the great sandals I picked up in Milan! I love how my feet look in them… https://domain.com/image.jpg",
"id": "<event-id>"
}
```
Labeling of a kind 1063 (NIP-94) event…
```json
{
"id": "<event-id>",
"pubkey": "<public key of the event creator>",
"created_at": "<unix timestamp in seconds>",
"kind": 1063,
"tags": [
["url","<string with URI of file>"],
["aes-256-gcm","<key>","<iv>"],
["m","<MIME type>"],
["x","<Hash SHA-256>"],
["size","<size of file in bytes>"],
["dim","<size of file in pixels>"],
["magnet","<magnet URI>"],
["i","<torrent infohash>"],
["blurhash","<value>"],
["l", "MeSH>D019142", "{\"confidence\":1,\"quality\":0.8}"],
["l", "GeoNames>203312", "{\"confidence\":1,\"support\":[\"https://www.cdc.gov/vhf/ebola/history/chronology.html\"]}"]
],
"content": "Scientific paper on the origins of Ebola.",
"sig": "<sig>"
}
```

### Labeling an event after initial publication

- Labeling after initial publication will use `kind 32144` [parameterized replaceable events](https://github.com/nostr-protocol/nips/blob/master/33.md).
- A kind 32144 event by the original pubkey overrides the labeling in the original event.
- All the labels that a Nostr user wishes to apply to an event need to be included in the kind 32144 event. If a previously listed label is missing when the kind 32144 event is updated, it will delete the missing label.
- `content` is optional for kind 32144. If included it should be a summary of the labeling. It should not reference URLs and Nostr IDs that are better placed in `source` parameters.

Kind 32144 events should have a `p` tag indicating the pubkey of the author of the event being reported, plus an `e` tag of the event being reported if reporting something other than kind 0. Client apps SHOULD include the recommended relay URL in the `p` and `e` tags.

This NIP modifies [NIP-10](https://github.com/nostr-protocol/nips/blob/master/10.md) by adding a `marker` of `label`, which SHOULD be used on `e` tags.

`a` tags with with other "shareable identifiers" as defined in [NIP-19](https://github.com/nostr-protocol/nips/blob/master/19.md), are recommended in order to help those reviewing moderation reports find the event in question.

It's worth noting that an unstructured, 3rd party label of someone else's profile (kind 0) is basically a review / recommendation of the other Nostr user. So this NIP will add a reviews and recommendations feature to Nostr.

Users cannot overwrite the labels given by other users - only their own labels. Client apps will use various methods to determine which labels are trusted enough to be visible or used in other ways.

[Confirmation is needed that what is spec'd below properly conforms to NIP-33.]

_Examples:_

A fan of Footster sees a post they really like that they think should get the tag #footster…
```json
{
"kind": 32144,
"pubkey": "<pubkey of labeler>",
"tags": [
["d", "labels/<eventid of event being labeled>"],
["e", "<eventid of event being labeled>", "<recommended relay URL>", "label"],
["p", "<pubkey of event being labeled>", "<recommended relay URL>", "label"],
["l", "#>footster"]
],
"content": "Lovely feet!",
"id": "<event-id>"
}
```
A scientist comes across a post on Ebola and they want to label it to make it easier for others to find…
```json
{
"kind": 32144,
"pubkey": "<pubkey of labeler>",
"tags": [
["d", "labels/<eventid of event being labeled>"],
["e", "<eventid of event being labeled>", "<recommended relay URL>", "label"],
["p", "<pubkey of event being labeled>", "<recommended relay URL>", "label"],
["a", "<sharable identifer for event with extra metadata>"],
["l", "MeSH>D019142", "{\"confidence\":1,\"quality\":0.8}"],
["l", "GeoNames>203312", "{\"confidence\":1,\"support\":[\"https://www.cdc.gov/vhf/ebola/history/chronology.html\"]}"]
],
"content": "Post discusses paper on the origins of Ebola.",
"id": "<event-id>"
}
```
If a profile is being labeled the labeling event would be similar, but slightly different…

```json
{
"kind": 32144,
"pubkey": "<pubkey of labeler>",
"tags": [
["d", "labels/<pubkey being labeled>"],
["p", "<pubkey being labeled>", "<recommended relay URL>", "label"],
["l", "MeSH>D019142", "{\"confidence\":1,\"quality\":0.9}"],
["l", "GeoNames>660013", "{\"confidence\":1}"]
],
"content": "Dr. Korhonen is a Finnish scientist who is one of the world's leading experts on Ebola.",
"id": "<event-id>"
}
```