The proposed metadata vocabularies
docmeta is a CLI that validates the presence and format of document metadata (frontmatter) against JSON Schema, in CI. Its built-in schemas have always transcribed contracts other people published: Hugo’s front matter, DITA’s prolog, Open Graph. This proposal adds the first vocabularies docmeta would publish itself. They cover the facts a docs set needs to stay maintained and readable by machines. Those are ownership, review, audience, applicability, lifecycle, relationships, AI provenance, and quality checks. No site generator defines those facts, and no standard owns them.
The nine vocabularies
Section titled “The nine vocabularies”The nine are designed as one family. They share the same conventions, and no two of them claim the same key. They are split by intent, so that each one is a separate decision to adopt. Six describe a page. Three carry quality and knowledge-graph metadata that any grader, graph builder, or CI tool can implement. Each has its own page (the sidebar lists all nine) with its fields, examples, design rationale, and its own questions for reviewers:
| Id | The question it answers | Fields |
|---|---|---|
docmeta:core:1.0.0-proposal.3 |
What is this page? | title* · description* · id · type · keywords · language · locale |
docmeta:stewardship:1.0.0-proposal.2 |
Is it cared for? | authors · owner · stakeholders · reviewed-by · created · last-updated · last-reviewed · review-interval · verified-against · source-of-truth |
docmeta:audience:1.0.0-proposal.1 |
Who does it serve, and who may see it? | audiences · personas · journeys · intent · visibility |
docmeta:lifecycle:1.0.0-proposal.1 |
Where is it in its life? | lifecycle · replaced-by · supersedes · remove-by |
docmeta:structure:1.0.0-proposal.1 |
What does it connect to? | applies-to · not-applicable-to · concepts · prerequisites · next-steps · related-pages |
docmeta:ai-context:1.0.0-proposal.1 |
How did machines make it, and how may they use it? | generated-by · provenance · risks · sample-questions |
docmeta:evals:1.0.0-proposal.2 |
What must be true of this page? | evals · eval-suite · eval-skip · eval-provenance |
docmeta:kg:1.0.0-proposal.1 |
What does the knowledge graph know about it? | kg, one closed block: SKOS concepts, iiRDS typing, PROV provenance |
docmeta:artifact-evals:1.0.0-proposal.2 |
What must a session using this artifact have done? | metadata.evals · metadata.eval-skip · metadata.eval-provenance |
Four families have moved past 1.0.0-proposal.1. Those are core (now
1.0.0-proposal.3), evals and artifact-evals from review round 6, and
stewardship from round 9. The other five stay where they started, because
a bump would announce a revision none of them made.
All nine are intended for docmeta’s default set, the schemas a run uses
when no schema is configured. Such a run would then require every page
to carry a non-empty title and description. Those are the only two
required fields in the family. The run would also validate any other
family key a page chooses to carry. A page with only the required pair
stays valid, because the other eight vocabularies require nothing until
you use their keys.
What a fully-annotated page looks like
Section titled “What a fully-annotated page looks like”---title: Install the operator on Kubernetesdescription: Deploy the operator with Helm and verify the rollout.type: how-toowner: platform-docsstakeholders: [jane.doe, pm-alex]reviewed-by: [sam.reviewer]created: 2025-11-04last-updated: 2026-08-20last-reviewed: 2026-08-20review-interval: P90Dverified-against: operator 1.4.2source-of-truth: https://github.com/example/operator/tree/main/helmaudiences: [administrators]personas: [persona-platform-admin]intent: Deploy the operator on a running clustervisibility: publiclifecycle: publishedapplies-to: [operator-1.4, kubernetes]concepts: [Operator, Helm chart]prerequisites: [create-api-token]related-pages: [operator-architecture]generated-by: claude-fable-5provenance: - generated-by: claude-fable-5 fields: [intent, sample-questions] confidence: { intent: 0.9, sample-questions: 0.84 }risks: [privileged, cost-incurring]sample-questions: - How do I install the operator on EKS?evals: - id: install-verified assertion: The Helm install steps produce a Ready operator pod. grader: human severity: warningkg: label: Operator installation broader: [Operator] type: task---Every key above is optional except title and description. A page
that carries only those two is valid. Each further key is a step you
take when you are ready for it.
The principles behind every field
Section titled “The principles behind every field”- Weak floors teach bad habits. A default that accepts an empty
title teaches the habit it exists to prevent. So
titleanddescriptionare required, every string the core vocabulary defines must be non-empty, andtypeandlanguagetake a single value. This is stricter than the loosest schemas that share those keys: Docusaurus permits an empty title, and Dublin Core allows repeated elements. The family’s compatibility rule is that a document valid under another built-in schema stays valid under these vocabularies. These strictness choices are the only exceptions to that rule, and an automated check records each one. - One value is a string; many values are a list. This holds for every field, with no per-field exceptions to remember.
- Claim content, never rendering. There is no
slug,layout,image,tags, ordering, or navigation here. The generator owns how a page is displayed and where it sits. These vocabularies only describe what a page is. - Derivable facts lie. There is no
datekey and no stored review deadline.last-reviewedplusreview-intervalgive the due date, so a stored copy could only agree with them or lie. Review round 9 held the document’s own dates up against this and put them back.createdandlast-updatedsit in stewardship, because git’s timestamps describe the path rather than the document. - Facts live at their altitude. A fact belongs at the level that
owns it. Reader expertise belongs in your persona definitions, not on
every page. Style guides belong in config.
stakeholdersstays at page level because the right people to consult differ from page to page. - Enumerate only what is switched on and bounded.
visibilityandlifecycleare the only enums this family invents, because something downstream branches on each value. Fields with recommended but open values, such asrisksand the artifact grader family, use an open list. The recommended values feed editors and tooling, and any other string stays legal. A consumer that meets an unknown value should treat it as a caution rather than as nothing. - Compose, don’t duplicate. Content classification is three layers, each
owned by the schema that published it. Those are
typefor what the page is, Seven-Action’sactionfor what the reader is doing, andintentfor the specific job. - Deeper wins. Where the
kgblock and a page field describe the same fact (type,concepts,applies-to), the declaration inside the block wins and the page-level field is the fallback. - Machines propose; humans retire the provenance. A
provenanceentry names the model that proposed some fields and its confidence in each. Humans delete the entry once they have reviewed those fields. The pattern appears at page level, in the graph block, and in both eval vocabularies. A surviving entry means machine-written metadata that nobody has checked yet.
Quality contracts, on pages and on agent artifacts
Section titled “Quality contracts, on pages and on agent artifacts”The same eval vocabulary covers documentation pages and the instruction artifacts (skills, agent definitions) that agents run with:
# a docs pageeval-suite: how-toevals: - id: install-command-current assertion: The documented install command matches the current package name. - id: links-resolve grader: command command: ["npx", "linkinator", "{file}"]# a SKILL.md: the host tool owns the top level, so evals nest under metadatametadata: evals: - id: used-read assertion: The session read at least one source file before editing. grader: tool-usage options: { tool: Read, expect: used } - Reproduce the bug with a failing test before applying the fix.Entries share one shape on both sides: id, assertion, type,
severity, evidence, examples, target, weight, runs, model,
and a per-entry skip. The assertion rule is the same on both sides too:
ai, human, and entries with no grader require one, and command
requires an assertion or a command. The two sides differ in their grader
families and in what target can select. Pages are graded by ai,
command, human, or a tool:* integration. Sessions are graded by
ai, human, command over the trace, or a deterministic session grader
such as tool-usage or cost. The tool:* spelling is accepted on both
sides, so one grader name works for page and artifact evals.
What we most want your opinion on
Section titled “What we most want your opinion on”These are the calls we consider most contestable, in the order we expect debate:
- Applicability is flat.
applies-to: [operator-1.4, kubernetes]uses flat labels. Named dimensions (product, deployment, generation) were designed and then removed, with prefix labels such asdeploy:kubernetesas the escape hatch. Is that too flat? lifecycleis a closed enum (draft · published · deprecated · archived). It catches typos and makes the rule “a deprecated page must name a successor or a removal date” enforceable. It also rejects anexperimentalorretiredstage unless you override the key.risksholds assurances too.read-onlyandidempotentsit in a field called risks. The reasoning: an unannotated page has not been assessed, which is different from being safe. Does the name survive?- The whole family ships in the default set. A
docmeta validaterun with no schema configured would fail pages that cannot say what they are called or what they are for. That is the one hard requirement. It would also validate any other family key a page already carries, and a baredocmeta fillwould propose the full menu. Is a family-wide default the right level of aggressiveness? stakeholdersat page level. These are the people to consult about this page, distinct from project-level stakeholder lists, which stay in project docs.
How to review
Section titled “How to review”Open an issue on hawkeyexl/docmeta. Field-level nitpicks are as welcome as structural objections. The complete design record is in proposal 0023, and the design notes beside it. That covers every cut and rename, plus the runnable example sets that verify each schema. Registration waits for this review to conclude.