Overview
Frontmatter carries the type, status, provenance, and dates that every query, audit, and agent workflow reads. It is never optional and never partly filled. This page covers the schema; the folder each type lives in is set in vault-architecture.
Declare type on every note and file notes by type
Every note has a type, and every type declares its folder in the spec. A note with no type evades every per-type rule; a note outside its folder breaks folder-scoped queries.
---
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 the block from a template (obsidian-templates); hand-typed frontmatter is where drift starts.
Require different fields per type
Required fields are declared per type in the spec and enforced by the auditor. A single global list 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) |
Require the fields a hurried author would skip: confidence on an atom, sources on a claim, alternatives_considered on a decision. They are what make the note worth keeping, and a machine check beats trust. Missing fields surface as rule C008 (vault-audit).
Write empty arrays, not missing keys
An absent key and an empty list mean different things to a query. counter_evidence: [] says “checked, none found”; a missing key says nothing. The same holds for null: outcome: null on an unresolved decision is a filled field. Write dates as YYYY-MM-DD and ids as minute-precision timestamps so string order matches time order.
Extend the base type per framework
A rigor framework adds fields to the base type; it does not create a parallel schema.
# 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: falseFields that gate each other travel together. publishable, corroboration_count, and legal_review_status are one unit; flipping publishable alone produces a critical finding. Framework choice is in rigor-frameworks.
Quote values that YAML 1.1 parsers coerce: unquoted publishable: yes parses as boolean true.
Remove fields nothing queries
An always-empty, never-read field is bloat, and bloat trains authors to skip frontmatter. In the monthly review, drop any field no query touches and no audit checks. Adding a field is cheap; making it required is a migration, covered in vault-evolution.