# The Ilu Rennik record format

Version 0.1, published 1 October 2026.

A person's record should outlive the company that holds it. Any program
they choose (another app, an assistant, an agent, themselves in ten years)
should be able to read it without us. This page says exactly what a record
is, so an export is a complete copy and not a dump of our tables.

Every Ilu Rennik export is written in this format: Settings, "Download
everything". A program can check a file against the
[JSON Schema](/format/ilu-record-0.1.schema.json); this page is also
available as [plain Markdown](/format/ilu-record-0.1.md).

## The parts

Five parts, all plain JSON:

1. **Facts**: what is true about the person's life.
2. **Sources**: what each fact stands on.
3. **Shelves**: where each fact is filed.
4. **Grants**: who may read which shelves.
5. **Disclosures**: what each reader asked, was told, and opened.

The original documents travel beside the JSON, named by id.

## The folder

One zip:

```
record.json          everything below, in one file
documents/<id>.<ext> the original files the sources point at
README.txt           what each part is, in plain words
```

An export may carry other files beside these (a spreadsheet copy of the
facts, one file per person). They are conveniences, not part of the
format.

`record.json`:

```json
{
  "format": "ilu-record/0.1",
  "exported_at": "2026-10-01T09:00:00Z",
  "owner": { "name": "Alex Rivera", "addresses": ["alex@example.com"] },
  "shelves": [],
  "facts": [],
  "sources": [],
  "documents": [],
  "grants": [],
  "disclosures": []
}
```

Fact, source, document and grant ids are UUIDs and never change for the
life of the thing they name. Shelves and elements are named by slugs of
their names. Every time is ISO 8601 in UTC, ending in `Z`. Every text is
UTF-8. A field with nothing to say is `null` (or an empty list), never
absent.

## Shelves

```json
{ "id": "finances", "name": "Finances",
  "elements": [ { "id": "bank-accounts-map", "name": "Bank accounts" } ] }
```

A shelf is one part of a life: Finances, Insurance, Home and property,
Health and medical, Documents, Subscriptions and accounts, Business,
Estate. An element is a thing a shelf holds (bank accounts, a will).
Shelves and elements are named, not numbered, so a reader that has never
seen ours can still show them. Every shelf is listed, empty or not; a
shelf lists the elements its facts are on.

## Facts

```json
{
  "id": "6f52af77-1c1e-4c55-9b57-0d3f8b6a2e11",
  "subject": "Email with MRI results",
  "statement": "The MRI results came by email from the clinic on 9 September.",
  "kind": "document_pointer",
  "shelf": "health-and-medical",
  "element": "medical-records",
  "placed": "filed",
  "in_vault": false,
  "status": "active",
  "held_because": null,
  "sealed": false,
  "standing": "confirmed",
  "first_seen": "2026-09-09T15:02:00Z",
  "last_confirmed": "2026-09-29T18:10:00Z",
  "effective": null,
  "owes": null,
  "supersedes": []
}
```

