ascribe.toml: checks and the editor

How the content model sets the checks’ levels and the editor’s build, what an absent section means, and how the file is validated.

For AI agents: the documentation index is at llms.txt, and this page is available as Markdown.

Part of the ascribe.toml reference, whose contents list every section. The rules for a loader are in the contract’s checks and the editor.

22. [checks]

How loudly each check about your content’s quality speaks: whether it’s reported as advice, a warning, or an error, or not at all. A diagnostic about whether the project is valid, such as a broken link, can’t be set here: it’s always reported at its own severity.

[checks]
code-language-missing = "warning"

[checks.page-size]
level = "warning"
limit = 40_000

Each key is a check’s name, as the diagnostics reference lists it. Its value is the check’s level, or a table, [checks.<check>], with the check’s own settings, which its entry in the reference lists, and these keys:

Key Type Default Description
level string the check’s own level The check’s level: "off", "advice", "warning", or "error". Without it, the check keeps its own.

Only a check the diagnostics reference marks configurable can be named; that section lists them, with their settings. Four have one, limit: for page-size, a whole number of characters above 0, 50_000 unless set; for image-large, a size, as a number of bytes or a string such as "1.5 MB" (a kilobyte is 1,000 bytes), "500 KB" unless set; for memo-long, a whole number of characters above 0, 2_000 unless set; and for summary-long, a whole number of characters above 0, 300 unless set. [checks.vale] and [checks.links] are reserved for the settings of tools Ascribe runs.

For example, a site whose sidebar lists every page doesn’t need to hear about pages nothing links to, and a team that wants smaller images can lower the limit:

[checks]
page-orphan = "off"
title-duplicate = "warning"

[checks.image-large]
limit = "200 KB"

Advice is shown in the editor and by ascribe check, and never fails the check, even with --deny-warnings; off turns a check off altogether. A check raised to "error" fails the check and stops the build, as an error does, though the page is still valid by the specification, and a review check raised this way can still be acknowledged. Quieting a problem compares [checks] with the other ways to quiet one.

A check the diagnostics reference marks off by default, such as summary-missing, is off until [checks] names it: with a level, it’s reported at that level, and as a table without one, such as [checks.summary-long] with only a limit, at its default level (Setting a check’s level).

In VS Code, the sidebar’s This page shows a page’s size against page-size’s limit, measured the same way, whether or not the page is over it.

Rules. A key that isn’t a check is an unknown key, with the closest check suggested (model-unknown-key), and so is a setting the check doesn’t have. A check that isn’t configurable can’t be named (model-check-not-configurable). A level is one of the four (model-invalid-value). page-size’s, memo-long’s, and summary-long’s limit is a whole number above 0, and image-large’s a size (model-wrong-type).

[[intended]]: acknowledgements

Says that a check’s problem with a content model entry or an image is intended, as @intended does for a block and the intended frontmatter key for a page. Each table names one check, one entry, and why.

[[intended]]
check = "phrase-unused"
phrase = "old-product-name"
reason = "Kept for the 2.x pages restored in the next release."
Key Type Default Description
check string required The check, by its name. It must be a review check that reports its problems at an entry, as the diagnostics reference says.
reason string required Why the problem is intended. Not empty.
phrase string required: exactly one of phrase, feature, and image The entry, when it’s a phrase: its key.
feature string required: exactly one of phrase, feature, and image The entry, when it’s a feature: its key.
image string required: exactly one of phrase, feature, and image The entry, when it’s an image: its path under the content root.

A glossary term is a heading, so it’s acknowledged on its page instead, with @intended under its heading; term here is an error that says so.

Rules. A check that doesn’t exist, isn’t a review check, or reports its problems somewhere other than an entry is an error (model-intended-check). A table without exactly one entry key, or naming an entry that isn’t declared, is an error (model-intended-entry).

[checks.vale]

Checks the prose with Vale, a program the project installs: Ascribe gives it each page’s prose, with phrases replaced by their text and without frontmatter, directive lines, attributes, or code, and reports its alerts as prose diagnostics at their place in the source. The editor runs it on a page when it’s opened and saved; ascribe check runs it with --vale, or always with in-check = true. Prose, through Vale has the steps.

