- reviewed
- 2026-07-02
- section
- authoring
- status
- example
- rating
- 8
- updated
- 2026-07-11
- related
- Linking notes
- demo
- CLI
- created
- 2026-07-26
- updated
- 2026-10-30
Properties
Properties
Properties are typed key-value metadata on a note: a status, a rating, a due date, an owner. Their
home is the note's metadata sidecar, next to its tags and description — out of your prose — and the
engine indexes them with the rest of the vault, so they are queryable and visible wherever the note
is shown. When a data point belongs in the prose, a small inline key:: value field embeds it
there. If you know Obsidian's properties or org-mode's property drawers, this is the same idea.
This page is its own demo: the four lines below are inline fields in its source, and the property strip
at the top of this page is rendered from them. They stay in the prose, because that is what an inline
field is for — a weight:: 68.2 line in a journal is a line of the journal, not a hidden attribute.
What is not here is this page's icon: that is note-level metadata, and it lives outside the body — in a
vault note's sidecar, and for a published page like this one in the site's own config (see
Home dashboard).
status:: example rating:: 8 updated:: 2026-07-11 related:: Linking notes
Where properties live
track keeps note metadata (title, tags, description) in a per-note sidecar file, not in YAML
frontmatter — the body stays plain Markdown. Properties follow the same rule: note-level properties
live under props in the sidecar, and every frontend edits them there through the same validated
engine path:
- The metadata editor edits the note's whole editable metadata: title, tags, description, cover
image, icon, flags, and props. The Web workspace Meta dialog gives each built-in field a dedicated
control — a title box (a rename on change), a tags box, a description box, a cover image you can
upload straight from the browser into the vault assets, an icon box, and checkboxes for the note
flags — and keeps props as the one free-form YAML block.
The Neovim
:Track metapopup edits the same metadata as one YAML document. Either way the engine validates and applies the edit atomically, and a changed title renames the note. - The CLI, for scripts and point edits:
track meta --title "My note" --set status=draft --set rating=8
track meta --title "My note" --set "authors=[[Ada Lovelace]], [[Alan Turing]]"
track meta --title "My note" --unset rating
track meta --title "My note" --flag DEPRECATED
track meta --title "My note" # prints metadata incl. props, flags, and the editable doc (JSON)
track meta --title "My note" --edit - # apply a full metadata document from stdinA comma-separated value becomes a list. --unset removes a key, and a plain track meta call
prints the current properties along with the rest of the note's metadata.
Note flags
Flags are a second kind of note-level marker, distinct from properties. A property is a typed
key-value fact (status: draft); a flag is a whole-note judgment from a small, closed set — today
DEPRECATED and CONFIDENTIAL — that renders as a red stamp over the note itself and as a badge
beside it in lists. DEPRECATED also pushes the note down in search results, so an old note stops
crowding out its replacement.
Flags live in the sidecar beside tags, and track meta edits them the same way it edits properties:
track meta --title "Old design doc" --flag DEPRECATEDThe note now carries the flag, visible in track meta output and in its sidecar:
{"title":"Old design doc","flags":["DEPRECATED"],"updated":true}flags:
- DEPRECATED--flag is repeatable — a note can be both DEPRECATED and CONFIDENTIAL — and --unflag removes
one. The set is closed and implementation-defined: a value outside DEPRECATED/CONFIDENTIAL is
rejected at write time, so a new flag is a deliberate product change, never an ad-hoc string.
Each flag carries a page of its own, stamped with the flag it describes: A deprecated note and A confidential note.
Inline fields
The sidecar is the home for note-level facts; when a data point belongs in the prose itself, write
it directly in the body, anywhere prose flows, as key:: value:
status:: draft
- rating:: 8
Met with [owner:: [[Ada Lovelace]]] about the plan.Three placements work:
- A whole line —
status:: drafton its own line. - A list item —
- rating:: 8, numbered items included. - Bracketed, mid-sentence —
[owner:: [[Ada Lovelace]]]inside a paragraph.
Inline fields are scanned at index time into the same property index as sidecar values, each with
the body line it came from — and they keep rendering as the text you wrote, wherever you put them: a
whole line reads as its own line, a bracketed field stays inside its sentence. They are data and prose
at once, which is the whole point of them; a fact that is not prose (a title, a tag, an icon) is not an
inline field at all — it belongs outside the body, in the note's sidecar. Code is never scanned: std::vector in a fenced block
stays code, and a [key:: value] example in inline code (like the ones on this page) never becomes
data.
For example, this very sentence carries a live bracketed field, [demo:: CLI], and that is why
demo appears in this page's property strip above — as a link, because its value is a wiki link.
Typing rules
A value's type is detected from its text, with the same rules everywhere (sidecar, inline, CLI):
| Value text | Type |
|---|---|
true, false | boolean |
8, -3.5 | number |
2026-07-11 (a real calendar date) | date |
[[Title]] | link |
go, lua (top-level commas) | list — each item typed on its own |
| anything else | string |
A link value keeps its resolution key ([[Ada Lovelace|Ada]] stores Ada Lovelace), so it resolves
and navigates like any other wiki link — you can see that in the related entry of this page's
strip. Commas inside [[...]] do not split a list.
Schema and completion
Optionally, declare a schema for the keys you care about in the vault config (<vault>/.track/config.yml):
properties:
status:
type: string
values: [draft, review, done]
rating:
type: number
due:
type: datetypeis one ofstring,number,boolean,date,link;valuesis an optional enum. Keys not listed stay unconstrained.track doctorreports every value that breaks the schema — wrong type, or a value outside the enum — with the note and body line it came from.- The editor LSP completes declared keys while you type a field, and completes
values(ortrue/falsefor a boolean) afterkey::.
Where properties show up
- The Web workspace note view (and this published site) shows a note's properties above the body — sidecar values first, then inline fields in body order. In the live workspace the Meta dialog edits the sidecar values; the published site stays read-only.
track metaprints them as JSON for scripts.- The index stores every value typed and with line provenance, and Query filters, sorts, and
tabulates notes by these values — from the CLI or an embedded
track-queryblock.