---
title: "Vault Frontmatter Schema"
slug: "vault-frontmatter-schema"
category: "knowledge-vaults"
tags: ["knowledge-vaults", "frontmatter", "yaml", "schema", "metadata", "obsidian"]
status: "stable"
last_updated: 2026-08-29
summary: "Type every note in YAML, give each type its own required-field set, write empty arrays over missing keys, and extend the schema per framework."
related: ["[[knowledge-vaults/vault-architecture]]", "[[knowledge-vaults/atomic-notes]]", "[[knowledge-vaults/vault-audit]]", "[[knowledge-vaults/rigor-frameworks]]", "[[knowledge-vaults/vault-evolution]]", "[[tooling/obsidian-templates]]", "[[meta/llm-info-standard]]"]
---

## Overview

Frontmatter is the spine of a vault. It carries the type, the status, the provenance, and the dates that every query, audit, and agent workflow reads. Frontmatter is never optional and never partially filled. This page covers the schema discipline; the folder each type lives in is set in [[knowledge-vaults/vault-architecture]].

## Type every note in frontmatter and file it by type

Every note declares `type`, and every type declares its folder in the vault spec. Those two facts together make the vault checkable: a note whose `type` is missing evades every per-type rule, and a note filed outside its type's folder breaks every folder-scoped query.

```yaml
---
id: 202608291430          # YYYYMMDDHHmm, generated by the template
title: "Full title as a claim"
type: atom
status: status/seedling
created: 2026-08-29
modified: 2026-08-29
domain: [finance/macro]
sources: ["[[@minto-1987-pyramid-principle]]"]
related: ["[[mece-issue-tree]]"]
confidence: medium
last_verified: 2026-08-29
decision_relevant: false
---
```

Generate this block from a template on note creation rather than typing it. Hand-typed frontmatter is where schema drift starts. See [[tooling/obsidian-templates]] for the template mechanics.

## Give each note type its own required-field set

Required fields are per type, declared in the spec, and enforced by the auditor. A single global required list either under-constrains atoms or over-constrains daily notes.

| Type | Required beyond id, title, type, created |
| --- | --- |
| atom | `status`, `sources`, `confidence` |
| source | `source_type`, `author`, `year`, `atoms_extracted` |
| claim | `sources` (non-empty), `confidence`, `last_verified` |
| decision | `decision_date`, `chosen_option`, `alternatives_considered`, `key_atoms`, `key_assumptions`, `expected_outcome`, `confidence_at_decision` |
| contradiction | `atoms_in_tension`, `resolution_criteria` |
| question | `status` (open, answered, abandoned) |

The load-bearing fields are the ones that would otherwise be quietly skipped. `confidence` on an atom, `sources` on a claim, and `alternatives_considered` on a decision are all fields a hurried author drops, and all three are exactly the fields that make the note worth keeping. Requiring them machine-checks the discipline instead of trusting it. See [[knowledge-vaults/vault-audit]] for how missing fields surface.

## Write empty arrays, never missing keys

An absent key and an empty list mean different things to a query engine, and the difference silently corrupts results. `counter_evidence: []` says "checked, none found." A missing `counter_evidence` says nothing at all.

The same rule covers nulls: `outcome: null` on an unresolved decision is a filled field. Dates are always `YYYY-MM-DD` and ids are always a minute-precision timestamp such as `202608291430`, so string sorting matches chronological sorting everywhere.

## Extend the schema per framework rather than per note

When a rigor framework applies, it adds fields to the base type rather than creating a parallel schema. An engineering vault adds ADR fields to its decision atoms; a journalism vault adds source-tier and corroboration fields to its claims.

```yaml
# Software and engineering (ADR)
adr_status: proposed | accepted | deprecated | superseded
superseded_by: ["[[ADR-...]]"]
blast_radius: small | medium | large

# Investigative research (source credibility)
source_tier: primary-document | on-record | on-background | anonymous
corroboration_count: 2
legal_review_status: not-reviewed | in-review | cleared | held
publishable: false
```

Field groups that gate each other travel together. `publishable`, `corroboration_count`, and `legal_review_status` are one unit: flipping `publishable` without the other two produces a critical rather than a publishable claim. Framework selection is covered in [[knowledge-vaults/rigor-frameworks]].

Quote values that YAML would coerce. Unquoted `publishable: yes` parses as boolean `true`, not the string `"yes"`.

## Remove fields that stop being queried

A field that is always empty and never read is schema bloat, and bloat trains authors to skip frontmatter. During the monthly review, drop any field no query touches and no audit checks.

Adding a field is cheap; making it required is a migration. Add it to the required set, run the audit to get the exact backfill list, fill values honestly, then re-run and confirm the count returns to zero. Never backfill a fabricated default: a `last_verified` set to today on a claim verified two years ago is a lie the schema will now vouch for. The full procedure is in [[knowledge-vaults/vault-evolution]].

## Related

- [[knowledge-vaults/vault-architecture]]
- [[knowledge-vaults/atomic-notes]]
- [[knowledge-vaults/vault-audit]]
- [[knowledge-vaults/rigor-frameworks]]
- [[knowledge-vaults/vault-evolution]]
- [[tooling/obsidian-templates]]
- [[meta/llm-info-standard]]
