Verify this review
Re-run LoopOver's published backtest corpus yourself — download a checksummed snapshot, replay the same scorer, and compare against the published numbers.
Why this page exists
LoopOver publishes measured per-rule precision on the fairness report. Numbers on a website only build trust if a skeptic can check them without asking anyone's permission. This page is the end-to-end walkthrough: export the same corpus snapshot the numbers come from, verify its checksum, replay the same scorer over it, and compare what you get against what is published.
Everything below runs read-only against a corpus export and pure functions from @loopover/engine.
Nothing posts anywhere, and nothing needs a LoopOver API key.
Every step below is runnable by a stranger. The corpus download needs no credentials of any
kind. It is redacted, and deliberately so: targetKey — the owner/repo#number a case came from
— is dropped outright rather than hashed, since scoreBacktest never reads it and a hash would
still be a stable per-PR identifier. Metadata is narrowed to the single confidence field the
shipped classifier reads, and timestamps are truncated to the day. What you lose is the ability to
point at which pull request a case was; what you keep is every input the scorer actually
consumes. The operator CLI further down is still there for anyone running their own deployment
against their own database.
For the wider contract — every claim, its artifact, and its trust assumption, including the ones you cannot check — see what you can verify.
1. Download the corpus (anyone)
One rule's labeled fired/override history, over the same trailing window the fairness report covers, as a checksummed JSON document (backtest & calibration explains how that history is recorded):
curl -s "https://api.loopover.ai/v1/public/eval-corpus?ruleId=ai_consensus_defect" > corpus.json
ruleId is required — a corpus only means anything for one rule, and the rule ids are the ones the
fairness report lists. Each case carries ruleId, outcome, label, day-truncated
firedAt/decidedAt, and metadata.confidence when the firing recorded one. caseCount and
truncated describe the array; truncated is true only if a rule ever exceeds the published cap,
and it is reported rather than hidden.
Operator / self-host: the same corpus, unredacted
Running your own deployment, the CLI reads your own database and keeps the target keys:
npx tsx scripts/backtest-corpus-export.ts --rule-id linked_issue_scope_mismatch --output corpus.json --remote
--remote shells out to wrangler d1 execute … --remote, so it needs that deployment's own
Cloudflare credentials. On a self-host deployment, point the same CLI at your own Postgres instead:
npx tsx scripts/backtest-corpus-export.ts --rule-id linked_issue_scope_mismatch --output corpus.json --pg "$DATABASE_URL"
The snapshot's checksum field is a SHA-256 over the canonicalized cases (keys sorted, so
property order can never change the hash). The fairness report's reproducibility freeze point
shows that checksum for the most recent persisted backtest run, whichever single rule that run
covered — re-exporting that rule over the same window reproduces the same checksum, byte for byte.
It is one run's freeze point, not a per-rule commitment for every rule on the report, so compare it
against an export of the rule the run actually covered.
2. Verify the checksum (anyone)
The document is self-verifying: recompute the hash over its own cases array and compare it to the
recorded checksum. This step deliberately imports nothing from LoopOver — canonical JSON is
eight lines, and a verification that runs our code to check our numbers is not much of a check:
node -e '
const { createHash } = require("node:crypto");
const canonical = (v) =>
Array.isArray(v) ? `[${v.map(canonical).join(",")}]`
: v && typeof v === "object" ? `{${Object.keys(v).sort().map((k) => `${JSON.stringify(k)}:${canonical(v[k])}`).join(",")}}`
: JSON.stringify(v);
const saved = JSON.parse(require("node:fs").readFileSync("corpus.json", "utf8"));
const recomputed = createHash("sha256").update(canonical(saved.cases)).digest("hex");
console.log(recomputed === saved.checksum ? "checksum OK" : "CHECKSUM MISMATCH");
'
The rule is: recursively sort object keys, drop all insignificant whitespace, leave array order
alone (order is meaning there), then SHA-256 the UTF-8 bytes. That is the same canonicalization
every other digest in this system uses, including each EvalScoreRecord's recordDigest.
The operator export from step 1 uses a different, older canonicalization
(buildBacktestCorpusManifest in scripts/backtest-corpus-export-core.ts: shallow key-sort, then
JSON.stringify the array). The two checksums are therefore not comparable, by design — each one
commits to the artifact it ships with. Verify the downloaded document with the snippet above, and
the CLI export with buildBacktestCorpusManifest.
3. Replay the scorer (anyone)
The published precision comes from the same pure functions any Node script can import:
scoreBacktest replays a classifier over the labeled cases, and compareBacktestScores applies
the Pareto-floor verdict between two scores. Replaying the shipped confidence floor over your
verified snapshot:
node --experimental-strip-types -e '
import { readFileSync } from "node:fs";
import { buildConfidenceThresholdClassifier, scoreBacktest } from "@loopover/engine";
const saved = JSON.parse(readFileSync("corpus.json", "utf8"));
const report = scoreBacktest(saved.ruleId, saved.cases, buildConfidenceThresholdClassifier(0.5));
console.log(report);
'
- "Reversed" is the positive class — a prediction of
reversedsays the rule's original firing was wrong, and it is scored against what a human actually decided. nullis never0. Precision and recall staynullbelow the decided-sample floor; the fairness report renders that as insufficient data, never as a zero.
4. Compare against the published numbers (anyone)
The fairness report renders each rule's decided-case count and measured precision from
the public stats endpoint's rulePrecision block. That endpoint is served by the API host, not by
this site, so fetch it absolutely — a bare /v1/public/stats resolves against loopover.ai and
404s:
curl -s "https://api.loopover.ai/v1/public/stats" | jq '.rulePrecision'
The same per-rule numbers are also published as digest-committed
EvalScoreRecords, each independently re-derivable without trusting the
transport — recompute recordDigest over the record's own remaining fields and compare:
curl -s "https://api.loopover.ai/v1/public/eval-scores" | jq '.records'
That array is empty whenever the latest backtest run's corpus is empty. A checksum over zero cases
is byte-identical for every rule and every window, so it commits to nothing a reader could re-derive
the scores from — publishing a record against it would assert a reproducibility that does not exist.
An empty records array therefore means the numbers are not currently committed to a corpus, never
that the numbers are zero.
The aggregated run history is readable directly too, again against the deployment's own database (operator / self-host):
npx tsx scripts/backtest-track-record.ts --db loopover --remote
Your replayed confirmed / decided for a rule should match the published precision for the same
window. The freeze-point checksum ties the published numbers to the corpus you just verified only
for the rule the latest run actually backtested — for any other rule it is a timestamped pointer to
a different run, not a commitment to that rule's own cases.
5. Verify an attested run (when a run carries one)
Placeholder pending real hardware. No production run carries a real attestation envelope
yet — that needs genuine AMD SEV-SNP hardware, tracked as
#8535–#8537.
Every command below is exactly what you will run once one exists; the software side (the harness,
the offline verifier, the deploy manifests) is already built and merged. Until then, exercise the
same verification mechanics against the project's own synthetic test fixtures — see
scripts/verify-attested-run/README.md — never against a real-looking file you were simply
handed, since that would defeat the entire point of this being independently checkable.
Replay (above) proves the numbers. Attestation is a second, additional path for a run that also
carries an AttestationEnvelope — it proves the computation that produced those numbers ran
inside genuine, hardware-encrypted memory, verifiable without contacting LoopOver at all:
npx tsx scripts/verify-attested-run.ts \
--envelope envelope.json --expected expected.json \
--vcek-cert vcek.pem --product milan
envelope.json— the publishedAttestationEnvelope:measurement,reportData,runId, the base64attestationReport, and its ownverificationstatus.expected.json— your own pinned expectations:{ "measurement": "<hex>", "corpusChecksum": "<hex>", "headSha": "<hex>", "baseSha": "<hex>" }— the same checksum and SHAs from the replay steps above, so both verification paths are checking the same underlying run.--vcek-cert— the chip's certificate; the tool defaults to this repo's own vendored AMD root chain, or fetches live from AMD's KDS with--fetch-vcek.
Under the hood, the tool recomputes reportData itself — buildAttestationReportData({ corpusChecksum, headSha, baseSha, runId }) — and checks it against the report's own user-data
binding, then walks the real certificate chain (ARK → ASK → VCEK, each a genuine X.509 signature
check) and verifies the report's own ECDSA-P384-SHA384 signature against it. Exit 0 means
verified; codes 1–8 each name a distinct, specific failure (see the script's own README for the
full table); 9 is a usage/IO error.
What this proves — and what it does not
Proved: the published scores are real computations over a real, checksummed, replayable corpus — not hand-entered numbers. Anyone can independently reproduce them from the snapshot. When a run also carries an attestation envelope, verifying it (above) additionally proves that exact computation ran inside genuine hardware-encrypted memory — a stronger, separate claim from reproducibility, checkable with zero contact with LoopOver.
Not proved, either way: that the live gate ran this exact code when it made its decisions. Attestation (like replay) only ever covers the offline backtest replay, never the live merge/close path — see the permanent-scope callout below. And attestation specifically proves computation, never data provenance: a genuinely attested run over dishonestly-recorded human-override history is still dishonest history, honestly computed. Closing that gap is tracked as its own explicitly-scoped question in #8136 and #8137. This walkthrough is honest about stopping at what each path actually proves rather than implying a stronger guarantee.
Live decision execution is permanently out of scope for attestation, by decision. The attested-evaluation epic (#8534) attests the offline backtest replay only. Attesting the live gate-decision path (the merge/close calls that actually act on a PR) was evaluated and declined — #9141 — because a network-reachable attestation service in the live request path trades a real availability guarantee for a proof the deterministic rule stage already gives more cheaply through replay (#8832, #8838), and because attestation proves computation, not the decision record's own honesty — the actual gap a skeptical verifier cares about, closed instead by an externally anchored, complete, replayable decision record. What "not proved" above means in practice: every live decision's provenance rests on the decision-record + replay + ledger-anchoring trust surface, never on attested execution — and that is not a temporary gap awaiting hardware, it is the standing design.