Report shapes
markdown source of this page
The page as a markdown file: index.md
+++
title = "Report shapes"
subtitle = "the JSON document and the count per check that wiki check writes for another tool"
status = "approved"
intent = """
These shapes exist so that a tool reading a check does not begin by parsing sentences written for a
person, and so that a build log too short to hold every problem still shows what is wrong. Each should be
enough on its own to decide what to fix first.
"""
[[infobox]]
group = "Identity"
rows = [
{ label = "Options", value = "--json, --summary", note = "one or the other", cite = "shape" },
]
[[infobox]]
group = "Rules"
rows = [
{ label = "Output", value = "standard output, and nothing else under --json", cite = "json" },
{ label = "Exit codes", value = "unchanged by either", cite = "shape" },
]
+++
`wiki check` says everything as sentences for a person, which is what [wiki check](../check.md)
describes. **One of these two shapes may be given, never both**, and neither changes the exit
code.[^shape]
## JSON
`--json` writes the page count, a record per problem, and the marked claims in a list of their
own.[^json] A record names the file, the line where there is one, the check that refused it, and the
sentence **carried unchanged**, so a problem the fields do not fit still reads.[^record] A marked claim
never joins the problems, because it fails nothing.[^json] Nothing else is written, on either stream, and
two runs write the same bytes.[^json]
```json
{
"marks": [],
"pages": 3,
"problems": [
{
"file": "thing.md",
"line": 22,
"message": "thing.md:22: “It says nothing.” states something and cites nothing; give it a reference, or {missing} if there is none",
"rule": "uncited"
}
]
}
```
Each `rule` names the check that refused it; a marked claim is named `missing`.[^rules]
## Count per check
`--summary` counts the problems by check, most first and by name where two tie.[^summary] **A wiki of a
few hundred pages prints more lines than a build log holds**, and a log that drops its oldest lines drops
the problems first.[^summary]
```text
wiki: 292 family
wiki: 207 pointing
wiki: 186 uncited
wiki: 346 pages, 685 problems
```
[^shape]: `src/builder/cli.py` — `main()` puts `--json` and `--summary` in a mutually exclusive group,
and `run()` returns the same status under either.
[^json]: `src/builder/cli.py` — `run()` writes one `json.dumps()` with `sort_keys=True` on standard
output and returns before the sentences, the counts and the marks are printed, putting
`missing_marks()` under `marks` instead.
[^record]: `src/builder/build.py` — `problem_record()` reads the file and line from `PROBLEM_PLACE` at the
head of the sentence, keeps the sentence whole as `message`, and leaves `file` and `line` empty where
it finds none.
[^rules]: `src/builder/build.py` — `check()` names each producer as it adds it, and `page_checks()` gives
the order they are reported in.
[^summary]: `src/builder/cli.py` — `run()` counts the records by `rule` and prints them sorted by falling
count then by name, then the page and problem count.
Last updated 19 September 2026