# Wryko Records — technical dossier

**Deployed and taking payment** · https://claim-audit-khaki.vercel.app

A line of fixed-price audits that each examine one thing and publish a record of what was found — and of what was never checked.

---

## How to read this document

Every figure below was counted on **2026-08-21** by opening files in the
`claim-audit` checkout. Nothing is transcribed. The third column of each table names the file
and the pattern the number came from, so any of them can be re-derived rather than trusted.

This file is generated from the same objects as the web page it came from — the same metric rows,
the same gate list read out of the runner, the same defect log. It cannot go stale relative to that
page, because there is no second copy of the content.

Generator: `npm run metrics` then `GET /work/wryko-records/dossier`.
Derived data snapshot: 2026-08-21T00:39:47.211Z

---

## The product

Fixed-price services on one codebase. Each takes a URL or a document, runs a checker whose limits are declared up front, and produces a record: a document that names its subject, hashes what it read, states every finding in the W3C ACT Rules vocabulary, and lists the criteria no machine can decide. The records are served publicly, because a published record found through a search is the entire acquisition channel — there is no outreach.

**What the build argues.** A checker that cannot say how much it measured is not a checker. Every service here reports its own coverage, and reports zero coverage as a failure rather than as silence.

---

## Measured

| value | what it is | how it was derived |
|---:|---|---|
| 20 | automated gates behind one command | names in the GATES array of claim-audit/app/scripts/gates.config.mjs |
| 7 | % mutation score | score in claim-audit/app/quality/mutants.json |
| 243 | mutants applied | applied in claim-audit/app/quality/mutants.json |
| 226 | survived — broken code every gate accepted | survivors[].length in claim-audit/app/quality/mutants.json |
| 5 | services in the registry | slug: entries in claim-audit/app/lib/services.ts |
| 4 | of them live and sellable | status: "live" entries in claim-audit/app/lib/services.ts |

---

## Verification — 20 gates

One command runs all of them and a partial pass is a fail. A gate whose tooling is missing counts
as a failure rather than a skip, because a check that cannot run has not passed.

| # | gate | what it catches |
|---:|---|---|
| 1 | `publication` | no personal contact detail anywhere — PUBLICATION.md |
| 2 | `types + build` | a type error is a defect that has not happened yet |
| 3 | `selftest` | the paid path produces a record, and HALTS when a verifier is unavailable |
| 4 | `verify_design` | duplicate images, missing mark, bare pages, placeholder copy |
| 5 | `visual baselines` | any unintended pixel change, page-level and element-level |
| 6 | `lighthouse` | the ten numeric bars in QUALITY_BAR §1, re-derived rather than quoted |
| 7 | `scrim contrast` | AA for text over photography, which axe cannot see and therefore never fails |
| 8 | `record integrity` | every published record can say what it examined — bytes, hash, subject, method |
| 9 | `rendered text` | source syntax leaked into prose — the one defect a frozen baseline certifies |
| 10 | `links` | every internal link resolves, and og:image, robots.txt and the sitemap name THIS site |
| 11 | `discoverable` | QUALITY_BAR §7 D1–D8, asserted against the served bytes rather than a source literal |
| 12 | `deliverability` | nothing can be paid for that has no producer, renderer and checker on disk |
| 13 | `figures` | no number in a published document that nothing on disk counted |
| 14 | `honest` | every gate's exit code agrees with the verdict it just printed |
| 15 | `mutation` | the other gates can actually fail, proven by breaking the code on purpose |
| 16 | `stripe` | what Stripe shows a customer matches what this repo says |
| 17 | `complete` | a stranger can find it, understand it, buy it, and receive it — provably |
| 18 | `pipeline registries` | every registry exists and has a station that reads it |
| 19 | `pipeline sync` | the enforcers that ran are the enforcers under review |
| 20 | `ci coverage` | every gate here is assigned a CI job, and every gate script on disk is accounted for |

---

## Provenance — the seven document stations

Presence is measured by checking for the station's output filename on disk.

| station | output file | produced | lines |
|---|---|---|---:|
| PickService | `SERVICE_PICK.md` | yes | 173 |
| SeedDocument | `claim-audit-seed.md` | yes | 302 |
| PRDDocument | `PRD.md` | yes | 1601 |
| DesignPackage | `DESIGN_PACKAGE.md` | yes | 140 |
| TDDDocument | `TDD.md` | yes | 2100 |
| BuildAgentFile | `build_agent.md` | yes | 1451 |
| LaunchRunbook | `launch_runbook.md` | yes | 760 |

