Engine changelog

The engine is versioned and every report says which version produced it. This page lists what each release added, because a detection engine that changes silently cannot be regression-tested, and being testable is the point of a deterministic one.

How versioning works here

Same bytes in, same report out: the engine reads no clock and no randomness of its own, so a caller can pin a document and a version and reproduce a report exactly. Three consequences follow.

First, every response carries an engineVersion field, and GET /api/v1/health reports the version currently serving. Second, every accuracy figure we publish on the evidence page is stamped with the version it was measured on. A number without a version is not checkable, so we don't publish one. Third, when a release changes what a signal family reports, that is a fact about the release, not a quiet drift: it lands here.

Signal families by release

Eighteen signal families run on any PDF today; a further one, issuer-mismatch, runs only when the caller supplies an issuer baseline and is deliberately left out of the public count. The founding releases shipped the core history-reading set; everything since is listed with the version that introduced it. Families are described fully, each with its benign causes, in the signal field guide.

Engine Signal family What it asks
1.27.0 glyph-anomalies Do the glyphs on the page carry retyping residue: subset, kerning or baseline patterns that differ from the text around them?
1.25.0 running-balance-break Does a statement's balance column actually follow from the rows above it?
1.21.0 br-identifier-checksum Do the Brazilian identifiers printed in the document pass their own check digits: CPF and CNPJ at introduction, extended in 1.26.0 to NF-e access keys, boleto lines and PIX payloads? Arithmetic only: a number is validated, never looked up.
1.20.0 signature-permissions What did the signer say could follow the signature, and did what followed stay inside it?
1.15.0 signature-integrity Does what the signature spans still hash to what it committed to?
1.14.0 embedded-image-anomalies Do the images inside the PDF (the JPEG inside a "scan") tell the same story as the file that carries them?
1.13.5 document-injection-markers Is there content in the file addressed to whatever processes it next, rather than to the reader in front of it?
1.4.0 redaction-exposure Did an intended removal actually remove anything, or is the text still live under the rectangle painted over it?
1.3.0 issuer-mismatch Does the document match a caller-supplied baseline of what this issuer's genuine output looks like?
Founding releases incremental-updates, metadata-mismatch, date-anomalies, producer-fingerprint, id-inconsistency, font-anomalies, hybrid-page, active-content, signature-coverage, structure-warnings The core history-reading set: revisions appended after creation, metadata that disagrees with itself, dates that cannot be in that order, a producer that changed, fonts and pages that arrived from somewhere else, and what a signature covers.

Beyond PDF

Office packages (docx, xlsx, pptx) have been inspected by a dedicated engine since 1.6.0, and images by their own signal set, compression history, metadata consistency, provenance and timeline. Both report through the same shape: signals with evidence, a band, and the version that produced them.

What a release never changes silently

Recalibrations that change scores or bands are the releases we document hardest, because they move numbers a caller may have built policy on. The measured effect of the largest one (and the false-positive rates before and after it) are published on the evidence page, stamped with the versions involved. If a figure there and a version here ever disagree, the figure is wrong and CI is supposed to have caught it before you did.