Skip to content

Release 0.3.0 under compatibility contract evidence-v3.2 - #6

Merged
Deep-Sixed merged 1 commit into
mainfrom
claude/relaxed-brown-dzjej0
Sep 23, 2026
Merged

Deep-Sixed merged 1 commit into
mainfrom
claude/relaxed-brown-dzjej0

Conversation

@Deep-Sixed

@Deep-Sixed Deep-Sixed commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

Work package: release integrity, step 1 of 2. Branched from main at c130317. This is the first half of the P1 finding from the repository review of the merged #2–#5 state.

The defect

PRs #3, #4 and #5 changed what admissible means, but the verifier kept reporting the identity of the build that came before any of them:

760977f (installer pin)   COMPATIBILITY = "evidence-v3.1"   VERSION = "0.2.0"
c130317 (main)            COMPATIBILITY = "evidence-v3.1"   VERSION = "0.2.0"

verifier_status decides whether records compose by compatibility alone; the commit and implementation digest are provenance and are never compared. So a record judged under the pre-hardening rules composed beside a record judged under the new ones. The pinned 760977f is such a build: 26 commits and +531/−39 lines of verify.py behind main, and it cannot even read the committed evidence = "…/3" policy line.

The change

Design doc §J: "A release that changes evidence semantics increments the contract and says so in its notes."

verifier_status already refuses any contract other than the verifier's own (it rejects anything not equal to COMPATIBILITY), so no composition logic changes. Once the contract is bumped, evidence-v3.1 records are refused.

Regressions (3; all fail against main)

  • test_records_from_the_pre_hardening_contract_are_refused: an evidence-v3.1 record is INADMISSIBLE on its own ("the rules in force") and beside current records ("different verifier contracts").
  • test_composition_refuses_a_record_from_the_pre_hardening_contract: the same through compose on an activated repository. The record is the checkout's own run, re-stamped, so only the contract can refuse it.
  • test_the_release_notes_name_the_contract_this_verifier_applies: the newest CHANGELOG entry must name this verifier's VERSION and COMPATIBILITY. The contract can't move without the notes moving too.

Why the installer pin is not moved here

install-ladder.sh fetches the real origin and refuses a pin that is not already an ancestor of origin/main, and two network-marked installer tests reach that check. Pointing the pin at this PR's own commit would turn CI red until merge. It also can't name the commit that contains it. So the pin moves in step 2, after this merges:

  • PIN in install-ladder.sh and check-install.sh;
  • CHECKER_SHA, which changes because check-install.sh changes;
  • INV_SHA, re-validated. The invariant block in INSTALL.md hashes to 282f2117… at both 760977f and main, so it's expected to stay;
  • the PIN constant in tests/test_install_scripts.py, and the docs that say "the pin predates scripts/", which stops being true;
  • a proposed first tag, v0.3.0. Tags are outward-facing, so I'll propose one rather than create it.

Consumer testing against Cerberus follows the pin move.

Deliberately not changed

  • docs/design/evidence-v3.md: its seven mentions of evidence-v3.1 / 0.2.0 are the §J example and the historical M4 record, not statements of the current identity.
  • The review's other findings (load_json shape, evidence-dir exclusion, nested-repo symlink) belong to a later hardening package. Branch protection is a repository setting.

Verification

Climb against f0cacf404f58 + sha256:28967a9dc9b9, over a baseline captured on
main at c130317:

    architecture       PASS    attestation  agent
    diff               PASS    attestation  agent
    fresh-review       PASS    attestation  agent
  * lint               PASS    execution    local, ci run 35843499956
    requirements       PASS    attestation  agent
    self-review        PASS    attestation  agent
    task               PASS    attestation  agent
    tests              PASS    execution    local
  * tests-py311        PASS    execution    ci run 35843499956
  * tests-py314        PASS    execution    ci run 35843499956
  --------------------------------------------------------------
  BLOCKED REQUIRED GATES   0
  STALE EVIDENCE           0
  STATE MATCH              TRUE
  CLEAN CLIMB              TRUE
  --------------------------------------------------------------
  READY FOR HUMAN GATE     TRUE
  • Local suite, read from the record: 399 passed, 1 skipped (396 + 3);
    drift: false. Ruff clean.
  • Both CI events on this head are green: push run
    35843499956
    and pull_request run
    35843533175.

This repository's own climb runs under evidence/2, which it has not moved off.
Its evidence/2 compose never reads verifier_status, so the bump doesn't
touch it. The contract is read only for evidence/3 records: by compose under
evidence/3, and by the shadow comparison behind qualify and compare.

🤖 Generated with Claude Code

https://claude.ai/code/session_016m6di8xFVdwwq949mJx9U1


Generated by Claude Code


Generated by Claude Code

#3, #4 and #5 changed what admissible means - drifted and refused records
are rejected at composition, CI evidence binds the whole provenance chain
against policy-declared expectations, and the adopted contract is committed
and fails closed - while the verifier kept reporting `evidence-v3.1` /
`0.2.0`, the identity of the build before any of it. `verifier_status`
decides composability by that contract and nothing else, so records judged
under the older, weaker rules still composed with records judged under the
new ones. The installer's pinned verifier, 760977f, is such a build.

§J of the design says a release that changes evidence semantics increments
the contract and says so in its notes. The contract is now `evidence-v3.2`,
VERSION and pyproject move to 0.3.0 together, and CHANGELOG.md is the notes:
what moved, and that `evidence-v3.1` records must be re-established.

Regressions: a record carrying `evidence-v3.1` is refused, alone or beside
current records, both at `verifier_status` and through `compose` on an
activated repository; and the newest CHANGELOG entry must name this
verifier's VERSION and COMPATIBILITY, so neither can move without the notes.
All three fail against main.

The installer pin is deliberately not moved here: `install-ladder.sh`
refuses a pin that is not already an ancestor of origin/main, so it can only
name this release once it has merged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016m6di8xFVdwwq949mJx9U1
@Deep-Sixed
Deep-Sixed marked this pull request as ready for review September 23, 2026 09:57
@Deep-Sixed
Deep-Sixed merged commit c86bf47 into main Sep 23, 2026
2 checks passed
@Deep-Sixed
Deep-Sixed deleted the claude/relaxed-brown-dzjej0 branch September 23, 2026 09:58
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.

2 participants