MeDiVa
DocsConcepts

Strictness

Strictness is two independent axes — presence and closure. Start lax, dial up with a single closure rule.

Hammond: "We spared no expense." Muldoon: "...the fences are only as strict as you set them."

Jurassic Park had two separate questions about every paddock: is the right animal in it? and can anything get out that shouldn't? mediva keeps strictness exactly that simple — two independent axes you compose, not a ladder of modes.

Presence

Whether a declared item must exist: required / optional / recommended. This is the base level — lax (optional) up to strict (required). Is the paddock occupied at all?

recommended sits between the two: a missing section is a warning, not an error, so the run still passes (exit 0) while nudging the author.

<!-- mdv: block recommended minWords=3 -->
## Rollback Plan
<!-- mdv: endblock -->

Omit that section and you get [missing-recommended-section] at warning severity — 0 errors, 1 warning, CI stays green. (Once the section is present, its other rules like minWords apply normally.)

Closure

Whether undeclared items are allowed. This is the perimeter fence — add one granular rule to seal the set:

elementclosure rule
checklistexactLabels
tablenoExtraCols
sectionsnoExtraSections
frontmatternoExtraKeys

Fences off, required only checks that the checklist exists and has at least one checkbox — it does not pin which items. The labels you write are just a starter template: someone can rename them, drop one, or let a clever raptor slip an extra item in, and it all still passes.

lax — checklist must exist and be non-empty; the specific labels aren't checked
<!-- mdv: taskList required -->
## Checklist
- [ ] Tests added or updated
- [ ] Docs updated
<!-- mdv: endtaskList -->

Fences on with exactLabels — exactly these two items, nothing smuggled in or left out:

strict — exactly these items, nothing else
<!-- mdv: taskList required exactLabels -->
## Checklist
- [ ] Tests added or updated
- [ ] Docs updated
<!-- mdv: endtaskList -->

Section structure

The closure rules above gate items inside one element. To gate the sections themselves — which headings exist, and in what order — reach for the scope-level structure atoms on a document or block: noExtraSections (no undeclared sections), ordered (declared order), and strict (both at once), with freeText to opt a scope back out.

<!-- mdv: document strict -->

<!-- mdv: block required minWords=5 -->
## Summary
<!-- mdv: endblock -->

<!-- mdv: block required minWords=5 -->
## Changes
<!-- mdv: endblock -->

strict here means exactly Summary then Changes, nothing else. Slip in a ## Notes and you get [unexpected-section]; swap their order and you get [out-of-order] — the bridge won't accept a mission log with the decks rearranged. See the structure atoms reference for the full set, including repeat/repeat=N for repeating sections and requiredWhen for conditional ones.

Conditional sections

Some sections should only be mandatory when a switch is thrown. requiredWhen makes a section required only when a condition elsewhere in the document is met — a checkbox is ticked, or a frontmatter key matches a value. The rest of the time the section can be omitted entirely.

Migration Notes is required only if 'Breaking change' is checked
<!-- mdv: choice required oneChecked -->
## Type of Change

- [ ] Bug fix
- [ ] Breaking change
<!-- mdv: endchoice -->

<!-- mdv: block requiredWhen.checked="Breaking change" minWords=5 noPlaceholder -->
## Migration Notes

Describe what breaks and how to migrate.
<!-- mdv: endblock -->

Tick Bug fix and a PR with no Migration Notes passes. Tick Breaking change and the same omission fails with [missing-section]"required when 'Breaking change' is checked." The frontmatter form is requiredWhen.<key>=<value>, e.g. requiredWhen.type=incident to demand a Postmortem section only on incident reports. This is the escape hatch from a blunt required: the slot appears on the form only when the mission actually calls for it.

How to adopt

Start lax — required only — so a team can integrate without a fight (nobody likes a perimeter fence on day one). Add the closure rule per element once the shape settles, and use Severity overrides (warn=, error=, off=) as the per-diagnostic complement. You rarely need a single global "strict" switch; reach for the one fence that matters. Clever girl.

Do not turn every fence on by default: avoid exactLabels while a checklist template is still changing, avoid noExtraSections on human-authored docs, and add closure only where extra content is actually harmful. A release checklist may need a locked paddock; a design note probably needs room to breathe.

On this page