---

## The defect log for this repository

### 1. manufactured-mutation-score

*Found by an adversarial audit · cited from `claim-audit/app/scripts/mutate.mjs`*

**What shipped.** Both live repositories published a 100% mutation score. Both were manufactured. Mutation testing breaks the code on purpose and records a mutant as killed the moment any gate exits nonzero — but it never checked whether that gate was ALREADY failing on unmutated code. In business #1 three of seven gates in the oracle were red before a single line was broken; one of them, check-complete.mjs, is red because the domain and the founder interviews are outstanding, which no mutation can change. In this repository two of seven read sibling checkouts that do not exist inside a mutation sandbox. Every mutant was "killed" by a gate that would have said exactly the same thing about untouched source. The honest scores are 7% and 12.5%.

**Why nothing caught it.** The tool whose entire job is to prove the other gates can fail had no check that it could itself fail. Worse, when the guard was finally written it did not work either: shards were spawned with stdio ignored and their exit codes never read, so the guard halted its shard, printed its explanation to a discarded stream, and the parent collected the shards that survived and reported a score. A halt nobody hears is not a halt.

**What catches it now.** scripts/mutate.mjs runs every oracle gate against an unmutated sandbox first and HALTS on any red, and the parent now reads each shard exit code and aborts the run with its output shown. Gates that cannot be honest oracles were removed from the oracle with the reason written beside them — they still run in npm run verify, where their red is the correct answer. The formal-methods name for this is a vacuous pass: Beer, Ben-David, Eisner and Rodeh, 2001.

### 2. fabricated-figure

*Found by reading · cited from `claim-audit/app/scripts/check-figures.mjs`*

**What shipped.** “1,392 claims examined, 108 false” was written into a fact sheet intended for a stranger, and stated three times across three documents. It had never been produced by anything — no record, no script, no log. Beside it: “11 registries” when there were 8, and “3 published records” when there were 2.

**Why nothing caught it.** Every gate on the project examined code or the running site. These were sentences about the project, written somewhere else. The documents most likely to be read by someone who mattered were the only artifacts with no verifier at all.

**What catches it now.** scripts/check-figures.mjs, which fails any number bound to a countable noun that METRICS.md cannot confirm — and fails harder on a noun nothing counts at all, because that is the case this was.

### 3. elapsed-time

*Found by reading · cited from `claim-audit/app/scripts/check-figures.mjs`*

**What shipped.** “spent the last year” appeared in a document about a repository that was days old.

**Why nothing caught it.** Nothing on disk records elapsed effort. Git records commit dates and nothing else, so there was no source that could have disagreed.

**What catches it now.** The same figures gate carries a separate rule for elapsed-time narrative, on the grounds that it is unfalsifiable rather than merely wrong.

### 4. missing-gate-passed

*Found by reading · cited from `claim-audit/app/scripts/gates.config.mjs`*

**What shipped.** The gate runner printed “ALL 8 GATES PASS” having run seven. When verify_design.py was absent it printed “– not installed”, excluded it from the failure list, and reported green.

**Why nothing caught it.** The strongest gate lived at an absolute path into a home directory. On any machine without it — a CI runner, a fresh clone, a collaborator — it silently stopped existing, and its absence was indistinguishable from its success.

**What catches it now.** A gate whose tooling is missing is now a named FAILURE, and the pipeline is vendored into the repo so the enforcers that ran are the enforcers under review.

### 5. decorative-flag

*Found by reading · cited from `claim-audit/app/scripts/verify-all.mjs`*

**What shipped.** Three gates fetched localhost:3000 and were marked `needsServer: true`. Nothing read that flag. It looked like a guarantee that a server would be running and guaranteed nothing.

**Why nothing caught it.** A checker pointed at a dead origin finds zero problems, and zero problems is exactly what a clean bill of health looks like.

**What catches it now.** The runner starts a server when any gate declares it needs one, waits for it, and refuses to continue if it never comes up.

### 6. empty-hash

*Found by reading · cited from `claim-audit/app/scripts/gates.config.mjs`*

