Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions 7A.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
NIP-7A
======

Comment-based Patching
----------------------

`draft` `optional`

A patch is a `kind:1111` [NIP-22](22.md) comment that references the patched event as its parent and whose `.content` is a `PATCH` label followed by a patch in a human-readable patch syntax.

Clients that support this can apply the patch on top of the original event and hide the patch comment.

Every other client can just display the patch as a normal `kind:1111` comment which is relatively human-readable and clearly labeled as a patch.

```json
{
"kind": 1111,
"content": "PATCH\n<patch-content>",
"tags": [
["patch"],
["e", "<event-id-being-patched>", "<relay-url>", "<pubkey>"],
["k", "<kind-of-event-being-patched>"],
]
}
```

## Patch syntax

`<patch-content>` is formed by one or more lines.

Lines starting with a number modify the `.content` of the patched event:

```
<index> -<number-of-characters-deleted> +<number-of-characters-inserted> <actual-characters-inserted>
```

Lines starting with a `t` modify a human-facing tag (e.g. `title`, `description`, `subject`, `picture`) of the patched event, replacing it with the given value:

```
t <tag-name> <new-value>
```

The indexes and amounts refer to unicode characters, not bytes.

## Mandatory Recommendations

This method should not be used to completely replace a thing (better delete and make a new one) or to continuously update it over time (better use replaceable events).

It is meant for fixing typos, adding missing content and other small text issues.

Therefore, clients should prevent users from:
- generating too large patches;
- publishing too many of such patches;
- making patches many days after the original event was published.

Likewise, clients reading these patches should refrain to apply them (and leave them only as hanging comments) if they are
- too large;
- too many;
- published too long after the original event was published.

Also, when generating content patches clients should prefer to do it over full words instead of over characters, in benefit of human-readability, unless perhaps when what is being fixed is a single character inside a word.

## Target kinds

The event kinds that are expected to be patchable this way are:
- `1` (short text notes),
- `11` (forum threads),
- `1111` (comments),
- `24` (public messages),
- `1621` (issues).

## Broken patches

In case a patch can't be applied, the reader client can just leave it as it is, displayed as a normal comment.

## Multiple patches

If more than one patch has to be made, they should all target the same original event (i.e. the second patch shouldn't tag the first patch), and the reader client should apply one after the other, in temporal sequence.

## "This patch format is ugly and not human-readable"

The current patch format is a middleground between human-readable and simple and computer-readable, so it isn't perfect. If this is a concern, though, reader clients that don't want to apply the patch directly (which is a reasonable choice) can easily parse the `<patch-content>` and display it in a more human-readable way (for example, with colors, removing the numbers, or by displaying it with context from the original post). Clients already parse every note's content for references, URLs, hashtags, so this would just be a thin extra parsing layer that wouldn't require a lot of changes.

## Handling replies to patches

If a reader client sees a reply to a patch that was merged on the upstream event, it could display such reply as if it was replying to the original event, possibly with some visual clue that it was targeting the patch (even better if the patch itself could be still accessed somehow, even after applied and hidden).

## Third-party patches

It is probably better to not support these and just ignore them by default, but if a client so desires it, may be a cool dynamic to allow people to publish patches to events authored by someone else.

In this case these should never be applied automatically, only upon user action that clearly implies this patch isn't by the original author (e.g. by clicking on the patch event that would otherwise just stay there as a normal weird-looking comment).