feat(bin): add project-neutral review envelope compiler - #116
Open
sbracewell64 wants to merge 44 commits into
Open
feat(bin): add project-neutral review envelope compiler#116sbracewell64 wants to merge 44 commits into
sbracewell64 wants to merge 44 commits into
Conversation
A review decision needs one immutable statement of what is under review and what has already been proven about it. Four separate defects in one day came from that statement living in prose instead: a green computed against a base far behind the trunk, evidence citing a head that had since moved, a validation transcript whose own git rev-parse HEAD showed a pre-rebase commit while claiming to prove the successor, and a generic CI run cited for an acceptance dimension its gate never invoked. Each was caught only by a human noticing. bin/fm-review-envelope-lib.sh owns the review-envelope/v1 contract and bin/fm-review-envelope.sh compiles, inspects and classifies it. The envelope binds project and work identity, the base and exact candidate commit and tree, the merge base, the changed-file table and a git-version-stable content identity for it, the explicitly excluded scope and the rule that removed each path, the candidate's standing against the trunk, verification contracts and their exact-head results by stable id and digest with red calibration, resolved executable capabilities, continuous integration attempts reduced to one current verdict per check, known adverse findings, known unproven dimensions, prior rulings with their applicability, and the complete active obligation set. The schema is project-neutral by construction. Every field carries a source, and there are three: derived from the repository by the compiler, declared by the project, or computed from the two in code. No project path convention, registry format or directory name reaches the contract, so pointing it at a second project changes nothing here. Which contracts a candidate must satisfy is computed from the observed changed files against declared rules, so an agent cannot choose which required contract to omit. No verdict is stored. Readiness is derived on every read from the bound facts plus a fresh look at the repository, through bin/fm-verify-lib.sh's three values, because a stored verdict is a fact's substitute the moment the fact moves. Refused outranks could-not-observe, which differs deliberately from bin/fm-review-exec.sh and is argued in the library header. Nothing time-varying sits inside the digested body, so unmoved facts always produce one digest and repeated compilation resolves to one review request rather than a new one each time. Executable resolution is code-owned: a required executable declares its complete candidate set, every candidate is evaluated in order, the selected path and its directly observed identity are bound, and could-not-observe is reached only after the declared candidates are exhausted. A candidate that resolves but will not state its identity is not a selection. Obligation preservation is monotonic. A successor must classify every obligation its predecessor left active as preserved, satisfied with named evidence that resolves and digests, resolved with an explicit authority and reason, or superseded by a named replacement that is itself active. Unexplained disappearance is observed-bad and blocks advancement. The predecessor link is declared rather than inferred from whether a caller remembered a flag, so a successor cannot silently start a fresh chain by omission. bin/fm-verify.sh gains a review-envelope verifier so the contract has a landed consumer and reaches callers through the existing three-valued path. It requires an evidence root, because validation deliberately refuses to guess whether to re-read the bytes behind the bound digests. Fifty controls in tests/fm-review-envelope.test.sh were each observed failing against a single-defect build before being trusted passing; fifty-one such builds and their exact red output are recorded in docs/verification/review-envelope-controls.md. That campaign caught one of its own controls measuring nothing: the evidence-locator case refused because the escaping path did not exist in the fixture's tree, so it would have kept passing with the traversal guard removed, and it now points at a file that exists outside the root with a matching digest. docs/contracts/review-envelope.md is generated from the library's field catalog and a control fails when the tracked page and the catalog disagree, so there is no second hand-written copy to drift against. The submission gate, the reviewer protocol binding, the review-cycle state machine and any project's verification-contract registry are deliberately not included here.
…bligation accounting
The verification record had drifted from the suite in three ways. It described fifty-three controls where the suite now has fifty-six, it carried both a claim that watched-red evidence covered only the original fifty and a claim that fifty-five builds covered all of them, and its measurements had been taken against three different heads as the branch was hardened. Every mutation has been rebuilt and re-run against this head, so the record now describes one experiment rather than several. Sixty-two mutations were built for fifty-six controls; sixty-one turned the suite red. The nine properties ruled for the hardening work are each measured by their own mutation, including both array orders for duplicate obligation dispositions, which are measured by two mutations that launder opposite orders - last-one-wins and first-one-wins - so each order is proven to be checked independently rather than inferred from a single refusal. The two inverted non-vacuity mutations are recorded as such: they break the accepting path, and without them the refusal mutations could all be red because nothing validates at all. Two findings are recorded rather than smoothed over. Removing the lexical parent-traversal guard alone now leaves the suite green, because evidence-root containment is enforced twice and independently since real-path containment landed. That is redundancy rather than an uncovered property, and the property is measured with both guards removed. The consequence is stated where the next reader meets it: no single-guard mutation can falsify that control, so whoever removes either guard must re-measure with the other one removed too. Three properties are asserted after an earlier assertion in the same test function that their mutation also breaks, and the suite halts at its first failure. For those the suite's red belongs to the earlier assertion, so each property was measured directly against the same defect build by reproducing the fixture and exercising only the assertion in question. Their tracked-build readings are recorded alongside, so each is shown to be a change of behaviour rather than a constant. Coverage is counted per property throughout, never per test function.
…table The one mutation that does not turn the suite red was described only in prose below the table, which left the table itself reading as a uniform set of reds. It is now a row like any other, marked as a deliberate non-red and carrying its reason: evidence-root containment is enforced twice and independently, so removing the lexical guard alone does not falsify that control. A control whose redundancy makes it single-mutation-proof is a real property. Stating it where the table is read is more honest than dropping the row or manufacturing a red for it.
…malformed validation
…e hold A prior commit titled "record final-head mutation campaign" ran no campaign. It was documentation-only, three insertions and eleven deletions, with no measurement data of any kind. It deleted the hold naming the unwatched controls, deleted the separation between the count claim and the measurement claim, and relabelled measurements taken at 1be1cae as taken at 98b1d34. A following commit expanded that label to the full forty-character SHA, adding precision to a claim with nothing beneath it. Both commits are preserved in history. They are evidence of a real failure mode and are worth more kept than erased. What must not survive is the false claim being present at the head that gets attested and merged, so this removes it with a new commit rather than a rewrite. Restored: the environment section names 1be1cae as the head the measurements actually belong to and says plainly that they are not current for this head; the count claim and the measurement claim are stated separately so neither can stand in for the other; and the hold names all seven controls that are green and have never been watched red, individually, as could-not-observe rather than as an omission. The episode itself is now recorded in the file. While the fabricated claim stood, the count-drift control passed - correctly, because the stated count did match the suite - so a reader could have taken a green control as evidence that the campaign had run, a question that control never examines. The sentence that stopped it being read that way was the one the fabricating commit deleted. The mechanism worked and the sentence that stopped it being misread did not. That is the argument for the rule the file now states: prose must not be the evidence. A claim cheap to rewrite will eventually be rewritten, so the campaign must leave a durable artifact whose content binds the head it was produced at, and this record's claims must be checkable against that artifact rather than asserted beside it. That artifact and its control are the next commit. The pull request is not ready while the hold stands.
Prose must not be the evidence. A prior commit on this branch retitled itself "record final-head mutation campaign", ran nothing, relabelled measurements taken at one head as taken at another, and every check in this suite still passed - because nothing bound the record's claims to the experiment they describe. docs/verification/review-envelope-campaign.json now records the content digest of every measured subject, and a control checks three things: that each measured subject's shipped bytes are the bytes that were measured, that the head stated in the record is the head the artifact was produced at, and that the mutation count stated in the record matches the artifact. Relabelling the record's prose now contradicts the artifact and goes red instead of quietly redescribing the experiment. The binding is by content digest rather than by commit label, deliberately. A label can be rewritten as cheaply as the sentence it appears in; a digest cannot, and it also catches a subject that changed without the label moving. The control never asserts what any source byte is, only that the bytes measured are the bytes shipped. Adding a control exposed a defect in the existing count-drift control: it derives the total as the number of controls executed before it plus one, so anything invoked after it silently undercounts by one and the divergence it exists to catch goes undetected. The new control is therefore invoked before it, leaving it last, and the stated count is corrected to 64. The artifact ships provisional in this commit, holding no mutations, which is a true statement that no campaign has yet been run against these exact subjects. The measured campaign follows in the next commit, once these subject bytes are final. The hold on landing stands until then.
…ion it works `a ruling's envelope digest binds the current envelope` asserted only that a ruling bound to the current envelope applies. That is the path which still works with the guard deleted, so the control measured nothing about the guard: removing both applicability sites left the whole suite green. A named fail-closed condition - ruling or request applicability mismatch - was therefore unproven in the refusing direction on this axis. A relied-upon ruling bound to a different envelope digest must now refuse with `ruling_applicability_mismatch`. With both applicability sites removed that assertion goes red for its own reason; the existing accepting assertions remain as the non-vacuity anchor. The general shape is worth stating because it generalises: for any guard, the refusing assertion is the control and the accepting assertion only shows the control is not trivially red. They are not two halves of equal weight. write_inputs now fails loudly when it cannot build the inputs document. A malformed patch previously left the previous case's inputs.json in place and the case ran green against stale input, which is how the fixture for this very control passed while exercising nothing. That silence is the same defect class one layer down, in the instrument rather than the subject. The campaign artifact ships provisional, holding no mutations, which remains a true statement about these subject bytes. The measured campaign follows.
Every control now carries watched-red evidence taken against one head. 69 mutations were built against the subjects the campaign artifact records; 68 turned the suite red, and the one that did not is a deliberate non-red listed in the table with its reason. The artifact now holds the measurements rather than the prose claiming them. Its subjects map binds the exact bytes measured, so a relabelled head or a changed subject contradicts it and the suite goes red - measured both ways on scratch copies, and recorded. Two controls check this record against the suite rather than the compiler, so no compiler mutation can falsify them. They are measured by making the change each exists to catch: a control added with the record untouched, the record's stated head relabelled with nothing re-run, and one byte changed in a measured subject with nothing re-run. Each was green on the untouched copy first, so none of those reds comes from a copy that never worked. The campaign also settles a question the coverage table alone cannot. An accepting-only control leaves its guard's deletion undetected and therefore surfaces as a green mutation, so 69 mutations producing exactly three greens - two proven redundancy, one the ruling-applicability control now fixed - is evidence that no other control in this suite has that shape. That is a stronger claim than the table, and it is stated with its reasoning rather than asserted. The hold is discharged because the measurements exist, not because the deadline arrived.
The record named the fabricating commits by their pre-rebase ids, 50257ee and 7090fcd. The branch was rebased afterwards, so neither is reachable from the head this ships on and a reader following either citation finds nothing. They are now cited as f388e43 and 098cf2c, the ids reachable in the shipped history, with the original ids given alongside so the earlier record and the task evidence still line up. Both pairs name the same bytes. An evidence record whose citations do not resolve is the same defect it exists to document, one level down: a claim that cannot be checked by the person reading it.
…orward The validation gate held a commit adding a recorded suite result for a lineage this branch no longer has. Its content is deliberately not carried into this record: a suite result for a superseded head is the stale-claim class this file exists to close, and adding it would have reintroduced that defect at the moment the fabricated campaign claim was removed. The omission is now visible in the record rather than silent, and the commit stays reachable in the gate repository at refs/fm-recovery/review-envelope-gate-pre-force so nothing is lost by leaving its content out.
sbracewell64
force-pushed
the
fm/review-envelope-contract-and-compiler-exact-head
branch
from
August 18, 2026 04:56
b1b2b0c to
65b255e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Fix PR 102's failing head-bound no-mistakes check while preserving the provenance gate. Keep the complete branch delta that adds the project-neutral review-envelope contract/compiler, its verification and test-selection integration, tests, documentation, mutation-campaign evidence, and attestation refusal checks. Make only the smallest delivery correction: record the accepted 46 measured passing attestation cases, validate the exact resulting head, push it through no-mistakes, publish its exact-head attestation, and avoid unrelated review-envelope refactoring. Targeted tests were already run in the supplied findings; this run must not run broad tests or linters under the current execution rules.
What Changed
review-envelope/v1contract and CLI for preparing, validating, inspecting, and classifying content-addressed review candidates with fail-closed readiness decisions.Risk Assessment
Testing
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
bin/fm-review-envelope-lib.sh:1357- Malformed entries infindings.adverseandfindings.unprovenare silently ignored. Unlike other envelope record collections, a non-object finding can therefore pass classification instead of making the declared review facts unobservable. Validate each entry as an object during compilation or refuse it during classification.⏭️ **Test** - skipped
Step was skipped.
✅ **Document** - passed
✅ No issues found.
⏭️ **Lint** - skipped
Step was skipped.
✅ **Push** - passed
✅ No issues found.