Doc PRF-16
Classification PUBLIC

Continuous Correctness Audit

Your software makes promises. We turn them into tests that run in your CI.

When a change breaks a promise, your build goes red — and you get the exact failing test, before your users find the bug.

0
promises written down and signed
0
real bugs found in one audit
0
miss — published, in full
Appendix A The fine print, for the skeptics

What "promise" means here. A formal requirement, written in FRETish — the requirements notation from NASA's FRET project — and compiled to temporal logic. 116 of the 123 requirements above carry a machine-checkable formal specification; the rest are stakeholder-level statements traced to them.

Precision, not recall. We do not claim to find every bug. We claim that every promise we write down stays checked, and that every finding we publish is reproducible by a stranger.

§2 · MethodPRF-16 · Fig. 1–3

Three steps. Nothing about how you ship changes.

Fig. 1STEP 1

We write down what your code promises.

We study one component and turn its behavior into short, plain statements. Each one says what must always happen — or must never happen.

A signed requirement
SYS-REQ-060 — Setting a value at one
path must never change the value
at any other path.
✓ approved & signed
Fig. 2STEP 2

You sign off. Each promise becomes a test.

You review the list and approve it — usually a couple of hours of your time. We turn every approved statement into a check that can fail.

A test that can fail
✗ FAIL TestSetScalarArray
  Set("a") also changed "b"
  → violates SYS-REQ-060
Fig. 3STEP 3

Every change gets checked. Forever.

The checks run in your CI on every commit. Break a promise and the build goes red, with the failing test pointing at the exact statement you broke.

Your CI gate
✓ PASS 123/123 promises hold
✓ gate merge allowed
Appendix B The fine print, for the skeptics

Before code is judged, the requirements themselves are checked — for consistency, realizability, and vacuity — by the Kind2 model checker and the Z3 solver. A requirement that can never fire, or that contradicts another, is rejected before it counts.

Coverage bar: MC/DC — the code-coverage standard used in avionics — measured across eleven languages, from Go and Rust to Solidity and Zig. Nine instrumented directly; C and C++ imported from the compilers' own measurement into the same gate.

Per requirement: worst-case (hazard) analysis, the way regulated industries do it, with evidence attached per selected obligation. The audit gate itself runs 52 distinct checks.

Why teams ask for this now

46% vs 33%

In Stack Overflow's 2025 survey, 46% of developers said they distrust the accuracy of AI-written code. 33% trust it.

— Stack Overflow Developer Survey, 2025

90% vs 30%

DORA's 2025 report found 90% of teams now use AI to write code — and about 30% trust what it writes. The code ships either way.

— DORA, 2025

§3 · Exhibit APRF-16 · all artifacts public

The bug that looked impossible.

A true story from our own code. Every artifact in it is public.

Exhibit Ajsonparser · Set()

The bug

A Go JSON library that people had trusted for a decade was silently losing data. Save one value, and sometimes another value disappeared. Nothing crashed. The output was still valid JSON. The library is ours — our principal built it and has maintained it for ten years, and it runs inside major cloud projects.

Why nobody caught it

Nobody's tests caught it, because the code looked fully tested. Every branch and every condition had been exercised. The problem was simpler and worse: nobody had ever written down that saving one value must not delete another. A rule that isn't written down is a rule no test can check.

The fix that lasts

Now the rule exists on paper: "saving one value must never delete another." And there is a test behind it that runs on every change to the library, forever. The bug can come back a hundred different ways; the test is waiting for all of them.

The uncomfortable part

This bug escaped our own audit too. A user caught it and reported it. So we published the whole story — what we missed, why fully-exercised code still hid it, and what we changed in our process so gaps like this get written down.

We think an audit you can check matters more than an audit that claims perfection.

Read the postmortem See it on the public register
Appendix C The fine print, for the skeptics

The technical shape: a scalar-array overwrite in Set() — the grow branch fired only for object-first arrays — silent, with valid JSON output, despite 100% MC/DC on the affected code.

The postmortem names three root causes: unspecified partitions, no output oracle, and literal pattern matching. In its own words: "MC/DC has no notion of 'correct'; it has only 'exercised.'" An unspecified partition is simply not in any check's denominator.

Reported by the community (jsonparser issues #286 and #267). We say "escaped the audit" because that is what happened.

§4 · Findings registerPRF-16 · public · no login

Every finding is public. Go look.

We audited our own library in the open. The requirements, the tests, and every bug — including the one that got past us — sit on a public register. No login.

portal.reqproof.com/projects/jsonparser ● live register
FindingHow it was foundStatus
Crash on malformed input — the same unchecked assumption repeated at eight call sites Seven sites by a systematic hazard sweep; the eighth by root-cause analysis FIXED
Silent data loss in Set() — saving one value could delete another Escaped the audit; reported by a user FIXED · postmortem published
Crash in Delete() on malformed input Reproduced by the solver as a counterexample, in 6 ms FIXED
Benchmark had mislabeled a competitor library since 2017 Found during review FIXED
23 findings on the register, each with severity and a command that reproduces it. See all
Appendix D The fine print, for the skeptics

Register contents, as of 2026-08-03: 23 findings; 16 known issues (10 open: 5 High, 2 Medium, 2 Low, 1 Info; 0 Critical) and 8 problem reports. Severity and CVSS recorded per finding; every finding page carries its reproducer as a runnable command.

Traceability: a map links each requirement to the test files that verify it and the code files that implement it; known issues link to the requirements they affect.

Also from this audit: 279/279 functions traced; 16M+ structure-aware fuzz executions; one hot path went from 128µs to 22µs; six releases in three days with zero breaking changes.

§5 · EngagementPRF-16 · terms

One component. About four weeks. Fixed fee.

Pick the component that scares you most. Here is what exists at the end.

  • A written list of your component's promises — short, plain statements, reviewed and signed off by you.
  • A test behind every promise, wired into your CI. Break one and the build goes red with the exact test.
  • A findings register: every bug we find, with severity and a command that reproduces it.
  • Everything lives as files in your repo, not a PDF in your inbox. If we vanish tomorrow, all of it keeps running.
  • Then it stays on. The checks run on every change, and new promises get added as the component grows.

The terms, plainly

Scopeone component
Duration~4 weeks
Pricefixed fee
Your timea few hours of review
Your codeunchanged by us
Aftercontinuous, in your CI

Client audits stay private. Our own library's audit is the public sample of exactly what you receive.

Appendix E The fine print, for the skeptics

The deliverable's anatomy is visible in the public repo: spec trees at four levels (stakeholder → system → software → integration), code annotations linking functions to requirements, tests carrying // Verifies: markers, known-issue and problem-report files, and the CI gate configuration.

We run our own tool on itself: nearly two thousand requirements across four spec levels govern Proof's own codebase, with zero orphan code.

First engagement, anonymized: an enterprise API gateway — one component, 47 approved requirements, about 2 hours of the owners' time, zero production code changed by us, and a nil-pointer crash class every existing test had missed.

Form PRF-16/A

Ask us to look at one component.

Leave an email. We'll reply with a few questions about the component and a fixed quote. No calls unless you want one.

One email thread. A human replies. Nothing else happens with your address.

Got it — check your inbox. We'll reply with a few short questions, then a fixed quote. If it isn't a fit, we'll say so plainly.