[checks.vale]
preset = "quiet"
off = ["Ascribe.Repeated"]
Key Type Default Description
preset string Ascribe’s own selection of Vale rules: quiet, rules that are almost never wrong. Nothing is downloaded: the preset is written under .ascribe/vale/.
config string Instead of a preset, the path of the project’s own .vale.ini, from the project root.
off array of strings [] Rules of the preset to turn off, by the names alerts give them, such as Ascribe.Repeated. Only with preset.
command string "vale" The command that runs Vale. A path with a separator is from the project root; a bare name is looked up as the shell would. A path is a program in the project: the editor asks before it runs one, and the agents’ hooks don’t run one (Prose, through Vale).
in-check boolean false Whether ascribe check, and the agents’ hook, check the prose without --vale. It also says the project wants its prose checked everywhere: without it, the editor doesn’t report that Vale couldn’t be run (prose-not-checked), since a machine without Vale isn’t one the project asked to check.
max-level string "error" The most an alert can be: "advice", "warning", or "error". Vale’s suggestion, warning, and error are advice, a warning, and an error up to it; with "advice", Vale’s alerts never fail --deny-warnings.

Ascribe writes the project’s own words (phrase values, glossary terms and their aliases, and the labels of dimensions, their values, and features) to a Vale vocabulary, Ascribe, under .ascribe/vale/, so Vale doesn’t take them for misspellings. It’s turned on for a preset and for the project’s own configuration alike; nothing the project wrote is changed.

The level of every Vale alert can be set at once with prose in [checks], and the advice that Vale couldn’t be run with prose-not-checked.

Rules. [checks.vale] has exactly one of preset and config, and off goes with preset and names its rules (model-checks-vale). preset is one of Ascribe’s presets, and max-level one of the three levels (model-invalid-value).

How ascribe report links checks the project’s external links, with lychee, a program the project installs. ascribe check never checks external links. Check external links has the steps.

[checks.links]
ignore = ["localhost", "*.internal.example.com"]
Key Type Default Description
command string "lychee" The command that runs lychee. A path with a separator is from the project root; a bare name is looked up as the shell would.
ignore array of strings [] The hosts whose links aren’t checked: a host name, such as example.com, or *. and a host name, which covers every host under it but not the name itself. Case doesn’t matter.
reuse-days whole number 14 How many days an address that answered isn’t asked about again. Each address’s own limit falls between half of this and all of it, so addresses first checked together don’t all come due on one day. 0 asks about every address on every run.
confirm-days whole number 3 How many days a link that answered before and fails now is listed as unconfirmed, and not reported, before it’s reported. A 404 or a 410 is reported at once. 0 reports every failure at once.

The answers it reuses and the links it holds as unconfirmed are kept in .ascribe/: What it remembers.

A broken link is link-external-broken and a moved one link-external-moved; both are configurable in [checks], and a broken one is acknowledged with @intended above its block.

Rules. ignore names hosts, without a scheme, path, or port, and reuse-days and confirm-days are whole numbers, 0 or more (model-wrong-type).


23. [editor]

Settings for the authoring environment (SPEC §10).

ascribe 0.4.4 on Linux
[editor]
build = "site"
Key Type Default Description
build string the only build, else site The build whose page-level diagnostics the language server reports by default (SPEC §8.1 checks pages once per build). It MUST name a declared build.

Default. If only one build exists, that build. Otherwise, the build named site, if there is one. Otherwise the key is required (model-editor-build-required).


24. Defaults: what an absent section means

A file containing only spec = "0.1" is valid. It means:

Section When absent
[project] content-root = "docs", output-dir = ".ascribe/build"
[types] One implicit default page type, named page, with frontmatter title = "string" and nothing else. If [types] declares any type, there’s no implicit type.
[fragments] Only paths with a _ segment are fragments. The fragment schema has no fields, so a fragment’s frontmatter can’t have any keys.
[notes] The five built-in note types.
[phrases] No phrases. Every {…} is literal text.
[glossary] No glossary.
[images] No image attributes.
[widgets] No project widgets.
[dimensions] No dimensions. Any @variant arm with attributes, or variant frontmatter, is an error.
[versions] scheme = "numeric"
[lifecycle] The five built-in states.
[features] No features.
[consumer] profile = "astro" with its defaults.
[builds] One implicit build, site, with variants = "switch" and availability = "badge". If [builds] declares any build, there’s no implicit one.
[listing] No rules. A page that doesn’t set listing is listed.
[crawlers] No lines.
[permalinks] No retired permalinks and no aliases.
[sources] No sources. Nothing outside the project’s folder can be read.
[checks] Every check at its own level.
[editor] build as in §23.

25. Validation

A content model with errors is reported, and nothing else is checked, since every other check depends on it. Its warnings are reported with the rest of the diagnostics. Every rule the loader enforces is listed in the diagnostics reference, on Diagnostics: the content model and Diagnostics: the content model’s builds and site, with its code and how to fix it. The contract’s §25 states each rule for someone writing a loader.