**What shipped.** A published record for an IRS W-9 shipped with `bytes: 0` and the SHA-256 of empty input, reporting six criteria passed on a file it had never read.

**Why nothing caught it.** Every gate photographed, measured or parsed the site. A false hash renders exactly as beautifully as a true one.

**What catches it now.** scripts/check-records.mjs — every published record must be able to state what it examined: bytes, hash, subject, method.

### 7. unsellable-service

*Found by an adversarial audit · cited from `claim-audit/app/scripts/gates.config.mjs`*

**What shipped.** Two services were marked live, with resolving Stripe links, and no producer script anywhere on disk. A buyer could have paid $500 for a record no code could build.

**Why nothing caught it.** Every gate asked whether the site was correct. None asked whether the business behind it could honour a sale.

**What catches it now.** scripts/check-deliverable.mjs — nothing may take money without a producer, a renderer and a checker present on disk.

### 8. unread-enforcer

*Found by an adversarial audit · cited from `claim-audit/app/scripts/gates.config.mjs`*

**What shipped.** Two registries governing human-only work and money spend each printed “Enforced by: check_pipeline.py” at the top. check_pipeline.py ran nowhere — not in a gate, not in CI, not in a station.

**Why nothing caught it.** The sentence asserting the enforcement was the least verified claim in the repository, and it was load-bearing for two documents about spending money.

**What catches it now.** check_pipeline.py is now a gate in the runner. Its own honest limit is published with it: several of its rules still only warn.

### 9. undeclared-mono

*Found by reading · cited from `claim-audit/app/app/globals.css`*

**What shipped.** `var(--mono)` was read in seven files — the brand board, every record renderer, two tools — and declared in none. Every SHA-256, record token, outcome label and byte count rendered in the body sans, on records whose entire argument is that you can compare a hash character by character.

**Why nothing caught it.** An unresolved custom property silently falls back to the inherited value, so a font-family that never applied looks exactly like one that did. A visual baseline had frozen the wrong font as correct; axe and Lighthouse do not grade typeface choice.

**What catches it now.** The token is declared, and the var() form and the utility-class form now resolve to the same stack so they cannot disagree.

### 10. no-focus-ring

*Found by reading · cited from `claim-audit/app/app/globals.css`*

**What shipped.** The bespoke `.btn` class had no focus state. Not a weak one — none. The entire stylesheet contained a single `:focus` rule, so every button and link on a site that sells accessibility records relied on whatever the browser drew by default, frequently nothing legible over a dark fill.

**Why nothing caught it.** Automated accessibility checking grades contrast and names and roles. It did not fail a missing focus ring on a custom class.

**What catches it now.** A `:focus-visible` rule over every interactive element, with two rings so it survives both the light and the dark ground. Inherited into this repository unchanged.

### 11. parser-missed-pairs

*Found by reading · cited from `claim-audit/app/lib/brand.ts`*

**What shipped.** The brand board's parser matched one declaration per line. The stylesheet pairs verdict tokens two to a line, so every `-bg` token was silently missed and the board reported four colour pairs as BELOW AA when all four cleared it. The palette was fine; the parser was broken.

**Why nothing caught it.** The board was a generated artifact nobody re-checked, and a wrong FAIL is as corrosive as a wrong PASS — it teaches people to distrust the tool.

**What catches it now.** It scans declarations rather than lines. It survived only because an uncomputable ratio is treated as a failure rather than skipped; had it skipped what it could not measure, the board would have printed “all pairs clear AA” while checking two thirds of them.

### 12. baseline-froze-the-bug

*Found by reading · cited from `claim-audit/app/scripts/verify-all.mjs`*

**What shipped.** A nav button on a paid page read “Get a record &mdash; $500” — the literal escape sequence, visible, for days.

**Why nothing caught it.** The visual baseline froze the broken text as the reference. A regression test cannot tell you that what it captured was already wrong. Lighthouse and axe passed: an em-dash entity is valid, legible, high-contrast text. TypeScript passed: both forms are valid JSX.

**What catches it now.** scripts/check-rendered-text.mjs reads the rendered DOM for source syntax that leaked into prose — the one defect class a frozen baseline actively defends.

### 13. scrim-over-photography

*Found by a gate · cited from `claim-audit/app/scripts/verify-all.mjs`*

