ExQuality.Stages.Diataxis (ExQuality v0.16.0)

Copy Markdown View Source

Checks that each page under a documentation quadrant reads as the kind of page its folder says it is: a tutorial teaches, a how-to guide shows the steps to a goal, a reference page describes, an explanation gives reasons.

Pages drift between kinds one helpful paragraph at a time, and a model-based audit catches that only when someone runs it. This stage is the cheap, deterministic half: it counts a fixed list of language cues on each page and reports a page whose cues point clearly at another kind.

✓ Diataxis: 12 pages, each reads as its type (0.0s)
✓ Diataxis: 1 warning: how_to_title at docs/guides/upgrade.md:1 (0.0s)
✗ Diataxis: 2 problems (0.0s)

What it reads

The front matter of .claude/diataxis.md, the project's documentation manifest, for its quadrants: map:

---
quadrants:
  tutorials: docs/tutorials
  how_to: docs/guides
  reference: docs/reference
  explanation: docs/explanation
---

Then every .md file under each of those paths. A page's declared type is its folder's quadrant, or the type: key in the page's own front matter when it has one (tutorial, how-to, reference or explanation). A page under two quadrant paths belongs to the deeper one. A project without the manifest has nothing to read, and the stage reports nothing.

How a page is read

Fenced code, inline code and link targets are dropped first. Each cue then scores for one type:

  • a cue phrase anywhere on the page scores 1 for each time it appears;
  • a cue phrase in the first paragraph under the H1 scores 3 instead (the phrases that open each kind of page);
  • an H1 starting "How to" scores 3 for a how-to guide; one starting "About" or "Why", or ending "explained", scores 3 for an explanation;
  • "you will" and "you'll", the second-person future, score 1 each for a tutorial;
  • imperative steps (list items opening with a verb such as "Run" or "Add") score 2 for a how-to guide when there are at least three and they make up at least a third of the page's paragraphs and list items.

A page reads as a type when that type scores at least 3 and more than twice any other type. A page whose cues are too few or too mixed is not judged.

Rules

  • type_mismatch - the page reads as a different type from the one it declares. The message carries every type's score.
  • how_to_title - a page declared a how-to guide has an H1 that does not start with "How to", or no H1.
  • bad_type - the page's front matter carries a type: that is not one of the four. Its folder's type applies.
  • bad_manifest - .claude/diataxis.md has front matter that never closes, or no quadrants: map with a path in it.

Severity

Findings are warnings by default: the stage reports them, names each one in its summary line and in the JSON report, and passes. severity: :error makes every finding an error and fails the stage on any of them.

Opt-in

The stage is off by default, so no consumer's gate changes on upgrade. Enable it in .quality.exs:

diataxis: [enabled: :auto]                    # on when .claude/diataxis.md exists
diataxis: [enabled: true]                     # forced
diataxis: [enabled: :auto, severity: :error]  # fail on any finding

Summary

Functions

Runs the Diataxis stage.

Functions

run(config)

@spec run(keyword()) :: ExQuality.Stage.result()

Runs the Diataxis stage.

Config options

  • enabled - false (default):auto (on when .claude/diataxis.md
    exists)true (forced)
  • severity - :warning (default) | :error