File kinds and schemas
Tag each file with a kind, then validate its headings and front matter against a schema declared inline on the kind or shared via a proto.md template — so a whole directory obeys one contract.
Not every Markdown file plays the same role. A plan is not a rule
README, and a release-channel page is not a guide. A per-file
style linter treats them all alike: it catches a long line, but
not a missing Decision section or an invented status value. A
directory of similar files drifts as it grows.
A kind gives each file a role; a schema gives that role a
contract. Bind files to a kind by a front-matter kinds: field or
a kind-assignment glob. The kind’s schema then constrains
required headings, section order, and front-matter fields. Declare
it inline on the kind, or share it from a proto.md template so a
whole directory validates against one source of truth.
For example, an rfc kind can declare its schema inline in
.mdsmith.yml:
kinds:
rfc:
schema:
frontmatter:
status: '"draft" | "ratified" | "deprecated"'
sections:
- heading: "Context"
- heading: "Decision"Tag a file with that kind:
---
kinds: [rfc]
status: approved
---
# RFC-0007: Adopt structured logging
## Context
We keep losing requests in unstructured log lines.This file breaks the contract twice. approved is not an allowed
status. The required Decision section is missing. MDS020
reports both:
RFC-0007.md:3:1 MDS020 status: got "approved", expected one of: "draft", "ratified", "deprecated"
RFC-0007.md:7:1 MDS020 ## Decision: got <missing>, expected section to be presentSchemas go further: they nest sections, repeat them, and inherit from a parent. See the file-kinds guide and the schemas guide for the full vocabulary.