**What shipped.** Text over a photographic band measured 1.36:1 — an eyebrow whose box ran roughly 950px past its last glyph, into the light end of the scrim gradient.

**Why nothing caught it.** axe computes contrast from a CSS background colour. Behind this text was a canvas, so it returned nothing at all, and nothing looks exactly like a pass. Every visual baseline passed too: the band looked precisely as intended, and was still an AA failure.

**What catches it now.** scripts/check-scrim.mjs rasterises the real composite and measures the brightest pixel under every letter.

### 14. regex-skipped-figures

*Found by reading · cited from `claim-audit/app/scripts/check-figures.mjs`*

**What shipped.** The figures gate's own extraction pattern used a lazy quantifier and tested only the final word, so “8 automated gates” matched with zero intervening words, tested “automated”, found no noun, and moved on. It reported “4 figures examined” on documents containing far more.

**Why nothing caught it.** Four is not zero, so the measurement guard that fails on zero did not fire either. The checker written to notice absence had a quiet absence of its own.

**What catches it now.** A greedy window of up to four words, with every word tested. The count of figures examined is printed on every run so the number itself is reviewable.

### 15. stale-pdf

*Found by reading · cited from `claim-audit/app/scripts/check-figures.mjs`*

**What shipped.** A rendered PDF sat four hours behind the HTML it came from, carrying superseded figures, under the filename somebody would actually attach to an email. Twice in one day.

**Why nothing caught it.** The figures gate reads the HTML, so it certified the source as clean while the artifact derived from it disagreed. The check and the thing that reaches a human were different objects.

**What catches it now.** The gate compares mtimes and fails when a rendered artifact is older than its source.

### 16. terminal-gate-lied

*Found by a mutant · cited from `claim-audit/app/scripts/gates.config.mjs`*

**What shipped.** The completion gate could print “NOT COMPLETE — 3 of 10 criteria unmet” and then exit 0. The runner reads the exit code, not the prose, so a business would have been declared finished while its own gate said in plain English that it was not.

**Why nothing caught it.** Nothing found this by reading. It was found by a mutation run — 2,022 mutants, of which two survived, both in that file. Every other gate is watched by something; the last one was watched by nobody, and its answer matters most.

**What catches it now.** scripts/check-gates-honest.mjs asserts that every gate's exit code agrees with the verdict it just printed.

### 17. no-gate-read-stripe

*Found by an adversarial audit · cited from `claim-audit/app/scripts/gates.config.mjs`*

**What shipped.** Thirteen gates, and not one of them read the account that takes the money. A live $500 checkout session for an undeliverable service sat payable while the deliverability gate printed ALL CLEAR, and the business profile described a retired product on every receipt for weeks.

**Why nothing caught it.** `grep -rn "api.stripe.com" scripts/` returned nothing. The repository was thoroughly checked against itself and never against the system that customers actually touch.

**What catches it now.** scripts/check-stripe.mjs reconciles what Stripe shows a customer against what the repo claims, and halts rather than passing when the credential is absent.

### 18. record-had-no-way-home

*Found by reading · cited from `claim-audit/app/components/RecordShell.tsx`*

**What shipped.** Every published record page shipped with no nav, no mark and no link home. Someone arriving at a record — the exact person the entire acquisition strategy is built to reach — could read the proof and had no way to find out who made it or how to buy one.

**Why nothing caught it.** The design gate checks that a nav carries a real mark, and a page with no nav has no nav to check. Lighthouse does not grade whether a page links anywhere. The visual baselines had frozen the navless layout as correct.

**What catches it now.** One RecordShell component wraps every record, replacing three hand-written footers that had already begun to differ. It is in this repository too, wrapping the dossiers.

---

## What is missing

- No customer has paid for a record. The payment links are live and the delivery chain is complete on disk; nobody has used it.
- Discovery is unproven. The strategy is that a published record ranks and a stranger finds it. Nothing yet demonstrates that it does.

---

## Standing constraints

- **No outreach, ever.** Discovery is organic search and published work only. No cold email, no
  sequences, no scraped lists.
- **No published personal contact details.** A name, a role and a role address. No home address and
  no personal phone number appear anywhere.
- **No figure that nothing counted.** A number may appear in a published document only if a
  generator produced it from disk.

---

Marcos Matthews — sole member, Wryko LLC · Support@wryko.com
