The proof verifier
A package is sealed by its design root, and the other three documents are not. A package that goes to an assessor comes without its case, its run bundles and the readers that made it. So the proof verifier makes a fixed list of named checks, and each check says what it found. It names every check it did not make. A pass then never says more than the package supports (SEG-SREQ-236).
affirmatrix.proof.verify() reads one package directory and returns a
Verification with ten
Check values, always in the same order. The command
line page shows how proof verify prints them (Command line and configuration).
Four statuses
passedandfailedThe verifier reached a verdict.
not judgedThe operator asked for the check, and the verifier could not reach a verdict. A run bundle that the package does not list the partner of, or a design that the readers do not supply, gives this status.
not madeThe operator did not ask for the check, so nothing was tried.
A check that fails or is not judged has a detail that names the subject: a
digest, a node, or both ends of an edge. The verifier raises no error for a
package that reads but fails a check.
The ten checks
Check |
Needs |
What it asks |
|---|---|---|
|
the package |
Does the design recompute to the recorded root? (SEG-SREQ-237) |
|
the package |
Do the documents and the directory name one package? (SEG-SREQ-238, SEG-SREQ-264) |
|
the package |
Do the documents agree on members, set-aside, skipped and excused outcomes, and revision? (SEG-SREQ-239, SEG-SREQ-265, SEG-SREQ-266, SEG-SREQ-267) |
|
the package |
Does the report record an unblocked scope? (SEG-SREQ-240, SEG-SREQ-268, SEG-SREQ-269) |
|
a case |
Does a review event bind each design edge? (SEG-SREQ-241) |
|
run bundles |
Are the given bundles the listed ones? (SEG-SREQ-242, SEG-SREQ-243) |
|
run bundles, configuration |
Do the readers supply the design of the package? (SEG-SREQ-244) |
|
run bundles, configuration |
Do the outcomes and findings rebuilt from the bundles equal the recorded ones? (SEG-SREQ-245) |
|
run bundles, configuration |
Does the rebuilt scope mint the recorded identifier? (SEG-SREQ-246) |
|
nothing |
Always |
The first four checks need nothing but the package. They are always made, with no
configuration, no case and no run bundle (SEG-SREQ-270). Without a case,
affirmations is not made. Without run bundles, the four bundle checks are
not made.
The root
root calls affirmatrix.proof._package.sealed_root(), the same function
that seals a package at generation. It takes the scope, the revision, the node
hashes and the design edges from the design consistency proof and from nothing
else. The generator and the verifier share this one function, so they cannot
drift apart. The hand recipe of the tutorial gives the same value.
The other three documents are not sealed. A whole new set of consistent siblings passes the four package checks. The checks that need the case or the bundles are there for this reason.
Affirmations
A review event binds an edge when the node hash of each end, derived from the content hashes that the event holds, equals the node hash that the package records for that end. The edge needs one such event. The check asks whether these hashes were ever affirmed. The store has no event that revokes an affirmation, so one binding event is enough, and an older event made against other content does not count against a later one.
A pass shows that the case holds an affirmation for each edge at the recorded hashes. It does not show who made it. The case is not sealed.
The run bundles and the rebuild
With run bundles, the verifier works in this order.
bundle-digestscomputes the digest of each given bundle. A bundle that the package does not list is a mismatch and fails the check. If every given bundle is listed but a listed bundle is not given, the check is not judged. A mismatch outranks a missing bundle.design-guardbuilds the design from the readers that the configuration names, with no run bundle, and compares it with the package. Each design node needs the same node hash, and each design edge needs to come from a reader. A change of requirement text since the package was made is a mismatch. The check reads the configured sources by hash and runs no git command.Only when both passed, the rebuild runs. Otherwise
rebuilt-evidenceandsnapshot-idare not judged, and nothing is rebuilt.
The rebuild reads the run bundles through the readers, collects the scope of the package, and judges it with the package gate. It judges at the revision that the package records and at the date of the snapshot timestamp that the recorded identifier carries. It does not use today’s date. It then compares the rebuilt execution coverage record and the rebuilt coverage report with the recorded ones. It mints the snapshot identifier again from the rebuilt scope, with the recorded timestamp, and compares that too.
The rebuild takes the design edges of the package as affirmed. A package exists
only for a scope that the gate found ready, so each design edge was affirmed when
the package was sealed. A strong edge that the readers supply and the package does
not record keeps the state the readers give it. It shows as an unready edge, and
the rebuilt report then differs from the recorded one. affirmations shows the
affirmations separately, against the case.
A run bundle that the outcome extractor refuses ends the verb with exit status 2 and no report.
Where it lives
affirmatrix.proof._verify holds the checks. affirmatrix.proof._stored
holds the reader of a package directory and the summary for proof show. The
reader is affirmatrix.case.read_package_directory(). It validates each
document with the schemas that the tool carries, so a package outside any case
reads the same way as one inside a case.
The verifier calls the configured readers. For this reason the proof component
may import the sources package, and tests/unit/test_import_layering.py lists
it. The sources package imports nothing above the records, so there is no cycle.
The verifier reads no repository, takes no current revision, and writes nothing.