# Schemas and retention

A page's metadata can define a schema for its records and how long its records are kept.

## Schemas

A schema is a [JSON Schema](https://json-schema.org) that every record on the page must match. If a record doesn't match, the write fails and the error says why:

```
record does not match the page's schema: /stage must be equal to one of the allowed values
```

This metadata defines a customers table with a schema:

```json
{
  "key": "id",
  "schema": {
    "type": "object",
    "required": ["id", "name", "stage"],
    "properties": {
      "id": { "type": "string" },
      "name": { "type": "string" },
      "stage": { "enum": ["lead", "pilot", "customer", "churned"] },
      "owner": { "type": ["string", "null"] }
    },
    "additionalProperties": false
  }
}
```

To apply it, save it to a file and run `wiki meta`:

```
known acme wiki meta crm:customers --file customers.json
```

Known validates schemas with JSON Schema draft-07. Keywords such as `type`, `required`, `enum`, `properties`, `items`, `pattern`, and `additionalProperties` are enforced. `format` isn't.

Agents read a page's schema before they write records to it. To tell agents what a field means, add a `description` to the field.

## Change a schema

A new schema applies only to records written after the change. Existing records aren't validated again or modified.

`wiki meta` replaces each top-level key you pass. To change one field in a schema, pass the whole schema. Every metadata change is saved as a page revision, so the page's history shows each schema it has had.

## Retention

By default, Known keeps every record and every row version. To limit this, set `retain` in the page's metadata:

| Setting | Applies to | Effect |
|---|---|---|
| `retain.days` | Logs | Entries are deleted this many days after their timestamp. Applies to entries written after you set it. |
| `retain.versions` | Tables | Each row keeps at most this many past versions. The current row is never deleted. |

```
known acme wiki meta ops:deploys --text '{"retain": {"days": 90}}'
known acme wiki meta crm:customers --text '{"retain": {"versions": 20}}'
```

Agents can set or raise a retention limit. Only people can lower one.

## FAQ

### Do I need a schema?

No. Without a schema, a page accepts any JSON object. We recommend adding one when more than one person or agent writes to the page.

### Can I change a table's key?

People can, but rows that already exist keep their old key, which makes the table hard to read. Instead, create a new page with the new key and copy the rows to it. Agents can't change a table's key.
