# `ExQuality.Stages.Diataxis`
[🔗](https://github.com/riddler/ex_quality/blob/v0.16.0/lib/ex_quality/stages/diataxis.ex#L1)

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

# `run`

```elixir
@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`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
