Runs on: a script on the mini · Reports to: Orchestrator · Client-facing: no
Produces: qa-machine.json — pass/fail per check, no opinions
Catches everything a computer can check, before a model is asked to judge anything. It exists because an LLM reviewing LLM output reliably catches tone and misses the wrong phone number.
This is the single most important design decision in the QA layer. If Machine QA were an agent, it would occasionally decide a phone number was "close enough". It cannot, because it is a string comparison.
Not a voice. Structured output only.
{"check":"contact_match","pass":false,
"detail":"/contact phone '03 389 4471' != dossier '03 389 4417'","owner":"build"}
Every failure names the owner so the orchestrator can route it without interpreting.
Orchestrator. It is a gate: red never advances.
The deployed preview URL, dossier.md, the agreed page list, build-report.json.
The deployed preview URL, dossier.md, the agreed page list, build-report.json, and the banned-
phrase list.
qa-machine.json:
{
"verdict": "red",
"ran_at": "2026-08-29T22:14:03Z",
"duration_ms": 71400,
"checks": [
{"check":"pages_present","pass":true},
{"check":"contact_match","pass":false,
"detail":"/contact phone '03 389 4471' != dossier '03 389 4417'","owner":"build"},
{"check":"lighthouse_a11y","pass":false,"value":88,"threshold":90,"owner":"build"}
],
"failed": 2, "passed": 24
}
Every failure carries an owner, so the orchestrator routes without interpreting.
qa-machine.json and return a single verdict.Completeness
Placeholders — zero tolerance
lorem, TODO, FIXME, [NEEDS:, {{, Your business name, example.comContact truth ← the one that justifies the whole script
tel: and mailto: hrefs match the visible textLinks and media
Standards
Design
audit-css.mjs passes: more than one duration and one easing, elevation beyond hairlines,
some texture. These are the measured signature of a cold site.tokens.css — no stray hex invented at build timeLanguage lint — the anti-slop pass
A script cannot tell whether copy sings. It can count the things AI prose does and human prose does not, which turns out to catch most of it:
| Check | Why it is a tell | Fails at |
|---|---|---|
| Banned phrases | "delve", "reach out", "leverage", "unlock", "in today's digital landscape" | any hit |
| Em-dashes | near-absent in how people actually write | any |
| Adverb ratio | AI reaches for "seamlessly", "truly", "carefully" | > 2.5% of words |
| Sentence-length variance | the strongest statistical tell — AI writes uniformly | stdev < 5 words |
| Rule of three | "fast, friendly and affordable" is a sentence no plumber has said | > 1 per 150 words |
| "not just X, it's Y" | the formulaic contrast | any |
| Paragraph-opening repetition | AI reuses one section shape | > 40% share an opening pattern |
| Wh-word sentence openers | "Whether you need…", "What makes us…" | > 15% of sentences |
| Specificity floor | a section anchored in nothing real | 0 numbers/names/places in a section |
Thresholds live in config and change deliberately, in git. The client's documented voice overrides every one of these — an owner who genuinely talks in threes is not slop, and the dossier is the authority on that.
SEO
seo.md specifiedClaim safety
Every check run, results written, an overall verdict. Green means Editorial QA may start.
| Mode | How it shows | Guard |
|---|---|---|
| Flaky check | intermittent red on a good site | retry once; a check failing intermittently is a bug in the check |
| Threshold creep | "it's only 2 points below" | thresholds are config, changed deliberately, in git |
| Check nobody owns | red result with no route to a fix | every check declares an owner |
| False confidence | green, then the client finds a defect | every escape adds a check — see below |
Red twice on the same check after the owning agent has had two attempts.
Under 2 minutes. Costs essentially nothing, which is precisely why it runs first.
This is the agent-shaped thing with the clearest improvement loop in the whole system.
Watch: escapes — defects the client or Greg found after Machine QA passed.