- `subject` names the thing, and says which thing it is ("Email with MRI
  results", never "An email with a link").
- `statement` is one sentence, true on its sources.
- `kind` is what sort of fact it is: `account_map`, `asset_location`,
  `business_owned`, `designation`, `document_pointer`, `instruction`,
  `letter`, `policy_fact` or `role`.
- `element` is null for a fact on its shelf with no element.
- `placed`: `filed` (on an element, a document that stands alone, or put
  in the vault by the owner) or `guessed` (shelved by its kind alone). A
  guessed fact is unconfirmed whatever stands behind it.
- `in_vault`: the owner put it in their own vault. It keeps its shelf.
- `status`:
  - `active`;
  - `conflicted`: two sources disagree and the owner has not said which
    is right;
  - `held`: read and kept, but held back when it was first read;
    `held_because` says why, in plain words;
  - `retired`: no longer true, or replaced. Kept, never deleted.
- `sealed`: a reader may learn the fact exists and its subject, never its
  statement or its sources.
- `standing`: `confirmed` (a document or the owner's own word stands
  behind it, and it is filed) or `unconfirmed`.
- `effective`: when the fact took effect, when a source says.
- `owes`: for money, who owes whom, as
  `{ "from": "Northwind Ltd", "to": "Alex Rivera" }`, or null when it was
  not established.
- `supersedes`: the ids of the facts this one replaced (several, when
  several were folded into one), so history is a chain, not a loss.

## Sources

**No fact without a source, and a source is something that exists outside
the record.**

```json
{
  "id": "e1c0d2a4-7f43-4a8e-a1f0-3b2c9d8e7f60",
  "fact": "6f52af77-1c1e-4c55-9b57-0d3f8b6a2e11",
  "kind": "email",
  "quote": "Your MRI results are attached.",
  "seen": "2026-09-09T15:02:00Z",
  "message": { "channel": "email", "from": "Lakeside Clinic <results@clinic.example>",
               "to": "Alex Rivera", "subject": "Your results",
               "sent": "2026-09-09T15:01:00Z" },
  "document": null
}
```

`kind` is one of:

- `email`, or `message` for another channel (LinkedIn, for one). `message`
  names it by channel, sender, recipient, subject and date. Never the
  body: the body stays in the owner's mailbox.
- `document`: a file. `document` is the id of an entry in `documents`.
- `said`: the owner's own words. `quote` is what they said, verbatim.

`quote` is text that appears in the source, word for word.

## Documents

```json
{ "id": "a7c1e9f2-5b6d-4c3a-8e7f-1d2c3b4a5e6f", "filename": "home-policy-2026.pdf",
  "type": "application/pdf", "bytes": 1200345,
  "file": "documents/a7c1e9f2-5b6d-4c3a-8e7f-1d2c3b4a5e6f.pdf",
  "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "missing": null }
```

The file sits beside `record.json` at `file`. `sha256` is computed over
the bytes in that file. The same bytes are written once: two documents
with the same content point at the same `file`. A document that could not
be included has `file` and `sha256` null, and `missing` says why in plain
words. Nothing is left out silently.

## Grants

Who may read the record, and how much.

```json
{
  "id": "0b8e2f4c-9d1a-4e7b-b6c5-2a3f4e5d6c7b",
  "reader": "Sam Rivera",
  "audience": "person",
  "email": "sam@example.com",
  "shelves": ["insurance", "estate"],
  "amounts": "exact",
  "opened": "2026-09-22T17:08:00Z",
  "ends": null,
  "closed": null,
  "last_used": "2026-09-25T10:00:00Z",
  "times_used": 3
}
```

- `audience`: `person` (a family member, an accountant) or `agent` (a
  program acting for someone).
- `shelves`: the shelves the reader may see. Empty means every shelf.
- `amounts`: `exact`, or `banded` (the reader is told ranges, not
  figures).
- `opened`, `ends`, `closed`: when the grant was given, when it expires,
  and when the owner closed it.
- What crosses a grant is fixed by the format, not by whoever holds the
  file: only facts that are `active`, `confirmed`, on a granted shelf and
  not `sealed`. A sealed fact crosses as its subject alone. An agent never
  receives a document.

## Disclosures

What each reader asked, what they were told, and when. This is the part
that makes a record safe to share: the owner can always see exactly what
left it.

```json
{
  "grant": "0b8e2f4c-9d1a-4e7b-b6c5-2a3f4e5d6c7b",
  "at": "2026-09-25T10:00:00Z",
  "question": "What is the deductible?",
  "answered": true,
  "answer": "The deductible is $1,000.",
  "told": ["6f52af77-1c1e-4c55-9b57-0d3f8b6a2e11"],
  "opened_document": null
}
```

Two kinds of entry, in time order:

- A question. `told` lists the facts the answer stood on, by id.
- A document the reader opened. `question` and `answered` are null,
  `opened_document` is the document's id, and `told` is the fact it was
  opened from.

## What a reader may rely on

1. Every fact has at least one source, and every quote is in its source.
   One exception: a retired fact that was replaced may have handed its
   sources to the fact that replaced it (the one whose `supersedes` names
   it).
2. Nothing is deleted. A retired or replaced fact stays, marked.
3. A grant's boundary is the rule above, whatever program reads the file.
4. The disclosures are complete. Nothing was told to a reader that is not
   listed.

## Left out on purpose

- Mail bodies. A record points at the mail; the mailbox keeps it.
- People and relationship history. A separate, later part, if ever.
- Nothing is left out for being uncertain. Anything read and never
  confirmed is in, marked `unconfirmed`, so a reader can tell what the
  person stands behind.

## Versions

Once published, a version does not change. A change to the format is a new
version number, and every file written in an older version still reads.
Questions: team@ilurennik.com.
