Obsidian frontmatter inventory: read-only census of the root-and-branch vault

Every .md parsed (2,519 files, no sampling), parser carrying four controls.
400 distinct keys over 5,867 instances; 68% of notes have no frontmatter at all.

Consumption cross-referenced against 357 dataview/tasks blocks, 23 templates
and all 39 .obsidian configs: 66 keys consumed (62% of instances), 29 written
by template and read by nothing, 305 orphaned. The Compass governance block —
canonical/owner/assurance/change_log/links/related — is in the written-not-read
set on 67-161 notes each.

Method correction recorded in the report: the first template pass matched key
names anywhere in a file containing Templater syntax, which tests whether the
word occurs in prose rather than whether a template writes the key. Redone
against each template's own frontmatter block.

Inventory only — no proposed schema, per the brief.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
David F Glidden
2026-08-19 11:34:34 +02:00
co-authored by Claude Opus 5
parent 0fbd4f625a
commit 5d577d0bbf
4 changed files with 20277 additions and 0 deletions
@@ -0,0 +1,365 @@
---
name: obsidian-vault-frontmatter-inventory-2026-08-19
description: Read-only inventory of YAML frontmatter conventions in the "David, root-and-branch" Obsidian vault — key census, consumption cross-reference, folder correlation, template drift. No proposals.
type: reference
---
# Obsidian frontmatter inventory — *David, root-and-branch*
**Date:** 2026-08-19 · **Mode:** read-only audit, no edits · **Scope:** the root-and-branch vault only
(`Ars Legendi` and `DFG Principles` exist and were **not** audited).
**Method.** Every `*.md` outside `.obsidian/`, `.trash/`, `.git/`, `.smart-env/` was parsed — 2,519 files,
no sampling. Frontmatter recognised only as a `---` block **beginning at byte 0**; a stray `---` mid-file
is not frontmatter. The parser carries four controls, all passing: well-formed → detected; no
frontmatter → none; stray mid-file `---` → none; unterminated → reported as its own outcome rather than
folded into silence. Keys were harvested **twice** — once via `yaml.safe_load`, once textually — so a
parse failure cannot silently shrink the census (410 textual key-lines vs 400 parsed keys; the gap is the
21 unparseable notes in §6).
---
## 1. Coverage — the first number
| | notes |
|---|---|
| markdown files | **2,519** |
| **no frontmatter at all** | **1,713 (68%)** |
| frontmatter present | 806 (32%) |
| … parsed as a mapping | 784 |
| … YAML error | 20 |
| … not a mapping / empty | 2 |
| unreadable | 0 |
| unmaterialized iCloud placeholders | **0** — so this census is of the vault, not of what happened to be downloaded |
**By folder** — coverage is not uniform; it tracks how recently and how deliberately a folder was built.
| folder | notes | with frontmatter | % |
|---|---:|---:|---:|
| 99. Archive | 1,070 | 120 | **11%** |
| 08. Notes | 596 | 230 | 38% |
| 00. Compass | 400 | 193 | 48% |
| 06. Projects | 246 | 105 | 42% |
| 04. Life admin | 47 | 45 | **95%** |
| 07. Learn | 29 | 19 | 65% |
| 97. Tools and Systems | 28 | 26 | 92% |
| 98. Templates | 23 | 18 | 78% |
| 03. People | 21 | 14 | 66% |
| 05. Work | 21 | 7 | 33% |
| 02. Reviews & Planning | 13 | 7 | 53% |
| 01. Daily | 11 | 10 | 90% |
| 00a. _inbox | 11 | 11 | 100% |
| 09. Atlas of Roots | 1 | 1 | 100% |
| 10. Instrumentarium | 1 | 0 | 0% |
| (vault root) | 1 | 0 | 0% |
---
## 2. The key census — 400 distinct keys, 5,867 instances
**Distribution is extremely long-tailed.** 227 keys (57%) appear on one or two notes; **170 appear
exactly once**. The top 10 keys carry 3,145 instances — 54% of all frontmatter in the vault.
### Keys on ≥10 notes, with observed value shapes
| key | notes | shapes observed |
|---|---:|---|
| `tags` | 698 | `list[str]`×689, `list[int\|str]`×6, empty×1, nested-list×1 |
| `title` | 610 | `str`×605, null/empty×5 |
| `type` | 416 | `str`×416 — **the only high-frequency key with a single shape** |
| `created` | 359 | `date`×339, `str(date-like)`×12, `str`×7, nested-list×1 |
| `status` | 305 | `str`×305 |
| `version` | 164 | `str`×157, **`float`×6**, `date`×1 |
| `date` | 163 | `date`×155, `str`×7, `str(wikilink)`×1 |
| `canonical` | 161 | `str`×158, **`bool`×3** |
| `owner` | 153 | `str`×153 |
| `assurance` | 126 | `dict`×117, **`str`×8**, null×1 |
| `last_reviewed` | 123 | `date`×115, `str`×5, null×1, nested-list×1 |
| `related` | 120 | `list[str]`×90, nested-list×8, `list[wikilink]`×7, `list[list]`×6 |
| `change_log` | 89 | `list[dict]`×51, **empty list×38** |
| `source` | 86 | `str`×79, `list[str]`×3, `str(url)`×2, `dict`×1 |
| `project` | 83 | `str`×81, `list[str]`×2 |
| `next_review` | 80 | `date`×80 |
| `links` | 77 | `dict`×76, null×1 |
| `aliases` | 71 | `list[str]`×71 |
| `location` | 67 | `str`×58, null×8, nested-list×1 |
| `category` | 52 | `str`×43, `list[str]`×9 |
| `week` | 51 | `str`×51 |
| `author` | 49 | `str`×45, `list[str]`×3, `dict`×1 |
| `last_updated` | 38 | `date`×38 |
| `description` | 36 | `str`×36 |
| `origin` | 34 | `str`×34 |
| `layout` | 33 | `str`×33 |
| `mood` | 30 | **null/empty×26**, `str`×4 |
| `focus` | 24 | **null/empty×24 — never once filled in** |
| `vault_section` / `month` / `marker` | 23 each | `str` |
| `class` / `roaster` | 22 each | `str` |
| `review_cycle` | 21 | `str` |
| `water` | 21 | `int`×10, `float`×6, `str`×4, `list`×1 |
| `coffee` | 21 | `str` |
| `grind_setting` | 21 | `float`×16, `str`×3, `int`×2 |
| `related_notes` | 20 | `list[str]`×13, `list[wikilink]`×4, nested×1, empty×1 |
| `bloom` | 20 | `int`×11, `float`×8, `str`×1 |
| `brew_temp` | 20 | `str`×16, `list[list[str]]`×4 |
| `superseded_by` | 18 | `list[list[str]]`×18 |
| `depends_on` | 17 | `list[wikilink]`×6, nested×5, `list[str]`×4, empty×2 |
| `summary` | 17 | `str` |
| `family` | 16 | empty×6, `dict`×6, null×4 |
| `context` | 15 | `str`×8, null×6, `dict`×1 |
| `retention` | 15 | `float`×9, `str`×4, `int`×2 |
| `updated` | 14 | `date`×14 |
| `languages` / `permalink` / `process` | 13 each | mixed / `str` / `str` |
| `relationship`, `dob`, `latitude`, `longitude`, `source_type`, `attributed_to`, `date_claimed`, `first_cited`, `fictional_description`, `chambers_cited_in`, `excerpts`, `dose`, `weather`, `temperature`, `humidity`, `pressure` | 12 each | see JSON |
| `citizenship`, `draft_created`, `emerged_from`, `related_real_sources`, `dateAdded`, `lastUpdated`, `method`, `roast_level`, `bloom_time`, `pour_strategy`, `total_time`, `rating` | 11 each | see JSON |
| `alias`, `person`, `bill_number`, `moon_phase` | 10 each | see JSON |
*Full per-key detail — every shape, four sample values, folder distribution, and the file list — is in
`fm_inventory.json` alongside this report.*
### 2a. Type instability, observed
Nine keys carry more than one value type. Three matter because a query would silently mis-sort or drop rows:
- `version` — `str`×157 but **`float`×6** (`1.0` unquoted becomes a number) and `date`×1.
- `canonical` — `str`×158 but **`bool`×3** (`true` unquoted).
- `assurance` — `dict`×117 but **`str`×8**: the same key is a structure on most notes and a bare string on eight.
- Nested-list shapes (`list[list[...]]`) on `created`, `related`, `location`, `superseded_by`, `brew_temp`,
`linked_daily_note` are the signature of a wikilink or date written unquoted inside a YAML list —
`- [[Note]]` parses as a nested list, not a link.
### 2b. Two keys that collide with Dataview's own namespace
- **`file`** is used as a frontmatter key on 5 notes. `file` is Dataview's implicit page object
(`file.link`, `file.day`, `file.name`) and appears in 83 query blocks in that sense.
- **`date`** on 163 notes coexists with Dataview's `file.day`, which is inferred from the filename.
---
## 3. Consumption — is anything reading these keys?
Cross-referenced against every consumption surface in the vault: **357 code blocks** (264 `dataview`,
72 `dataviewjs`, 21 `tasks`) across 98 notes; **23 templates** in `98. Templates`; all **39** `.obsidian`
JSON configs; 14 CSS snippets.
> **A method note, because the first pass of this was wrong.** I initially scored a key as
> "written by a template" if its name appeared *anywhere* in a file containing Templater syntax. That
> tests whether the word occurs in the prose, not whether a template writes the key — and it inflated
> the bucket badly (`practice`, `work`, `note` all scored as template-written on prose matches alone).
> The figures below come from parsing each template's **own frontmatter block**. Likewise, Dataview
> matches are made after stripping string literals and `FROM` clauses, so a folder path like
> `FROM "08. Notes"` no longer counts as consumption of a key named `notes`.
| verdict | keys | key-instances |
|---|---:|---:|
| **CONSUMED** — appears in a Dataview query field position | 66 | **3,661 (62%)** |
| **WRITTEN-NOT-READ** — a template writes it, no query reads it | 29 | 1,128 (19%) |
| **ORPHAN** — no template declares it, no query reads it | **305** | 1,078 (18%) |
| DECLARED-ONLY (`types.json`, unqueried) | 0 | 0 |
**The shape of it: the *mass* is consumed, the *variety* is not.** 62% of all frontmatter instances sit
on the 66 keys something actually reads. But 305 of 400 distinct keys — 76% — are read by nothing, and
248 of those appear on four notes or fewer.
### 3a. WRITTEN-NOT-READ — the governance block is the largest instance
These are written faithfully by template onto hundreds of notes and queried by nothing in the vault:
| key | notes | declared by |
|---|---:|---|
| `canonical` | 161 | 1 template |
| `owner` | 153 | 1 |
| `assurance` | 126 | 1 |
| `related` | 120 | 1 |
| `change_log` | 89 | 1 — and **38 of the 89 are an empty list** |
| `links` | 77 | 1 |
| `aliases` | 71 | 1 |
| `location` | 67 | 1 |
| `vault_section` | 23 | 2 |
| `month` | 23 | 3 |
| `review_cycle`, `water`, `bloom`, `brew_temp` | 20–21 | 1–2 |
| `family`, `languages`, `process`, `relationship`, `dob`, `dose` | 12–16 | 1–2 |
| `citizenship`, `bloom_time`, `pour_strategy`, `alias` | 10–11 | 1–2 |
| `reflection`, `homeopathy`, `skin_observations`, `full_name`, `occupation` | 2–7 | 1 |
`canonical`, `owner`, `assurance`, `change_log`, `links`, `related` are the Compass's own
governance/provenance apparatus — the fields that would answer *is this authoritative, who holds it,
when was it last checked, what does it depend on.* **Nothing queries them.**
### 3b. ORPHAN keys on ≥5 notes — no template, no query
`source`(86) · `last_updated`(38) · `layout`(33) · `focus`(24) · `marker`(23) · `related_notes`(20) ·
`vault_path`(19) · `depends_on`(17) · `context`(15) · `permalink`(13) · `source_type`(12) ·
`attributed_to`(12) · `date_claimed`(12) · `first_cited`(12) · `fictional_description`(12) ·
`chambers_cited_in`(12) · `excerpts`(12) · `weather`(12) · `temperature`(12) · `humidity`(12) ·
`pressure`(12) · `emerged_from`(11) · `related_real_sources`(11) · `dateAdded`(11) · `lastUpdated`(11) ·
`method`(11) · `person`(10) · `bill_number`(10) · `created_by`(9) · `address`(9) · `billing_period`(9) ·
`dose_in`(9) · `dose_out`(9) · `pour_durations`(9) · `chat_topics`(9) · `due_date`(8) ·
`contract_number`(8) · `organ`(7) · `currency`(7) · `meter_number`(7) · `payment_method`(7) · `cups`(7) ·
`moon_illumination`(7) · `steward`(7) · `period`(6) · `language`(6) · `brew_time`(6) ·
`executor-action`(6) · `body`(6) · `sources`(5) · `spiral_stage`(5) · `symbol`(5) · `provenance`(5) ·
`domain`(5) · `sequence`(5) · `published`(5) · `tone`(5)
**plus 248 orphan keys on 1–4 notes (385 instances).**
### 3c. Obsidian's own property registry is effectively unused
`.obsidian/types.json` declares **26** properties. Twenty-two are `TQ_*` UI toggles belonging to the
Tasks plugin. The genuine declarations are **four**: `aliases`, `cssclasses`, `tags`, `status`. Of the
400 keys in use, 396 have no declared type.
---
## 4. Folder correlation — distinct shapes do exist
Five folders show a consistent, recognisable shape; the rest are mixed.
- **`00. Compass`** — 84 keys / 1,836 instances. The most consistent shape in the vault:
`title`(190) `tags`(163) `status`(137) `type`(135) `version`(115) `canonical`(107) `owner`(99)
`created`(80) `assurance`(78). This is a governed-document shape and it is applied evenly.
- **`03. People`** — 29 keys / 100 instances, tightly matching the People template:
`relationship`(10) `languages`(9) `dob`(9) `citizenship`(9) `family`(8) `alias`(8).
- **`01. Daily`** — 18 keys / 69 instances: `date` `week` `month` `health` `family` `work` `reflection`.
Only 11 notes remain in the folder; `week`(51) and `mood`(30) live mostly in `99. Archive`, so the
daily practice has been archived rather than discontinued.
- **`04. Life admin`** — 95% coverage but **120 distinct keys** over 47 notes: `bill_number`
`billing_period` `meter_number` `contract_number` `tariff` `power_contracted_kw` `total_amount_eur`.
A per-document-type shape, invented per bill rather than shared.
- **`08. Notes`** — **188 distinct keys**, the widest in the vault, because it holds unrelated
populations at once: coffee logs (17-key tasting shape), book notes, CapableMind architecture notes,
chamber material (`attributed_to` `first_cited` `chambers_cited_in` `fictional_description`).
- **`99. Archive`** — 1,070 notes, 11% coverage, 51 keys. Mostly ChatGPT exports carrying
`tags`/`type`/`aliases`/`date`/`location`/`week`/`mood`.
---
## 5. Template drift
**23 templates.** Five carry **no frontmatter at all** — `Book_Note_Template`,
`Document (PDF) note template`, `End of Day Checklist`, `GPT_Model_Selector_Template`,
`Zibaldone Note Template`. Notes made from them start with no properties.
**Four emit frontmatter that does not parse as YAML** — `PPP_Template`,
`Tasting_Log_Template_Dataview`, `Tasting_Log_Template_With_Blend`, `Weekly_Coffee_Journal_Template` —
because Templater expressions sit unquoted in value positions. Their keys had to be harvested textually.
This is upstream of §6: a template that emits invalid YAML propagates it to every note it creates.
**No template declares a key that appears on zero notes** — every declared key is in real use somewhere.
**Declared-vs-actual drift**, comparing each template against its target folder:
| template → folder | declared but absent | present (≥3 notes) but undeclared |
|---|---|---|
| Daily Note → `01. Daily` | — | `title` |
| People → `03. People` | — | `title` |
| Weekly_Review → `02. Reviews` | — | — |
| Quarterly Review → `02. Reviews` | — | `last_reviewed`, `start_date`, `week` |
| Monthly Review → `02. Reviews` | `month`, `year` | `start_date`, `week` |
| Yearly Compass → `02. Reviews` | `year` | `last_reviewed`, `start_date`, `week` |
| concept_thread → `08. Notes` | `vault_section` | 73 keys |
| Tasting_Log_Dataview → `08. Notes` | — | 60 keys |
> ⚠ **What this comparison can and cannot show.** A note does not record which template made it, so
> "target folder" is a **proxy**. It is a fair proxy for `01. Daily`, `03. People` and `02. Reviews`,
> where the folder holds one note type. It is **not** meaningful for `08. Notes`, which holds many
> unrelated populations — the "73 undeclared keys" there is an artefact of the proxy, not drift. Read
> those two rows as *not established*, not as a finding.
>
> `title` is the one clean drift signal: two templates that do not declare it, on folders where notes
> consistently carry it.
---
## 6. Notes whose frontmatter is invisible — 21
These parse as neither properties nor Dataview fields. Whatever they claim, **nothing can read it**:
`03. People/Kai Aureli Glidden Pujolràs.md` · `03. People/Lune Polymnie Marie Glidden.md` ·
`04. Life admin/Life Admin — To-Do Master List.md` · `98. Templates/Weekly_Coffee_Journal_Template.md` ·
`98. Templates/PPP_Template.md` · `98. Templates/Tasting_Log_Template_With_Blend.md` ·
`98. Templates/Tasting_Log_Template_Dataview.md` · `00a. _inbox/2025-09-13-- wild gut.md` ·
`00. Compass/…/Animal Rationis Capax/99. Archives—Previous…` ·
`00. Compass/…/ARC/Stubs & ideas/Lang…` · `00. Compass/…/ARC/Stubs & ideas/Fire…` ·
`05. Work/CV-bio/Site version of CV.md` · `04. Life admin/01. DFG/04. Health/Transition Ritual/…` ·
`04. Life admin/01. DFG/06. Passeig de Sant Joan/Facturas/Electricidad/…` ·
`08. Notes/Reflections/The Chamber as Threshold.md` · `08. Notes/Children/02. Kai/Kai – Vaccine Record.md` ·
`08. Notes/CapableMind/thinking-mirror/architecture/cold-start-ingestion-…` ·
`08. Notes/Claudia Grice/05 Taxes/…/Med…` (frontmatter is a string, not a mapping) ·
`97. Tools and Systems/04. Philosophical Curricula/Zen_Mind_Beginners_Min…` ·
`…/Ways_of_Seeing_Berger…` · `…/The_Timeless_Way_of_Bu…`
Both children's People notes are in this list.
---
## 7. Variants and near-duplicates
### 7a. Same key, different spelling
| normalised | variants (notes, verdict) |
|---|---|
| tag | `tags`(698, consumed) · `tag`(3, consumed) |
| source | `source`(86, orphan) · `sources`(5, orphan) |
| last_updated | `last_updated`(38, orphan) · `last-updated`(3, orphan) |
| related_note | `related_notes`(20, orphan) · **`related notes`**(1) — *with a space* |
| language | `languages`(13, written-not-read) · `language`(6, orphan) |
| note | `note`(19) · `notes`(7) |
| domain | `domain`(5) · `domains`(2) |
| period | `period`(6) · `periods`(1) |
| theme | `themes`(6, consumed) · `theme`(1, orphan) |
| nif | `nif`(2) · `NIF`(2) |
| consumption_kwh | `consumption_kwh`(2) · `consumption_kWh`(1) |
| linked_note | `linked_notes`(2) · `linked_note`(1) |
| tool | `tools`(1) · `tool`(1) |
### 7b. Same job, unrelated spelling
**"When was this touched" — six keys, three read, three not:**
`last_reviewed`(123, consumed) · `last_updated`(38, **orphan**) · `updated`(14, consumed) ·
`lastUpdated`(11, **orphan**) · `modified`(4, orphan) · `last-updated`(3, orphan).
**"When was this made" — six keys:** `created`(359, consumed) · `date`(163, consumed) ·
`dateAdded`(11, orphan) · `draft_created`(11, consumed) · `created_by`(9, orphan) · `date-created`(3, orphan).
**Relations — twelve keys, three read:** `related`(120, written-not-read) · `links`(77, written-not-read) ·
`related_notes`(20, orphan) · `superseded_by`(18, **consumed**) · `depends_on`(17, orphan) ·
`related_real_sources`(11) · `emerged_from`(11) · `related_threads`(9, **consumed**) · `parents`(4) ·
`relations`(3) · `linked_to`(3) · `emerged_through`(3).
**Classification — seven keys, three read:** `type`(416, consumed) · `category`(52, consumed) ·
`layout`(33, orphan) · `marker`(23, orphan) · `class`(22, consumed) · `domain`(5) · `document-type`(3).
**Provenance — eight keys, two read:** `source`(86, **orphan**) · `author`(49, consumed) ·
`origin`(34, consumed) · `source_type`(12) · `attributed_to`(12) · `first_cited`(12) · `sources`(5) ·
`provenance`(5).
**Identity:** `title`(610, consumed) · `aliases`(71, written-not-read) · `alias`(10, written-not-read) ·
`document-title`(3) · `full_name`(2).
### 7c. Three naming conventions coexist
`snake_case` (dominant) · `kebab-case` (`last-updated`, `date-created`, `document-type`,
`project-phase`, `executor-action`, `obsidian-folder`) · `camelCase` (`dateAdded`, `lastUpdated`).
---
## 8. Fields that are always empty
`focus` — 24 notes, **null on all 24**. `mood` — 30 notes, null on 26. `virtue`, `practice`, `meaning` —
6 notes each, null on all. `change_log` — an empty list on 38 of 89. These are declared and carried but
never filled.
---
## Instrument caveats
1. **"Consumed" means read by a Dataview query, a template, or Obsidian config inside this vault.** A key
read by an external tool, by an MCP client, by Claude, or by the steward's eye is invisible to this
method and would be scored ORPHAN. Every orphan verdict is therefore an **upper** bound on disuse.
2. **`08. Notes` and `06. Projects` template-drift rows are proxy artefacts**, marked in §5 as not
established.
3. **21 notes could not be parsed.** Their keys are in the textual harvest but not the shape analysis, so
§2's shape counts are a floor.
4. **This is a point-in-time census**, 2026-08-19, of the vault as it stands on disk.
*Raw data: `fm_inventory.json` (per-key shapes, samples, folders, file lists), `final.json`
(per-key consumption verdicts), `templates.json` (per-template declared keys).*