Skip to content

feat(bin): add project-neutral review envelope compiler - #116

Open
sbracewell64 wants to merge 44 commits into
mainfrom
fm/review-envelope-contract-and-compiler-exact-head
Open

feat(bin): add project-neutral review envelope compiler#116
sbracewell64 wants to merge 44 commits into
mainfrom
fm/review-envelope-contract-and-compiler-exact-head

Conversation

@sbracewell64

@sbracewell64 sbracewell64 commented Aug 18, 2026

Copy link
Copy Markdown
Owner

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

  • Add the project-neutral review-envelope/v1 contract and CLI for preparing, validating, inspecting, and classifying content-addressed review candidates with fail-closed readiness decisions.
  • Integrate review-envelope verification into the verifier and targeted test-family selection, with comprehensive contract, adapter, mutation-campaign, and generated documentation coverage.
  • Strengthen attestation refusal assertions and record the exact measured result of 46 passing attestation cases for the validated head.

Risk Assessment

⚠️ Medium: The provenance gate is broadly fail-closed, but malformed finding records can be omitted silently from its readiness decision and should be rejected before merge or addressed promptly.

Testing

  • ⏭️ Test - skipped

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 warning
  • ⚠️ bin/fm-review-envelope-lib.sh:1357 - Malformed entries in findings.adverse and findings.unproven are 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.

sbracewell64 and others added 30 commits August 18, 2026 00:53
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.
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.
…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
sbracewell64 force-pushed the fm/review-envelope-contract-and-compiler-exact-head branch from b1b2b0c to 65b255e Compare August 18, 2026 04:56
@sbracewell64 sbracewell64 changed the title feat(bin): add review envelope compiler and provenance validation feat(bin): add review envelope contract and compiler Aug 18, 2026
@sbracewell64 sbracewell64 changed the title feat(bin): add review envelope contract and compiler feat(bin): add project-neutral review envelope compiler Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant