Reference: Incremental update vs full rewrite
Engine 1.32.0 contains no new read, no new family and no new detection. What one revision of a PDF wrote, counted by kind and narrowed to what a page can reach, has been computed for every revision of every document since 1.20.0. Until this release it left the engine only as a sum.
Now two evidence blocks carry it per revision, both numbered from 1, where revision 1 is the original save:
The two new keys, on families that already fire
incremental-updates.evidence.changedPerRevision[].touched
signature-permissions.evidence.revisionsAssessed[]
The sum failed differently in each family
signature-permissions added its appended revisions together and
reported the total. So a report could say this certification was
broken and never by which of the four appends. On a document
with one append those are the same sentence. On a certified contract with six
appends, five of them permitted form fill-ins, they are not, and the reviewer
holding the report has to go find the one that mattered by hand.
incremental-updates failed the other way. It published object
numbers and a kind classification for the objects a revision
replaced, which is blind to a revision that only adds: a new
annotation, a new page, a further signature. A permitted form fill-in produced
a row carrying a list of object numbers and an empty kind list, which is
exactly what a revision that did nothing worth naming also looks like. Two
different revisions, one of them interesting, indistinguishable in the
output.
The rows cannot contradict the headline, and that is arithmetic
A per-revision surface invites one specific defect: a document-level verdict that no row underneath it supports. The reason this release does not need to fear it is that the per-revision verdict is the same pure function the document-level one has been since 1.24.0, applied to one revision's counters instead of the total. Every branch of that function turns on a counter being non-zero, and a sum of non-negative integers is non-zero exactly when one of its terms is. So the document-level assessment is always the strongest of the per-revision ones, by construction rather than by review.
It is still checked, because "by construction" is a sentence and sentences
rot: test/engine/revision-detail.test.ts sweeps every PDF fixture
in the repository, collects every violation before asserting, and fails if any
document's headline ever outruns its rows.
Seven counters partition. The eighth narrows. I summed eight.
Each row carries eight counters. Seven of them
(pageContent, images, pages,
widgetAnnotations, otherAnnotations,
signatures, other) partition the revision's total
writes: they sum to objectsWrittenTotal, every object in exactly
one bucket. The eighth, pageImages, is not a bucket beside them.
It is a subset of images: of the images written, how many a page
actually draws.
I wrote the first version of the sweep test summing all eight, and
certified-page-image-added.pdf failed it immediately: 3
classified against 2 written, because the one page-drawn image had been
counted in images and again in pageImages. The
fixture was right and the test was wrong, which is the better order to
discover it in. It is also the same distinction a full corpus run charged
engine 1.24.0 to learn in the opposite direction: an image was
written and a page draws it are different facts, and neither
substitutes for the other. The OpenAPI description and the architecture doc
now state the subset relation in the same breath as they offer the numbers,
because a consumer who totals the eight will otherwise rediscover my bug in
production.
Counts, not a diff, and the report says which
The boundary is worth stating as plainly in a post as the release states it in the schema: these are counts of objects by kind. Nothing in this engine renders two revisions and compares them.
"Revision 3 rewrote one page content stream and added two form fields" is what is known, and it is a lot: on a certified document there is no reading of that row compatible with nobody touched the page. "Revision 3 changed the amount from 1.200,00 to 12.000,00" is not known, and producing it is a different capability with a different cost, no measurement behind it and no fixture population. A competitor in this space sells "versioning that shows exactly what changed" and publishes no measurement of any kind. This release is the half of that claim that is true, labelled as which half it is.
Nothing. No severity, no score, no band; both additions are new keys on families that already fire, and every existing evidence key keeps its shape. The evasion bench re-ran anyway, because its own rule is that a version bump without a re-run means nobody checked: 92 fixtures, seven evasions, and the recorded summary came back identical to the 1.31.0 record in every field except the version it stamps.
Walk a chain yourself
The fastest way to build an intuition for revision chains is to look at one from a file whose history you know: a contract you signed digitally, a form you filled, a statement you downloaded. The revision tool draws the chain, and since 1.32.0 the report's evidence carries the per-revision rows this post is about.
See a PDF's revision history: free, nothing stored, and the file is parsed in memory and discarded with the response. A signed document with three appends is normal. The interesting question is what each append wrote, and now the report answers it.