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 specialinbox.md. - A file lives in exactly one folder.
README.mdat 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.
---
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:values 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.
- [ ] 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
- [ ] somethingline to a project file orinbox.md. - Complete a task — change
[ ]to[x](TR-2 will adddone:YYYY-MM-DDon 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 logis 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 — point an agent at the vault.
- Getting Started — the 30-second tour.