# ssb-crut-authors

Basically `ssb-crut` but adds `authors` field and rules which go with that
to control who can publish valid updates to a record.

## Example usage

```js
const CRUT = require('ssb-crut-authors')
const Overwrite = require('@tangle/overwrite')

const server = Server() // some scuttlebutt instance
const spec = {
  type: 'gathering',
  props: {
    title: Overwrite({ type: 'string' }),
    description: Overwrite({ type: 'string' }),
    date: Overwrite({ type: 'string', pattern: '^2020-\d\d-\d\d' }),
    // authors    <-- automatically added
  },
  // isValidNextStep    <-- auto-adds authoship logic, you can add more logic on top
}

const crut = new CRUT(serve, spec)

const details = {
  title: 'party',
  authors: { add: [server.id] }
}
crut.create(details, (err, gatheringId) => {
  //
})
```

## Authorship Rules

1. You must add at least one author when creating a record
2. A valid update is one which
    - a) is authored by someone in the list of active authors on the tip(s) the update is extending
    - b) leaves the record with > 1 author (after update is applied)
3. An `Author` must be one of:
    - a `FeedId`
    - `*` (wildcard), and means anyone can author
4. If `*` is active (has been added and not removed) then anyone can update, regardless of whehter they have been removed.

Rare edge cases:

### Edge Case (A) - _authors simultaneously remove one another_

An example of edge case (A) would be:
- there are two authors added in initial message `A`
- update `B` removes one author, `C` removes the other
- one of those authors tries to publish M

```mermaid
graph TB
A-->B-.->M
A-->C-.->M

classDef default fill: purple, color: white, stroke: none;
classDef proposed fill: hotpink, color: white, stroke: none;
class M proposed
```
_Diagram of a branched state (tips `B`, `C`) and you're trying to publish an update (merge node `M`)_


This could be a block because of rule (2.a), as to extend two tips you must be an active author according to each tip,
(and no author is valid for both tips).

**Special Rule**: in this case the "original author" is considered a valid author to publish a resolving message

Notes:
- this special rule only applies if there exists no valid author who could merge
- publishing an "empty" transformation M is insufficient as merging these authors state would violate rule (2.b)
    - i.e. `M` here must contain add at least one author


## Requirements

Same as `ssb-crut`: https://gitlab.com/ahau/lib/ssb-crut#requirements

## API

Same as `ssb-crut` except `authors` is a reserved variable:
- `spec.props` cannot include `authors`
- `spec.staticProps` cannot include `authors`

## TODO

This was extracted from `ssb-profile` in order to generalise it to more records.
  - Need to review if we've extracted all the relevant tests about authorship from there

We might want to consider modifying `ssb-crut` to take "plugins" to extend core functionality and make this a plugin
