---
title: "Vault Format: how tasks are stored on disk"
source: https://fieldbw.com/docs/tr-2/vault-format
---

# Vault Format: how tasks are stored on disk

A TR-2 vault is just a folder. Everything below is what TR-2 expects to find there — and what it promises not to mangle. The full grammar lives in `SPEC.md`; this page is the working summary.

## Vault layout

```
<vault>/
  .tr2                 # format-version marker (see "Versioning")
  README.md            # orientation; humans/agents read this first
  inbox.md             # the capture list
  Work/                # a folder = a GTD "area"
    website.md         # a file = a project
    Subarea/           # areas nest arbitrarily
      launch.md
```

- A **folder** is a GTD area. Areas nest to any depth.
- A **file** (`*.md`) is a project, or the special `inbox.md`.
- A file lives in exactly one folder.
- `README.md` at the vault root is orientation only and is **never rewritten** by TR-2.

## Project file anatomy

Optional YAML frontmatter, then a GFM task checklist, then any markdown you like.

```markdown
---
id: 7f3a2b
type: project
title: Website redesign
---

- [ ] Redesign homepage @next due:2026-05-25
  - [x] Audit current layout
  - [ ] Wireframe v2
- [x] Fix nav bug done:2026-05-18

## Done
- [x] Decommission old CMS done:2026-05-12

Any free prose, headings, code fences, links — preserved verbatim.
```

### Frontmatter

| Key | Meaning |
|---|---|
| `id` | short stable identifier (survives renames). Optional but recommended. |
| `type: project` | reserved; identifies a project file. |
| `title` | optional display title. Falls back to the file name. |
| `archived: true` | parks the project — hidden from the default sidebar and lists; still on disk, accessible from the **Archived** view. |

**Any other keys are preserved untouched.** Unknown keys, comments, blank lines, and key order all round-trip exactly. Reserved-for-later keys (don't repurpose): `area`, `tags`, `recurring`, `created`.

### Task lines

A task is a GFM checklist item. Three checkbox states:

| Box | State | Notes |
|---|---|---|
| `- [ ]` | open | |
| `- [*]` | in progress | `- [/]` accepted; TR-2 writes `*` |
| `- [x]` | done | `[X]` accepted; TR-2 writes `x` and adds `done:` |

`*` and `+` list bullets are accepted and preserved. Indentation makes subtasks.

### Tokens

Lightweight, human-readable, position-independent within the line:

| Token | Meaning |
|---|---|
| `@today` | belongs in **Today** |
| `@next` | a next action; surfaced in **Next** + a per-task badge |
| `@someday` | parked "maybe later"; appears in **Someday**, excluded from Today / Scheduled |
| `@waiting` | reserved (parsed & preserved; surfaced later) |
| `#tag` | a free-form tag; each tag gets a derived cross-vault view |
| `due:YYYY-MM-DD` | due date. On/before today → **Today**. In the future → **Scheduled**. |
| `done:YYYY-MM-DD` | completion date. Written by the app on completion, cleared on un-complete. |

**Grammar:** `@word` = `@` + `[A-Za-z][A-Za-z0-9_-]*` (a context). `#word` = `#` + `[A-Za-z][A-Za-z0-9_/-]*` (a tag). `key:value` = `key:` + non-space value. Tokens are whitespace- or line-start delimited. Unrecognised `@words`, `#tags`, and `key:value`s are left alone — adding meaning to one later cannot break an older file.

### Sections

An ATX heading (`## Name`) inside a project body groups the tasks that follow it. Headings are preserved verbatim. You can drag-reorder sections in the app; you can also rename or delete the heading directly in the file.

### Notes on a task

Prose lines indented deeper than the task, placed directly beneath it, are the task's **note**. The note travels with the task on reorder/move.

```markdown
- [ ] Redesign homepage @next due:2026-05-25
    Pick a direction with the team first.
    Longform is fine.
  - [ ] Wireframe v2
```

### The optional `^id`

A task line may end with an opaque block id: `- [ ] Email Bob ^ab12` (`^` + 1–16 of `[0-9A-Za-z]`). TR-2 adds one **only** when it must disambiguate two tasks with identical text. Editors should leave them alone but can delete one safely — TR-2 falls back to content/position matching with no data loss. A freshly hand-authored vault contains zero `^ids`.

## The `## Done` section

A trailing `## Done` heading collects completed top-level tasks. When you check a task off, TR-2 sweeps its whole subtree under this heading; un-checking moves it back.

- The heading is **optional**. A file without one round-trips unchanged.
- The text is exactly `Done`; any heading level is recognised. TR-2 writes `## Done`.
- The sweep is idempotent and only fires on a real status change — opening a file never silently rewrites it.
- Subtasks travel with their root subtree; a checked child of an open parent is **not** archived in isolation.
- You can delete or rename the heading freely; the next done-state change recreates it.

## The round-trip guarantee

> `serialize(parse(bytes)) == bytes`, byte-for-byte, for **any** input — including content TR-2 does not model.

TR-2 only rewrites the specific lines a user edits in-app. Everything else (prose, headings, code fences, unknown frontmatter, CRLF line endings, a missing final newline) is emitted verbatim. This is enforced by a blocking test suite. TR-2 will never destroy content it doesn't understand — so hand-editing the file or letting an AI rewrite parts of it is safe.

## Editing by hand / by AI / by `git`

The files are the source of truth, so:

- **Add a task** — append a `- [ ] something` line to a project file or `inbox.md`.
- **Complete a task** — change `[ ]` to `[x]` (TR-2 will add `done:YYYY-MM-DD` on its next write).
- **Move a task** — cut from one file, paste into another. The task is wherever it lives on disk.
- **Rename an area** — rename the folder. Everything beneath follows.
- **Diff history** — every change is an ordinary text diff. `git log` is your audit trail.

## Versioning

A vault carries a tiny `.tr2` marker file at its root. It declares the format version (currently `v1`) so future TR-2 builds can opt into changes without surprising older files. The file format described on this page is `v1` and the round-trip guarantee applies in full.

## See also

- [AI Workflows](/docs/tr-2/ai-workflows) — point an agent at the vault.
- [Getting Started](/docs/tr-2/getting-started) — the 30-second tour.
