MeDiVa
DocsConcepts

Frontmatter

Validate YAML metadata keys with front directives, including presence, allow-lists, dates, placeholders, patterns, and closure.

Bishop: "I may be synthetic, but I'm not stupid." Metadata deserves the same treatment: small rules, clear boundaries, no mystery cargo in the hold.

front declares rules for YAML frontmatter. It is a structural marker, written as front <key> for one metadata key, or as bare front noExtraKeys to close the whole metadata set. It has no end tag.

The frontmatter reader handles the common subset — the leading --- … --- block with top-level key: value pairs. Nested maps, lists, and block scalars are out of scope for the front <key> rules, which target one top-level key each.

<!-- mdv: front status required oneof=draft,review,published -->
<!-- mdv: front date date=iso -->
<!-- mdv: front noExtraKeys -->

That contract says:

  • status must exist, and it must be draft, review, or published.
  • date must be an ISO date if it is present.
  • no other frontmatter keys are allowed.

It validates a document like this:

---
status: review
date: 2026-06-28
---

# Mission log

What it catches

Point that same contract at a document where the metadata is wrong on every axis:

---
status: shipped
date: last-tuesday
author: dana
---

# Mission log
mission.md:1  error  [frontmatter-not-allowed-value] The frontmatter key "status" is "shipped", which is not an allowed value (draft, review, published).
mission.md:2  error  [frontmatter-bad-date] The frontmatter key "date" is "last-tuesday", which is not an ISO date.
mission.md  error  [unexpected-frontmatter-key] The frontmatter key "author" is not one the schema declares.

Two more cases worth knowing:

  • A missing or empty required key both report [missing-frontmatter-key] ("required, but is missing or empty") — an empty status: is treated the same as omitting it.
  • A duplicated key emits a [duplicate-frontmatter-key] warning, and the first value is the one validated — so a stray second date: doesn't silently override the real one.

Rules

rulewhat it checks
requiredthe key must be present
optionalthe key may be absent
oneof=a,b,cthe value must be one of the listed options
date=isothe value must be ISO-shapedYYYY-MM-DD or a full timestamp. A regex check, not a calendar check, so an impossible date like 2026-13-99 still matches. It is a content concern (the real date is human-owned), so it surfaces under validateState, not validateSyntax
noPlaceholderplaceholder values like TODO or TBD are rejected
pattern=/regex/the value must match the regex
front noExtraKeysno frontmatter key is allowed unless the contract declares it

Use front noExtraKeys when the metadata shape is part of the contract, like a release note with exactly status and date. Leave the fence open when authors need room for local metadata from another tool.

On this page