Skip to content

Markdown formatting for docs and skill prose

State: open/active

  • Markdown in scope follows one settled formatting rule set — ATX headings, - bullets, explicit numbering, wikilinks for entities, language-tagged fences, hand-formatted tables, quoted-schema_version frontmatter, no raw HTML, prose wrapped at 100 — chosen for Obsidian-first authoring in D-0008-markdown-standard.

Every markdown file under the scoped paths conforms to the rule set decided in D-0008-markdown-standard:

AxisRule
HeadingsATX (#…######); exactly one H1, matching the frontmatter title. No Setext.
Line lengthWrap prose at 100 columns. Tables, fenced code, headings, link targets, and frontmatter are exempt — never reflow them.
Unordered lists- only.
Ordered listsExplicit numbering (1. 2. 3.), not lazy (1. 1. 1.).
LinksInline ([text](url)) for external URLs; wikilinks (…) for catalogued entities. No reference-style links.
Block-idsLine-terminal ^anchor at the end of the tagged block.
Transclusionfile / file; never a pasted copy.
Code fencesTriple-backtick with a language tag; no indented code blocks.
TablesHand-formatted; not reflowed and not width-limited by any tool.
FrontmatterYAML between --- fences; schema_version quoted; block-list style for tags / related / applies_to.paths. The entity schema is authoritative on shapes.
HTMLNo raw HTML elements. <…> placeholder notation and angle brackets inside code/wikilinks are not HTML and are allowed.
Trailing whitespaceStripped.
Final newlineExactly one trailing \n.
Wikilink rename safetyPer D-0002-entity-identifier-shape — the id is the stable anchor; the slug never tracks title changes.

The rule set also inherits three authoring rules from docs/CLAUDE.md and may not soften them:

  • Be Succinct — succinct but fully explanatory prose; avoid modifiers that add nothing.
  • Use Structure — prefer a table over a free-form list for parallel-shape content.
  • Naming — refer to the project as SDLC (uppercase).

The corpus drifts on formatting, costing per-PR re-litigation and tripping Obsidian (block-ids, frontmatter, table reflow). A settled rule set lets a reviewer cite instead of re-argue, and gives the future formatter (T-0007/T-0008) an unambiguous target. The full rationale, per-axis tradeoffs, and Obsidian-compatibility analysis live in D-0008-markdown-standard.

Enforcement is split three ways; honor the right track per rule:

TrackRulesHow
FormatterList markers, ordered-list explicitness, code-fence form, trailing whitespace, final newline, prose line-length (tables/code/headings exempt)rumdl (D-0011-markdown-formatting-tool), configured by .rumdl.toml at the repo root. Writes on every commit via the markdown-fmt lefthook step, and on demand via /markdown-format or just fmt-markdown. Checked read-only by the root:guard-markdown-fmt CI guard, the sdlc.yaml quality gate, and moon run root:fmt-check.
Schema validatorFrontmatter shapes (schema_version quoting, list styles), id/filename shapesdlc entities validate (solutions/ontological/lib/model/ops/validate.ts) and the identifier audit (sdlc entities check-identifiers) — already live; the markdown formatter does not own these.
Reviewer (subjective)Be Succinct, Use Structure, SDLC-uppercase naming, HTML prohibition, wikilink-vs-inline choiceHuman review. A spell-check target may assist with SDLC casing; the judgment stays with the reviewer.

The formatter is rumdl, chosen in D-0011-markdown-formatting-tool and wired in by T-0008. One command owns the corpus: the root package.json declares format:md and format:md:check, and the CI guard, the sdlc.yaml quality gate, the root fmt / fmt-check verbs from S-0013-baseline-task-vocabulary and the fmt-markdown / check-markdown justfile recipes all delegate to it, so the layers cannot drift apart. The rule set lives in .rumdl.toml; bumps to the pinned rumdl@0.2.77 are gated by the sdlc gate markdown-fixtures regression fixtures.

.rumdl.toml is also the single authority for what is never formatted, and its excludes apply even to explicitly named paths — so the gate names broad top-level trees and a new package or app is covered on arrival rather than silently missed. Five kinds of thing are excluded: generated build artifacts, fixtures whose markdown IS the assertion, render demos that display the very constructs the formatter has opinions about, subtrees under another project’s formatting regime (solutions/determined), and .mdx, which belongs to prettier.

This Standard is open/active: the formatter mechanically enforces the Formatter-track rules on every commit. Two classes of rule stay disabled with a note in .rumdl.toml. Broken relative links (MD057/MD051/MD052) await a link-repair follow-up per D-0011-markdown-formatting-tool. MD018 is off because its fix invents headings rather than correcting them: reflow moves a #token to the start of a line, MD018 adds the space that turns it into a heading, and MD025 demotes the result — splitting a sentence and inserting a section nobody wrote.

  • Setext heading — Title underlined with ==== instead of # Title. Violates the ATX-only rule; breaks reliable Obsidian heading transclusion for H3+ siblings.
  • Lazy ordered list — 1. 1. 1. for three steps. Violates the explicit-numbering rule; renders inconsistently in source view.
  • Reflowed table — a tool rewraps a table so every row fits 100 columns, exploding the diff. Violates the tables rule (hand-formatted, never reflowed) and the line-length exemption.
  • Raw HTML — <br> or <details> in a docs/ file. Violates the HTML prohibition. (<basename> in prose or Record<string> in a code span is not a violation — those are placeholder/code notation.)
  • Reference-style link — [text][ref] with a [ref]: url footnote for an external URL. Violates the link-style rule; use an inline link.

← Back to Standards