Retrofit docmeta into an existing docs repo
Adding metadata validation to a mature docs repo has a chicken-and-egg problem. The reason you want validation is that the existing metadata is inconsistent: fields missing, values fat-fingered, no enforcement. But if your very first CI run holds every page to a strict standard, hundreds of long-lived docs fail at once and the gate is unmergeable before anyone has written a single new line.
The way through is to adopt incrementally. Land a permissive schema that the repo already satisfies, so the build is green on day one and the gate is real. Then tighten the standard over time, on your schedule, while the gate quietly catches new regressions from the start.
Step 1: Start with a permissive schema
Section titled “Step 1: Start with a permissive schema”The built-in google:okf:0.1 schema requires a single field, type. That is lenient, but on a repo that has never enforced metadata, even one required field may fail a lot of pages. For a true day-one-green adoption, start from a schema that requires nothing and tighten from there.
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "required": [], "properties": { "type": { "type": "string", "minLength": 1 }, "title": { "type": "string", "minLength": 1 } }}This schema requires no field. It only checks format when a field is present, so a title: that is accidentally empty fails, but a doc with no title at all passes. You get format enforcement immediately without demanding any field be filled in yet.
Point your config at it:
paths: - "docs/**/*.md"
schemas: - ./schemas/permissive.jsonRun a full pass to confirm the repo is green as it stands:
npx docmeta validateIf something still fails here, it is a genuine format problem (a malformed timestamp, an empty required-by-you field), not a missing-field avalanche. Fix those few, and your baseline is clean.
Step 2: Wire the CI gate
Section titled “Step 2: Wire the CI gate”With a green baseline committed, add the gate now, before the standard is perfect. docmeta exits 0 when everything passes and 1 when a file fails, so any CI system can use a bare docmeta validate as a pass/fail step. Wiring it early means the gate starts catching regressions immediately, even while the schema is still permissive.
npx -y docmeta validate --format githubThe --format github flag turns failures into inline annotations on the pull-request diff. The full recipe (workflow file, the exit-code contract, and annotation behavior) lives in the CI track; copy it instead of assembling your own.
Step 3: Scope what gets checked
Section titled “Step 3: Scope what gets checked”A real repo has files you do not want to validate yet: archived content, generated pages, drafts. Narrow the gate with paths and exclude so it covers only what you are ready to stand behind on day one, then widen it as you go.
-
Limit
pathsto the areas you have reviewed. Thepathskey is the fallback target set when no paths are passed on the command line. Point it at the subtree you have confirmed is green rather than the whole repo.docmeta.config.yaml paths:- "docs/guides/**/*.md" -
Exclude the corners you are not ready for. Your
excludeglobs merge with docmeta’s built-in ignores (**/node_modules/**and**/.git/**are always skipped) and add to them.docmeta.config.yaml exclude:- "**/drafts/**"- "docs/archive/**"
Exclusions are how you sequence the rollout. You bring each subtree under the gate when its metadata is clean, instead of blocking the whole adoption on the messiest folder.
Step 4: Roll out folder by folder
Section titled “Step 4: Roll out folder by folder”You rarely tighten the whole repo at once. Use per-folder overrides to hold a stricter schema where the metadata is already clean, while the rest of the repo stays on the permissive default. New and well-maintained areas adopt the real standard first; legacy areas catch up on their own timeline.
# Permissive default for the long tail.schemas: - ./schemas/permissive.json
# Stricter rule for an area that is already clean.overrides: - files: "docs/guides/**/*.md" schemas: - ./schemas/guide.jsonFiles under docs/guides/ are held to guide.json (which can require type, title, and more); everything else stays on the permissive default. As another area reaches full coverage, add an override for it, or widen an existing glob. Overrides are evaluated in order and the first matching glob wins, so order them most-specific first.
Step 5: Ratchet strictness over time
Section titled “Step 5: Ratchet strictness over time”The permissive schema was only ever a starting line. Once an area is under the gate and contributors are keeping it clean, tighten the standard: add a recommended field, then make it required when coverage is high. Do this one field at a time so the build never takes a big hit.
The staged technique has its own guide: validate a field’s format first, drive coverage, then promote it to required. Follow it each time you raise the bar.
Step 6: Close the backlog with fill
Section titled “Step 6: Close the backlog with fill”Ratcheting works because new pages arrive already compliant. It does nothing for the pages that were already there, and on a mature repo that backlog is most of the docset. Typing description: into four hundred existing files by hand is the reason adoption stalls at step 5.
docmeta fill works that backlog down. For each page it resolves the same schema set the gate uses, asks an LLM to infer the properties that are missing or invalid, and writes back only the values it is confident about. Because the schema drives the prompt, the fields it proposes are exactly the ones you are about to require.
Preview before you trust it:
docmeta fill docs/reference/ --dry-run✓ docs/reference/api.md /description Reference for the public HTTP API. 0.93 below 0.7: /resource 0.41
anthropic/claude-sonnet-4-5 · Threshold 0.7 · 12 files · 9 fields would be written · 7 skippedThen run it for real on one folder at a time, and review the diff like any other pull request:
docmeta fill docs/reference/ && git diffValues below the threshold are skipped, and the report lists each one by name and score. Those pages genuinely need a human, and now you have a short list of them to work through. Raise --confidence when you want only near-certain values:
docmeta fill docs/reference/ --confidence 0.9 --dry-runRe-running at a different threshold re-scores the cached proposals, so tuning the gate costs nothing after the first pass.
Once a folder is filled and reviewed, promote its field to required using the ratchet from step 5. fill is what makes that promotion cheap.
What you have now
Section titled “What you have now”A repo that went green on day one, a CI gate that has been catching regressions since before the standard was finished, a folder-by-folder path to the stricter rules you actually want, and a way to clear the existing backlog without a data-entry marathon. You adopted docmeta without a flag day and without a backlog of red checks blocking everyone’s work.