Skip to content

Check the prose with vale #265

Description

@fniessink

The problem

Two checks read the prose today, each through a narrow slit. codespell catches a misspelled word. tools/sentence_complexity_check.py catches a sentence that needs a second pass. Neither reads style: a term the project spells two ways, a heading that answers a different question than its section asks, a sentence that buries its actor. That is what a prose linter is for, and of the tools this project shares with Quality-time, vale is the one it doesn't run.

The prose here is not incidental. The README is generated from docs/README.md.in and is the documentation; the CLI help is read by everyone who runs update-time -h; the log messages are the product's whole output. A defect in any of them reaches a user the way a defect in the code does.

The work

Add a vale check to just check, in the shape every other check has: a private recipe whose output is captured, reporting one PASS or FAIL line, joined to the parallel check recipe.

Vale is packaged on PyPI as vale (3.13.0.0 at the time of writing), which installs the binary into the environment, so it joins [dependency-groups] dev and arrives with uv sync like every other check rather than needing an install route of its own.

The increment ends with the check green over whatever it is pointed at, which may mean narrowing the style rather than rewriting the tree.

What this must not change

  • codespell and tools/sentence_complexity_check.py keep running, unless the work shows vale covers one of them outright.
  • just check stays parallel, and each check keeps reporting a single line.
  • The docstring conventions in .claude/CLAUDE.md. Where a packaged style contradicts them, the style is what gives way, since those conventions are chosen and the style is a default.

Out of scope

  • Rewriting the prose that a wider style would flag. Which prose is worth rewriting is a question per finding, not a precondition for having the check.
  • The generated README.md, which is written from docs/README.md.in and would be checked twice.

Documentation

None for the README, which documents what Update-time does rather than how it is checked. The justfile's check recipe lists the checks, so vale joins that list.

Open questions

  1. What should it read? The other prose checks read src tests tools docs *.md .claude/CLAUDE.md. A style linter earns most on the reader-facing prose — docs/README.md.in, CHANGELOG.md, and the CLI help in src — and least on docstrings, which follow this project's own rules and would argue with a packaged style.
  2. Which style: one vale packages, or a project style listing only the rules this project wants? A packaged style decides the first question too, since it is written for documentation rather than for docstrings.
  3. Does vale's readability rule cover what tools/sentence_complexity_check.py does? That tool exists because a sentence needing a second pass is a defect no linter catches; if vale catches it, one of the two should go.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions