CLI
Run mediva check in a terminal or CI — validate files against a contract, get an exit code and exact diagnostics.
MOTHER, the Nostromo's computer, never sleeps. She doesn't argue, doesn't editorialize — she scans what's in front of her and reports exactly what's wrong.
mediva checkis your MOTHER for Markdown: point it at a file, get back a verdict and an exit code.
npx mediva check <files...> --schema <contract.mdv.md>Examples
# one file
npx mediva check README.md --schema readme.mdv.md
# zero-config scan: every X.mdv.md beside X.md
npx mediva check
# shell-expanded files — sweep the whole docs deck at once
npx mediva check docs/**/*.md --schema docs.mdv.mdThe zero-config scan
Run mediva check with no file arguments and it sweeps the deck like MOTHER walking the ship: it walks the current directory downward and validates every X.md that has a sibling X.mdv.md contract beside it. No config file, no glob list to maintain.
What the scan skips while it walks:
node_modulesanddist— dependencies and build output are never scanned.- Any hidden directory (a name starting with
.):.git,.next, editor state,.claudeworktrees, and so on. - Any directory containing a
.mdvignorefile — that whole subtree is pruned, like a.gitignore-marked area. Drop a.mdvignoreinto a folder of intentionally-invalid fixtures to keep them out of the scan. - Symlinked directories are not followed, so a symlink loop can't hang the walk.
A pruned area is still reachable by explicit path: npx mediva check .git/HOOKS.md --schema h.mdv.md validates a file the bare scan would skip. The scan only pairs true siblings — an X.mdv.md with no matching X.md is left alone, and the CLI does not expand globs itself (let the shell do that, as in the last example above).
Output
By default mediva prints human diagnostics and a summary — a calm readout on the bridge display:
README.md:1 error [empty-section] Empty section
The "Installation" section has a heading but no content under it.
fix: This heading promises content to the reader. Write the actual details for this section. If no information genuinely exists yet, write `Not specified.` — do not invent content to fill the gap.
1 error, 0 warningsAdd --json for machine-readable output (stable diagnostic codes), suitable for tooling — pipe it straight into your own dashboard:
npx mediva check README.md --schema readme.mdv.md --json | jq '.results[].diagnostics[].code'SARIF
--sarif makes check emit SARIF 2.1.0 for code-scanning upload, including the schemastore $schema, runs[].tool.driver.name = "mediva", rule descriptors, and defaultConfiguration.level mapped from mediva severity (error → error, warn → warning). It is a check output mode, and it takes precedence if both --json and --sarif are passed:
npx mediva check README.md --schema readme.mdv.md --sarif > mediva.sarifExit codes
0— no errors. Self-destruct averted; bay doors open.1— one or more errors.2— usage or configuration error: unknown command, bad option, missing value, unreadable file.
That makes mediva check a drop-in CI gate. See Recipes → PR bodies for a GitHub Actions example, issue forms for --title, monorepo CI for the zero-config scan, and changelogs for explicit-file checks.
Commands
check— validate explicit files, or auto-discover everyX.mdv.md→X.mdsibling pair when run with no file arguments.render --schema schema.mdv.md [-o out.md]— strip mdv comments into plain Markdown.highlight file.md [--no-color]— colourise mdv directives for a terminal.show schema.mdv.md— print the contract in plain words.explain minWords— show what a rule or field kind means (it resolves rules and internal field kinds, not surface tag names).init [dir]— scaffold.githubPR/issue templates, a GitHub Action, and a README schema (and a starter README if one is missing). The one-command way to put mediva on a repo — see Mediva CI.
Options
--schema <file>— validate or render against an explicit contract.--title "..."— the titletitle*rules validate against. These rules read only the title you pass in (via--title, orcontext.titlein a--contextfile) — they do not fall back to the document's first#heading. Without a title supplied,document titlereportsmissing-title. Pass the PR/issue title (or the document's own heading text) explicitly.--context <file>— pass JSON context for issue-state rules.--json— emit machine-readable diagnostics forcheck.--sarif— emit SARIF 2.1.0 diagnostics forcheck.-o <file>— writerenderoutput to a file instead of stdout.--no-color— disable ANSI colour forhighlight.-h,--help·-v,--version.
External context
Rules that inspect the outside world need a little telemetry from your ship. issueState=open checks a Fixes #N reference against context.issues; without context, mediva reports missing-context instead of guessing.
Pass that context as JSON:
{
"issues": [{ "number": 123, "state": "open" }],
"title": "Ship the docking checklist"
}npx mediva check PR.md --schema pr.mdv.md --context context.json--title "..." is the shortcut for setting context.title, which is what the title* rules validate. There is no first-#-heading fallback: if neither --title nor a context.title is supplied, a title rule fails with missing-title. When the title you want to check is the document's H1, either pass it with --title, or enforce the heading in-document with a block heading.level=1 heading.pattern=/…/ instead of a document title rule.