Repository navigation
Releases
v6.5.0
A feature release following 6.4.0, with an offline Sigstore bundle verifier and stricter in-toto statement checks. It adds proofbundle verify-sigstore, which verifies GitHub Artifact Attestations and npm provenance offline against the trusted root, the artifact digest and the identity the relying party supplies. The verifiers for eval-result v0.1, test-result v0.1 and SVR v0.1 statements now refuse statements that lack the members their predicates require or that carry them in another form, and every rfc3339z time field must name a real calendar instant. Statements that a released version accepted with such members missing or malformed no longer verify. That includes statements that earlier exporters of this package emitted from caller-supplied time, claim timestamp or test-result url values in another form; the CHANGELOG names each case.
python -m pip install --upgrade proofbundle==6.5.0
Highlights
proofbundle verify-sigstoreverifies GitHub Artifact Attestations and npm provenance offline. It checks one Sigstore bundle under the profilesgithub-artifact-attestation,npm-provenanceandnpm-publish, from the Fulcio leaf and its embedded SCT to the inclusion proof and the checkpoint, and an in-toto Statement with a SLSA Provenance v1 predicate. It imports no Sigstore client.safeForAutomationis false in every verdict, since revocation and log consistency over time are not checked.- Stricter checks for eval-result v0.1, test-result v0.1 and SVR v0.1 statements. An eval-result v0.1 statement must carry its eight required members, at least one claim, and the required forms of
verifier,suiteandsubjectProfile. A test-result v0.1 statement must carryresultandconfigurationwith the required types. An SVR v0.1 statement must carryverifier,verifier.id,timeCreatedandproperties. The affected URI and timestamp fields are now validated as described in the entries below.proofbundle intoto --verifyandproofbundle svr --verifyreport the verifier's failure reasons; the meanings of their exit codes are unchanged. - Time fields name a real instant. Every
rfc3339ztime field checks month, day in month, hour, minute and second after its form, sodecision verify --strictrefuses adecidedAtof2026-13-15T09:05:00Z. The Rust verifier applies the same rule to the one time field it checks. - Stricter input and binding checks, and lower memory use in five JSON traversals. The Bitcoin header map in the trust policy,
--bitcoin-header,--bundled-header, the agent-review policy file and the SD-JWT bundle-binding check now reject inputs or bindings they previously accepted. Five JSON traversals carry paths as links and render path text only when needed for a message, keeping memory use proportional to the input and any supplied path declarations.
Verify this release yourself
Use the checksums and build provenance to check the downloaded files. To check the signed pre-tag audit receipt, use a clone at the source commit identified by the build attestation. The commands, prerequisites and limits are in Verifying a published release.
What a receipt still does not prove
A valid signature binds the signed content to the signing key. It does not make a reported result true.
decision verify and outcome verify do not implement the complete offline verification procedure in draft-gruszka-audit-decision-receipts-05. They do not perform all the procedure's checks for approval records, action bytes, executor identity, separation of keys and identifiers, effects and the execution-time window. decision verify also exits 0 when the evaluation time is before decidedAt, although Section 3.2 step 9 of revision 05 requires decidedAt <= T.
A Statement with two subject entries, which Section 3.2 step 6 does not allow, exits 0 without --require-derived-subject and 2 with that switch. Both measurements use --strict, the gate-1 public key, --aud observer-1, --nonce dec-0002 and --verification-time 2026-10-15T09:06:00Z. The valid V2 control still exits 0 with the switch. These command results are not verdicts of full conformance to revision 05.
Without --policy, decision verify does not establish that decisionMaker.id is the identity trusted for the signing key. In vector F3 of Appendix A.5 of draft-gruszka-audit-decision-receipts-05, the receipt names gate-2 under the gate-1 key. With --strict, --aud observer-1, --nonce dec-0002 and --verification-time 2026-10-15T09:06:00Z, it exits 0 without a policy and reports POLICY: NOT_EVALUATED. The same invocation exits 3 when --policy supplies a trusted_decision_makers mapping from that key to gate-1. These results depend on the stated verification time; they do not mean that an expired receipt passes without a policy. The command does not read or hash the evidence bytes referenced by evidenceRefs, with or without that test policy.
Measured on the reference machine
The budget cost axis was measured on the reference machine on 2026-11-06 using the code at 14fe339. The record identifies the run as a reference measurement (ist_referenzmessung=true). All 12 expected axes and all 7 expected combinations passed, and no axis was skipped. The recorded calibration factor maschinenfaktor_schnellstes_ende is 1.036, and the timing-limit setting is latte_aus_der_klammer=schnellstes_ende. These results apply to the listed axes and combinations, not to every reader or input. The measurement record lists every axis and combination.
Details
All 20 entries, one line each, as in the CHANGELOG
Added
proofbundle verify-sigstoreverifies GitHub Artifact Attestations and npm provenance offline.proofbundle.adapters.sigstore_bundle.verify_sigstore_bundlechecks one Sigstore bundle against the trusted root, the artifact digest and the identity the relying party supplies. It reads media types 0.1 to 0.3, a DSSE envelope and Rekor v1 entries of kinddsseandintoto, under three profiles:github-artifact-attestation,npm-provenanceandnpm-publish. It verifies the Fulcio leaf, its chain at every verified time and its embedded SCT, the signed entry timestamp, the inclusion proof and the checkpoint, and an in-toto Statement with a SLSA Provenance v1 predicate under the rules of the two GitHub workflow buildTypes, their four allowed events included. For npm-publish, supplying the version document also checks itsdist.signaturesagainst the registry's keys. For npm-provenance, supplying package.json also checks its package identity and repository. The reader does not open the tarball; the relying party must supply package.json from the artifact whose digest it provides. Whether the predicate agrees with the certificate is reported as a note, because those rules come from the producers' code and not from a specification. It was written from the specifications pinned inSPEC_PINand imports no Sigstore client. Unknown members of the DSSE envelope are refused, a deviation from DSSE thatdocs/SIGSTORE_BUNDLE_VERIFIER.mdnames. The exit codes follow the TRACE reader: 0 verified, 1 a cryptographic or structural failure, 2 unreadable input or a feature not implemented, 3 an unmet requirement of the relying party.safeForAutomationis false in every verdict, since revocation and log consistency over time are not checked. Each vector oftests/fixtures/sigstore_bundle/fails at the step it names, and public bundles of the npm registry and of the cli/cli test data verify offline against the vendored public-good root. It is Python only, and its parity register row is PENDING.
Changed
- docs/predicates/action-outcome.md no longer lists the attestation of
executor.idas closed, and docs/NON_CLAIMS.md names the outcome checks proofbundle does not perform. The trust-pack check bindsexecutor.keyIdto the signing key and to theoutcomeExecutorsrole; the pack names no identifier per key, so an anchored executor key can write anyexecutor.idand the outcome verifies. NON_CLAIMS.md now says thatexecutor.idis the signer's own statement, and names the inputs of draft-gruszka-audit-decision-receipts-05 that the decision and outcome verifiers do not take: the expectedexecutor.idand the approval record of Case 1, which the draft requires, and the effect and action bytes, which it calls optional. The binding, the two required inputs and the effect bytes are scheduled for 6.6.0. No verdict changes. - The texts name the two base64 alphabets the DSSE verifiers read, and say that
passedis optional in eval-result v0.1. SPEC.md section 7b said the test-resultpayloadis standard base64 and not base64url, while the verifiers of this version read both alphabets, as the DSSE envelope allows, for SVR, test-result and eval-result alike; the text now names both, padded, and docs/IN_TOTO_PROFILE.md says the same for all three verifiers. The v0.1 claim row says that a claim withoutpassedverifies and carries no verdict, and that a consumer who needs one reads v0.2. No verdict changes. - The
[scitt]extra and the dev pins take cbor2 6.1.5, measured as the pin asks.tools/scitt_ccf_external/reader_crosscheck.jsoncarries the run cbor2-6.1.5 of 2026-10-29, made withreader_crosscheck.pyin the environment of the 6.1.4 run. Of the 70 values the run of 6.1.4 recorded, each is equal in the run of 6.1.5 but the cbor2 version, and the data-hash recomputed with the strict options equals the receipt's on 4 of 4 real statements.reader_crosscheck.pynow holds each of the five files it reads against the size and sha256 pin offetch_external.pybefore it m...
proofbundle--v0.4.0
proofbundle plugin 0.4.0
This is the first plugin-specific tag and GitHub release of proofbundle for Claude Code and Codex. It is separate from the Python package and its existing v0.4.0 tag.
The public marketplace of this repository lists one plugin, proofbundle, the verifier. It registers no hook. The Guard is the separate plugin proofbundle-guard, the owner's house profile. No public catalog lists it; the owner's machines add its own marketplace from a checkout of this repository at plugins/proofbundle-guard and install it beside the verifier. Installing proofbundle does not install or enable proofbundle-guard. The source of both plugins is public, and the release archive holds both.
Earlier 0.4.0 installations
Version 0.4.0 was already available from the public marketplace on main before this release, including an earlier form in which the plugin proofbundle carried the Guard's hooks. If you installed before this release, follow the tested Claude Code reinstall procedure and supported-host notes in the plugin README.
The version remains 0.4.0. A version display or routine marketplace refresh alone does not establish that the installed files changed. In the measured Claude Code reinstall, source identity, retained data and the absence of the old Guard hooks were checked. Users of other installations should check their own installed files and hook listing rather than infer a change from the version display. Publishing this release does not revoke earlier installed copies. The number of outside installations is not known.
Codex has not reached M1 for this release. Its unmeasured runtime and lifecycle cases are not covered by the measured Claude Code procedure, and the migration under Codex is NOT MEASURED.
Acceptance and limits
Claude Code has not reached M1 for this release, and the release is published without it. M1 is the acceptance defined in the test plan; it includes real-host operation and lifecycle checks, not just a passing test harness. The acceptance ran at commit 6d29ead on 2026-11-04, and the implementation-gap record carries it row by row. In the record's own words, "At this measurement V-CC-7 (TV-8) is FAILED, G-CC-13 (the pilot of TG-11) is NOT MEASURED, the record of used releases on the operator's machine (G-CC-16) is not measurable with V6 at 6d29ead, TG-6 was not run in a host (G-CC-7), and the gate directory of TL-3 and TL-4 and a stale hook entry of TL-4 were not checked (L-2, L-3). G-CC-3 (TG-1) has 14 different answers against the comparison head, all additional D129 blocks with none lost. The owner accepted these differences as an intended policy change on 2026-11-05; the unchanged TG-1 requirement of zero different answers is still not met. The delivery-profile TG-9 run showed a push proceeding without Guard protection, but did not emit the literal INACTIVE status required by TEST_PLAN.md. At least acceptance points 1, 2, 4 and 8 remain unmet; Claude Code has not reached M1 at this measurement." M1 is the target of 0.4.1.
At candidate commit 43544e2, the archived-file inventory differs from 6d29ead only in plugins/proofbundle/m0/IMPLEMENTATION_GAP.md; the plugin code and the marketplace files are unchanged. The final release commit receives its own archive and signature checks. The record's V-CC-2 entry retains the earlier real-host failure and the interactive run at 6d29ead in which /mcp listed the server with seven tools; the cause of the earlier failure is not known. These release notes are not themselves evidence of a host measurement.
Verification reports the pinned core verifier's result. A valid signature proves authorship under a trusted key and integrity of the signed bytes; it does not establish that recorded claims are true. An absent, disabled or untrusted Guard provides no protection.
The verifier pin is proofbundle==6.4.0 in the verifier and in the Guard. Initial startup can require the runtime and package download described in the README.
A Guard installed from its house marketplace is read from that checkout in place. It follows the checkout, not a version number, so a house machine compares its checkout with this release's commit when that correspondence matters.
House Guard PR-count behaviour
In Claude Code, the house Guard counts pull requests opened through recognised Bash gh commands per session (D110). With a valid count below eight, house rule H3 adds no ask of its own; at eight or more it does. If a session ID and plugin data directory exist but open-prs.json is absent, the current gate treats the count as zero and also drops that H3 ask. If the session ID or plugin data directory is unavailable, or the counter file is present but unreadable or invalid, H3 retains its ask. Losing or removing a counter file can therefore reset this advisory count; it is not a guarantee that a session has fewer than eight open pull requests. Other gate rules can still ask or deny. The counter does not cover every GitHub or MCP operation, and it is not a live count across sessions.
The Guard's decision receipts
Two corrections of the Guard's decision receipts are in this release, decision D135 of the plugin.
- Trace context. A Level 1 receipt records the Guard's decision on a tool call, including a Bash call or a supported MCP write. When the hook event supplies
session_idortool_use_idin the accepted form, the receipt copies them intotraceContext.traceIdortraceContext.parentId, respectively; missing or unusable IDs are identified innotChecked. The separate Level 2 git pre-push hook has no Claude session or tool-call IDs and its own receipt carries no trace. Agit pushinvoked through Bash can have a Level 1 receipt with trace context even though the pre-push receipt has none. - Merge digest. For a GitHub merge call with a specified head commit and merge method,
parametersDigestis the SHA-256 of the RFC 8785 form of the requestedgithub.mergeoperation, including the lowercased repository, pull request number, head commit and merge method, plus the commit title and message where supplied. The digest records what the call requested, not what the host actually merged. A GitHub MCP server that ignoresexpectedHeadShacan merge a different head. Without a specified head commit or merge method the receipt carries no such digest.
The key signer accepts receipts carrying traceContext only from this version on. Its program is plugins/proofbundle/pilot/key_signer.py, not part of the proofbundle-guard plugin. Updating the Guard alone does not update the copy running under the key account. An operator using that pilot must separately replace the key account's copy with the matching version, as described in plugins/proofbundle/pilot/RUNBOOK.md (step 2). Until then an owner's release that requires the signed ALLOW stays unused. Receipts written before this release verify as before.
What the release signature covers
The assets are:
- proofbundle-plugin-0.4.0.tar
- proofbundle-plugin-0.4.0.release.json
- SHA256SUMS
- proofbundle-plugin-0.4.0.release.json.sig
The archive holds LICENSE, the public marketplace file, the verifier's folder plugins/proofbundle and the Guard's folder plugins/proofbundle-guard with its house marketplace file. Every marketplace source in it resolves inside the archive.
The signature authenticates the exact release-statement bytes. The statement binds the archive's filename, size and SHA-256. SHA256SUMS is a deterministic two-line index reconstructed from the authenticated statement and its file hash; it is not independently signed.
The intended release public key, as standard base64 of 32 raw Ed25519 bytes, is:
iJipntJA8N//h+ln9CgLzeC9n/M5OdCZNeBhbfagom8=
Its raw-key SHA-256 is:
e53405faeb960e17c653fbc5eb6a862a115550efdf064f64b958a0d9bdca921b
Confirm the owner-key binding through a previously trusted copy or another authenticated channel. The key printed next to these assets is not by itself a new trust anchor. Follow the exact verification procedure in the linked README; checking SHA256SUMS alone does not verify a signature.
The release statement identifies the fixed commit and archive. The default installation commands continue to follow main, which can change. The signature does not establish which source revision or cached files a host loaded, even if they also report 0.4.0. Compare installed source identity and content with the archive when that correspondence matters.
The statement does not authenticate separately downloaded verifier distributions, host software, local configuration or GitHub's automatically generated source archives. The annotated plugin tag itself is unsigned; the detached signature is over the release statement.
If you try the verifier plugin with Claude Code, I'd be glad to hear what works and what doesn't.
Assisted by little helpers.
v6.4.0
A feature release following 6.3.1, with an experimental SCITT reader, a TRACE verifier and a stricter JSON reader. It adds proofbundle.scitt_ccf, an experimental reader for SCITT Transparent Statements with CCF receipts under the narrow profile scitt-ccf/v1, and proofbundle verify-trace for TRACE v0.2 Trust Records. The strict JSON reader now refuses non-finite numbers, integer literals outside the inclusive range -(2^53 - 1) to 2^53 - 1, and JSON bytes with a UTF-8 byte order mark or encoded as UTF-16 or UTF-32. Review the inputs your code hands a verifier when upgrading.
python -m pip install --upgrade proofbundle==6.4.0
Highlights
- An experimental reader for SCITT Transparent Statements with CCF receipts.
proofbundle.scitt_ccfreads statements under the narrow profilescitt-ccf/v1, which follows draft -06 of the CCF profile, and needs the[scitt]extra. It is reached only by calling it; no verify path of the package reaches it. The Rust cross verifierpb_verify_rs, which is not part of the Python package, gives the same results for statement signatures, Transparent Statements and consistency receipts over shared vectors. proofbundle verify-traceverifies TRACE v0.2 Trust Records. It checks a record against keys, a time window and expectations that the relying party supplies, in the compact JWS form and in the embedded Ed25519 form. A pass is evidence for the relying party's policy, andsafeForAutomationis false in every verdict.- The strict JSON reader rejects non-finite numbers and applies explicit integer and encoding limits.
loads_strictrefusesNaN,Infinity,-Infinityand every number that becomes infinite, integer literals outside the inclusive range -(2^53 - 1) to 2^53 - 1, and JSON bytes with a UTF-8 byte order mark or in UTF-16 or UTF-32, withBundleFormatError. With ansd_jwt_vcwhose issuer signature verifies, a signed JSON payload refused for a duplicate member or one of these limits now demands and failssd-jwt-bundle-binding. A payload that is not JSON at all remains outside the scope of that binding. Review code that hands a verifier such input. - The release run compares its files with the signed candidate. Before any upload, the tag run compares its sdist and wheel with the pair signed in the candidate block of the short soak and of the Rust differential, and stops when the bytes differ. The build tools are selected at fixed versions through
.github/build-constraints.txt; the constraints name versions, not archive hashes.
Verify this release yourself
Use the checksums and build provenance to check the downloaded files. To check the signed pre-tag audit receipt, use a clone at the source commit identified by the build attestation. The commands, prerequisites and limits are in Verifying a published release.
What a receipt still does not prove
A valid signature binds the signed content to the signing key. It does not make a reported result true.
Measured on the reference machine
The budget cost axis was measured on the reference machine on 2026-10-27 using the code at e29a268. The record identifies the run as a reference measurement (ist_referenzmessung=true). All 12 expected axes and all 7 expected combinations passed, and no axis was skipped. The recorded calibration factor maschinenfaktor_schnellstes_ende is 1.0, and the timing-limit setting is latte_aus_der_klammer=schnellstes_ende. These results apply to the listed axes and combinations, not to every reader or input. The measurement record lists every axis and combination.
Details
All 30 entries, one line each, as in the CHANGELOG
Added
proofbundle.scitt_ccfreads a SCITT Transparent Statement with CCF receipts under the narrow profilescitt-ccf/v1of ADR 0009 (PR278, pull request 406). It is experimental and needs the[scitt]extra (cbor2==6.1.4); without it every entry point refuses withno_lib, and nothing falls back to a weaker reader. Its own structural pre-scan,proofbundle._cbor_prescan, decides before cbor2 sees a byte: definite lengths, shortest heads, no floats, unique map keys, tag 18 only at the top and tag 1 only around an integer CWT time claim; cbor2, held inproofbundle._scitt_second_reader, must then read the same values. The three verifiersverify_statement_signature,verify_transparent_statementandverify_consistency_receiptare reachable only by calling them: the anchor type is not registered, and no verify path reaches it. The statement key is selected by the protectedx5chainand never trusted from it, a key is built only by its own type, and consistency receipts have a closed status set of their own. A Receipt meets the CWT Claims rule of a Signed Statement, a text iss and sub in the protected header (RFC 9943 section 6), and a label whose value is null is present, not absent.tools/scitt_ccf_external/holds the measuring tools and their recorded runs: the offline recomputation of third-party receipts, the comparison with microsoft/scitt-verifier, the measurement of section 4 for the working group inSECTION4_WGLC.md, and two differential corpus rounds registered on a local scitt-ccf-ledger.pb_verify_rs verify-scitt-statement-signaturegives the status and verdict ofproofbundle.scitt_ccf.verify_statement_signature(PR290, pull request 408). It exits 0 forconfirmed, 1 forstatement_signature_invalidand 3 for a status that is no verdict about the signature, and a file over its input budget ismalformed, exit 3, as Python reads the same bytes.src/scitt.rsshares no reading code with the Python module: its own CBOR reader, the COSE_Sign1 shape and the statement header types of the CDDL pass, and ES256, ES384, PS256 and PS384 through the RustCrypto cratesp256,p384andrsa, with a signature s >= n refused before thersacrate would reduce it. The crate carries RUSTSEC-2023-0071, a timing leak of a private key; the verifier links only its public-key verification. The 91 vectors oftests/fixtures/scitt_statement_signature/vectors.json, written bytools/scitt_ccf_external/statement_signature_vectors.pyand real statements of the two corpus rounds among them, hold both verifiers to the built verdict intests/test_scitt_statement_signature_parity.pyandcrosscheck.py, and the parity register row is COVERED.pb_verify_rs verify-scitt-transparent-statementgives the result ofproofbundle.scitt_ccf.verify_transparent_statement(PR292, pull request 409). It prints one JSON object with the fields of itsto_dict()but the prose, and exits 0 forconfirmed, 1 for a status that says a check over the evidence failed and 3 for a status that is no verdict about it; the relying party's trust is a JSON file withscitt_statement_keysandscitt_ccf_servicesby issuer.src/scitt_transparent.rsshares no code with the Python module: it runs the CDDL pass of each receipt and of every proof family, computes the roots, holds each receipt to the rules of the profile and verifies its signature over the root. The vectors oftests/fixtures/scitt_transparent_statement/vectors.json, written bytools/scitt_ccf_external/transparent_statement_vectors.py, hold both verifiers to the built verdict, the Transparent Statements a local scitt-ccf-ledger served in the two corpus rounds among them, and the parity register row is COVERED.pb_verify_rs verify-scitt-consistency-receiptgives the result ofproofbundle.scitt_ccf.verify_consistency_receipt(PR297, pull request 410). It prints one JSON object with the fields of itsto_dict()butdetail, and exits 0 forconfirmed, 1 for a status that says a check over the evidence failed and 3 for a status that is no verdict about it.src/scitt_consistency.rsshares no code with the Python module and runs section 4 in the order ofCONSISTENCY_STATUS_ORDER, the receipt signature over the newer root under the relying party's service keys by issuer and kid. The vectors oftests/fixtures/scitt_consistency_receipt/vectors.json, written bytools/scitt_ccf_external/consistency_receipt_vectors.py, hold both verifiers to the built verdict, vectors over three signed states of a local scitt-ccf-ledger among them, where the service's own signature over the newer root stands with a proof computed from the ledger's leaves, and the parity register row is COVERED.- Section 4 consistency receipts get fifteen vectors, an independent checker and a Go reader (PR355, pull request 411). The consistency reader qualifies a success without both tree sizes as
confirmed_without_tree_sizes, andpb_verify_rs verify-scitt-consistency-receiptgives that status, exit 0, witholder_size,newer_sizeandnewer_size_sourcenull, as the Python call without sizes gives them: no size comes from the receipt, and so none from itsccf.v1txid (-06 section 7.3).tools/scitt_ccf_external/section4_vectors/holds the receipt-level vectors S4-01 to S4-15 with their generator, a checker that imports nothing from proofbundle and a manifest; they record two readings of section 4 and leave to the working group which one the draft means. The directory carries one key file,TEST_ONLY_es384_private_key.pem, an ES384 key made for these vectors alone and published on purpose, the key of no service, release or person.tools/scitt_ccf_external/section4_reader_go/is a Go reader of section 4 written from the draft text. - A decision proof for the Rust verifier
pb_verify_rs, and two workflows that run it.formal/z381_pruefentscheidungproves over the domains D1 to D6 thatverify-bundlegives every input exactly one verdict of the cl...
v6.3.1
A patch release following 6.3.0, with stricter verification and changed result reporting. Statement validation is reported separately from DSSE signature checks, and reference-check results and executed-outcome evidence levels change as described below. The release also improves handling of specific invalid inputs, extends the inspect_ai adapter and updates repository tools. Review the changed fields and remaining exception paths when upgrading.
python -m pip install --upgrade proofbundle==6.3.1
Highlights
- Statement validation is separate from DSSE signature verification. The eval-result, in-toto and SVR verifiers require the in-toto Statement v1 layer and report
statement_okseparately fromsignature_ok. These and the decision, outcome, relation statement, verification summary, run ledger and trust pack verifiers require subjects that identify artifacts by digest. A successful DSSE signature check alone does not establish that the Statement passes validation. - Reference reporting changes for callers upgrading from 6.3.0.
automation.referencesResolvedisNonewhen no reference was checked;safeForAutomationandautomationBlockersare unchanged. Executed-outcome evidence levels useREFERENCE_WELL_FORMEDfor a well-formed digest reference, orCONTENT_RESOLVEDwhen the evidence resolver confirms it, instead of always reportingCLAIMED.action_outcome_provenandokare unchanged. Review code that depends on these fields. - Stricter validation and more specific errors for the corrected cases. The decision validator rejects JSON null in required fields that do not allow it. The validators named below enforce the corrected digit restrictions and closed
sha256Digestobjects. The corrected error paths return reason codes, blocking verdicts or module-specific errors. Eight public functions remain open for the formatting cases described below, and the twocanonicalprimitives still propagate canonicalization errors. - The inspect extra admits inspect_ai up to 0.3.281. Version 0.3.281 is the latest version measured in a fresh environment. The adapter includes sample counts and early-stopping metadata when supplied by the log, allowing a reported early stop to be distinguished from a completed run. The reported
nis unchanged.
Verify this release yourself
Use the checksums and build provenance to check the downloaded files. To check the signed pre-tag audit receipt, use a clone at the source commit identified by the build attestation. The commands, prerequisites and limits are in Verifying a published release.
What a receipt still does not prove
A valid signature binds the signed content to the signing key. It does not make a reported result true.
Measured on the reference machine
The budget cost axis was measured on the reference machine on 2026-10-21. All 12 axes and all 7 combinations passed, and none was skipped. The calibration factor maschinenfaktor_schnellstes_ende is 1.0, the ratio of the fastest recorded calibration time in this run to the median of the earlier reference recording. The timing limits used the fastest-sample setting, recorded as latte_aus_der_klammer=schnellstes_ende. The measurement record lists every axis and combination.
Details
All 30 entries, one line each, as in the CHANGELOG
Added
- Add ten conformance vectors of the kind
content_root_vectorunderconformance/action_chain_content_roots/. They pin the content root of ADR 0002 as data, andCONTENT_ROOT_CONTRACT.mdstates the contract. The Rust verifierpb_verify_rsrecomputes the eight pinned roots through itscontent-rootsubcommand. - Add
tools/scitt_ccf_external/pr31_strict_reader, a strict reader of a CCF inclusion receipt written to the text of pull request 31 to the CCF receipt profile, with 24 probes and 42 vectors. - Document in
THREAT_MODEL.mdthat a caller's own Python objects passed to the API are code in the same process, outside the verification boundary, and whereRESTRISIKO_620.mdlists the sites where such an object makes a never-raise surface raise.
Changed
automation.referencesResolvedisNone, no longerTrue, when every reference field it reads isNoneor absent, because no reference check ran.safeForAutomationandautomationBlockersdo not change.anchors.receipt_canonical_roottakes its RFC 8785 bytes from the package's one canonicalizer. A value of a subclass ofintorfloat, anIntEnumamong them, is refused withBundleFormatError; each of the 689 JSON objects tracked in the repository keeps its root.- The
inspectextra admitsinspect_aiup to 0.3.281, the last version measured in a fresh environment. - The limit of one run of the mutation gate follows the measured baseline of its selection, 1.5 times the baseline and never less than 3600 s. A run past its limit stays not measurable and counts as a gap.
Fixed
verify_eval_result_dsse,verify_intoto_dsseandverify_svr_dsse, and with themproofbundle intoto --verifyandproofbundle svr --verify, no longer verify a signed statement without the in-toto Statement v1 layer._typemust behttps://in-toto.io/Statement/v1, and every subject entry must carry a digest. The result reports this asstatement_okand the DSSE check alone assignature_ok. Statements written by this package's exporters keep their verdict.- The decision, outcome, relation statement, verification summary, run ledger and trust pack verifiers, and the matching commands of the Rust verifier, no longer accept a signed statement whose subject names no artifact by digest. Their emitters and
emit_agent_reviewraise their own error for a subject override they would not verify, such as asubject_sha256in capitals. The conformance caserelation/target-subject-missingexpectsRELATION_TARGET_MALFORMED. - The decision validator now rejects JSON null in required fields that do not allow null under
schemas/decision-receipt-v0.1.schema.json;decision verify --strictcould previously reportsafeForAutomation=truefor such a receipt. AnotCheckedentry written as a bare string remains accepted as a deprecated form. - The decision, outcome, run ledger, verification summary and trust pack validators correct the affected pattern checks to use ASCII digit classes and reject additional members in
sha256Digestobjects, matching the corresponding schema constraints.verify_trust_packno longer raisesTypeErrorfor a key whosealgis a list. - agent-review v0.1, v0.2 and v0.3 restrict digits in timestamps to ASCII, as required by RFC 3339. Their
schemaVersionchecks also use ASCII digits. By maintainer decision these changes apply to all three existing predicate versions rather than introducing a new version; the receipts and vectors in the repository retain their verdicts. - The eval-result v0.2 checks read the digits of
evaluatedAtas ASCII. verify_decision_receiptreads the evidence level ofactionOutcome.outcomeReffrom the digest inside the reference. A well-formed digest readsREFERENCE_WELL_FORMED, orCONTENT_RESOLVEDwhen the evidence resolver confirms it, where 6.3.0 read every executed outcome asCLAIMED.action_outcome_provenandokdo not change.- The inspect_ai adapter tells a run stopped early from a complete one with the same counts. The signed provenance carries
total_samples,completed_samplesand, from inspect_ai 0.3.266,logged_samples, each only when the log sets it, andearly_stopping_managerandearly_stopped_samples.nis unchanged. - The agent-review verifiers answer a correctly signed receipt that carries a value of the wrong type, a number RFC 8785 cannot represent or a lone surrogate with a reason code or a verdict that blocks, instead of
internal_error. The new reason codes areSTATEMENT_NOT_CANONICALIZABLEandPREDICATE_NOT_OBJECT.emit_agent_reviewraisesAgentReviewErrorfor such a value. - The modules that canonicalize a statement through the package's canonicalizer map its refusal, and the refusal of the structural budget in front of it, to their own typed error, instead of letting a bare
ValueError,BundleFormatErrororBudgetExceededout. The two primitives ofcanonicalpass the refusal on, as documented. - The corrected public entry points handle failures while formatting values for messages, subject names or serialization, including large integers, deeply nested lists and objects whose
__repr__raises. This does not establish a never-raise guarantee for every public API. Eight public functions inintoto,_verdict,sdjwt_issueandevalclaimremain open for these cases and are tracked in the residual-risk record. verify_decision_receiptandverify_outcome_receiptno longer raiseUnboundLocalErrorfor a signed statement whose predicate is not an object under a policy with arelationssection.experimental.attested_inference.binding_presentanswersFalsefor signed material without a JSON form.sdjwt.issuer_key_fingerprintno longer raises for astrsubclass whose hash raises, andagent_review.validate_time_claimanswers anassurancethat cannot be hashed with the error every wrong assurance gets, instead ofTypeError.verify_sdjwt_vcandverify_bundleno longer accept a presentation in which two committed disclosures give the same claim different values. A claim name stands once in its SD-JWT object.- A test-result statement of the verifier block names at least one case. One with all three case lists missing no longer validates, and
join_test_resultno longer reports it asPASSED. - A command-line mode refuses th...
v6.3.0
A feature release following 6.2.1. The installed package adds opt-in eval-result v0.2 export and verification, changes the default DSSE key ID handling, and fixes two pytest receipt behaviours. The repository also adds SCITT statement identification material, a pilot profile and contract, and an incremental Merkle accumulator.
python -m pip install --upgrade proofbundle==6.3.0
Highlights
- DSSE key IDs are included by default when available. Envelopes created by
dsse.sign_envelope, including in-toto exports, carry the signer's OpenSSH SHA256 fingerprint as an unsignedkeyidby default when the signer exposes its Ed25519 public key. Usekeyid=""to omit it; signers without an exposed Ed25519 public key omit it unless supplied explicitly. - eval-result v0.2 for the revised in-toto draft. An opt-in export and verification under its own predicate type; exports still default to v0.1, and
--verifyaccepts both. - Statement identification material for SCITT. The repository includes requirements and a verification package in
docs/scitt/statement_identification/. - Repository pilot material and an incremental accumulator. A profile and vectors for the shipped decision and outcome predicates, the first pilot contract, and an incremental Merkle accumulator with a restart rule are provided under
docs/andtools/.
Verify this release yourself
Use the checksums and build provenance to check the downloaded files. To check the signed pre-tag audit receipt, use a clone at the source commit identified by the build attestation. The commands, prerequisites and limits are in Verifying a published release.
What a receipt still does not prove
A valid signature binds the signed content to the signing key. It does not make a reported result true.
Measured on the reference machine
The budget cost axis was measured on the reference machine on 2026-10-13. All 12 axes and all 7 combinations passed, and none was skipped. The calibration factor maschinenfaktor_schnellstes_ende is 1.0581, the ratio of the fastest recorded calibration time in this run to the median of the earlier reference recording. The timing limits used the fastest-sample setting, recorded as latte_aus_der_klammer=schnellstes_ende. The measurement record lists every axis and combination.
Details
All 11 entries, one line each, as in the CHANGELOG
Added
- Add opt-in eval-result v0.2 export and verification under
https://b7n0de.com/attestation/eval-result/v0.2for the revised in-toto draft. Export withproofbundle intoto --predicate-version v0.2 --evaluator <URI>. v0.2 requires anevaluator, identifies each model and dataset by exactly one of a salted commitment or a digest-bearing ResourceDescriptor, and records artifact digests inevidence[]. Receipt evidence uses the SHA-256 of the receipt file's exact bytes. Exports still default to v0.1;--verifyaccepts both versions. Seedocs/IN_TOTO_PROFILE.mdfor mappings and migration details. - An independent reading of draft-abak-agent-control-delivery-evidence-01. Adds
interop/acde_01, a verifier-side implementation derived from our reading of the text of -01 alone, with 130 requirement sentences, 146 vectors and a run record with agreement 108, contradiction 0, ambiguity 14 and not implemented 8. Nothing outsideinterop/acde_01changes. - Add SCITT statement identification requirements and a package verifiable against them.
- Add a pilot profile and vectors for the shipped decision and outcome predicates.
- Document which capabilities ship in 6.1.0 and which are available only on the main branch at the documented comparison point.
- Add an incremental Merkle accumulator alongside the bundle emitter, with a restart rule and before-and-after run records.
- Add the first pilot contract for comparing approved agent actions with GitHub evidence.
Changed
- DSSE envelopes created by
dsse.sign_envelope, including in-toto exports, now include the signer's OpenSSH SHA256 fingerprint askeyidby default. Usekeyid=""to omit it; signers without an exposed Ed25519 public key omit it unless supplied explicitly. The key ID is unsigned. The pinned-key DSSE and in-toto verifiers, includingpb_verify_rs verify-dsse, do not use it to select a key; the trust pack retains its key-selection rules. Archived receipts and regression fixtures may still omit it and be rejected by consumers that require it. Seedocs/IN_TOTO_PROFILE.mdfor interoperability notes. - Pull-request label changes no longer restart the main CI workflow. The
landunglabel starts mutation checks in a separate workflow; new commits rerun them while the label is present, and removing the label cancels them.
Fixed
- The pytest plugin now skips receipt generation and reports why when
PROOFBUNDLE_METRICis set to a value other thanpass_rate, preventing pass-rate values from being labelled as another metric. Unset orpass_ratecontinues to select the pass-rate metric. - The pytest plugin now decides
passedfrom the exact counts of passed and run tests instead of from the pass rate rounded to six decimal places. With the>=comparator, two passes out of three no longer pass a threshold of0.666667.
Full changelog · Known limitations for 6.3.0 · Earlier risk record · Release scope · proofbundle.dev
Created with AI assistance. Reviewed and published by me.
v6.2.1
A security update for everyone on 6.2.0. It tightens checks on policy validity, timestamps, key algorithms and log inclusion proofs, and rejects ambiguous input on additional paths.
python -m pip install --upgrade proofbundle==6.2.1
Highlights
- Policy checks use one time for both validity limits. Decision-policy lifetime checks keep fractions of a second, and claim-age checks no longer truncate the calculated age to whole seconds.
- One signature method cannot stand in for another. An old root key cannot approve a rotation using an unsupported algorithm, and an Ed25519 outcome signature alone cannot meet a hybrid-key requirement. Empty log-key or origin lists reject the respective trust check.
- A proof counts only where it was checked. Trust in a transparency log inclusion applies only to the inclusion context the verifier checked, including its position, tree size, proof path and root.
- Duplicate fields and unsupported requirements are rejected. Agent-review policy files and Chia node replies with duplicate JSON keys are rejected. The credential profile check also rejects unsupported or malformed critical-extension fields.
Verify this release yourself
Use the checksums and build provenance to check the downloaded files, and check the signed pre-tag audit receipt from a clone. The commands and their limits are in Verifying a published release.
What a receipt still does not prove
A valid signature binds the signed content to the signing key. It does not make a reported result true.
Details
All 15 fixes, one line each, as in the CHANGELOG
- Repeated field names are rejected in review policies.
agent_review.load_policyrefuses a policy file that carries the same JSON key twice (AgentReviewError) instead of reading the last value. - Replies from Chia with repeated field names are rejected. The Chia RPC reader in
anchors_chia_addrefuses a node answer that carries the same JSON key twice (ChiaRpcError) instead of reading the last value. - Credential checks reject unsupported requirements.
sdjwt_vc.check_vc_profilerefuses an issuer JWT header with an unsupported or malformedcritfield (RFC 7515 §4.1.11), including when the issuer signature is not required. - A policy is checked at the same time as the receipt, including fractions of a second.
verify_decision_receiptjudges a decision policy's lifetime at the receipt's evaluation instant with its fraction of a second, not at that instant cut to the whole second. - These verification commands require whole seconds.
--verification-timeofdecision verifyandverify-enclaverefuses a time whose fractional seconds are not all zero, however many digits are written. - These commands label results at a supplied time as HISTORICAL. With
--verification-time,decision verifylabels verification results HISTORICAL even without--policy, andverify-enclavelabels its JSON and text results HISTORICAL. - One clock reading judges both ends of a policy's validity. A policy lifecycle evaluation without an explicit instant reads the wall clock once and judges both ends of the policy's validity window at that one instant.
- Policy time checks do not silently replace a supplied time with the current time. For their time comparisons,
policy_expired,policy_not_yet_validand the trusted-checkpoint check ofevaluate_policyno longer replace a malformed non-Nonenowwith the wall clock;Noneretains the default clock behaviour, and naive datetimes are treated as UTC. - An enclave check rejects an invalid supplied time.
verify_enclave_attestationrefuses an evaluation timenowother thanNoneunless its type is exactlyint. - Fractions of a second count when checking a claim's age.
check_freshnesscompares parsed timestamps without truncating their age to whole seconds; withmax_age_secondsset, a negative age or an age above the bound is not fresh. - The time is checked before it reaches the proof verifier. Before dispatching an anchor verifier,
verify_anchorandverify_anchorsreject a suppliednowother thanNoneunless its type is exactlyint. - A log entry must match the proof that was checked.
evaluate_policytreats a trusted checkpoint, the tree context and the root as authenticated only when the bundle states the same inclusion context (hash algorithm, leaf index, tree size, audit path and root) thatverify_bundleverified for it. - An old key cannot approve its replacement using an unsupported signing method.
verify_trust_packno longer treats an explicit unsupported or invalidalgon an old-root pin as Ed25519; an absentalgand the legacy bare-key form still mean Ed25519. - When two signature methods are required, one alone is not enough.
pack_key_binds_signerbinds an Ed25519 outcome signature only to an Ed25519 pack key; a hybrid or ML-DSA key never binds it, so a role declared hybrid is not met by the classical half alone. - An empty list of permitted log keys or sources grants no permission.
evaluate_public_transparencytreats a presenttrustedLogKeyslist as an allowlist whenrequireSignedCheckpointis enabled, and a presenttrustedLogOriginslist as an allowlist; an empty list accepts no key or origin in the respective check.
Full changelog · Known limitations · Release scope · proofbundle.dev
Created with AI assistance. Reviewed and published by me.
v6.2.0
Stricter input checks at verification boundaries, hardened Ed25519 trust-anchor handling, and offline AGT receipt verification. Beta. Locations of the closing records are listed under Audit status.
Changelog · Known limitations · Release scope
Highlights
- Agent Governance Toolkit receipts verify offline, without AGT installed and without network access.
- Low-order and non-canonical Ed25519 keys are refused wherever the verifier relies on a key.
- The Rust and Python verifiers refuse the same inputs in more places than in 6.1.0.
If you use 6.0.0 or 6.1.0, please upgrade. 6.2.0 also contains security fixes for those releases.
pip install proofbundle==6.2.0
Findings addressed in 6.2.0
6.2.0 fixes the issues described below, including findings in the released 6.0.0 and 6.1.0 and a pre-release regression in pull request 313. The rows summarize affected surfaces, effects, fixes and measurement baselines. Fixes are linked to their public pull requests, including 311, 312 and 313. The last five rows describe additional classes addressed in pull request 311 and state where each was measured.
| Finding | Affected | Effect | Fixed by |
|---|---|---|---|
| Truthy non-boolean callback results promoted verification evidence | 6.0.0, 6.1.0; Python API resolver and registered-anchor-verifier paths | For example, an evidence resolver returning "false" lifted a digest from REFERENCE_WELL_FORMED to CONTENT_RESOLVED |
Boolean success decisions now require exact True; documented receiver-key results remain supported (#293, which carries #291) |
| A low-order Ed25519 key as a trusted key | 6.0.0, 6.1.0; verify_ed25519, dsse.verify_envelope |
With the identity point supplied as the key, R = identity, S = 0 verifies without a private key |
Trust-anchor paths now reject weak keys, including dsse.verify_envelope; bare verify_ed25519 and the bundle's in-band key retain the §4a profile (#280, #293) |
| A low-order Ed25519 key as the holder key of an SD-JWT key binding | 6.0.0, 6.1.0; CLI included | an SD-JWT bound to the identity point and a Key Binding JWT signed by nobody (R = identity, S = 0) gave "key binding valid" | 6.2.0: issue_sd_jwt raises ValueError, its documented refusal for a bad holder key, and the verifier refuses the presentation (#280, #293) |
| A related map that says it is empty hid an attached retraction | 6.0.0, 6.1.0; Python API | With reject_superseded enabled, a dict subclass reporting length 0 hid a verified attached retraction. verify_decision_receipt and verify_outcome_receipt returned ok=True; the same entries in a plain dict returned ok=False |
6.2.0 reads the map by what it stores (#300) |
An edge's declaredAt accepted non-ASCII decimal digits |
6.0.0, 6.1.0 in validate_relationships; signed CLI comparison measured on main 86671552 |
On that main head, the package emitted such a signed edge; decision verify returned exit 0 with ok=True, while pb_verify_rs verify-relation refused the same bytes with exit 2 |
The edge's declaredAt now accepts ASCII digits only; both verifiers refuse the tested non-ASCII cases (#300) |
| Eight findings involved caller-controlled inputs | 6.0.0, 6.1.0; Python API | For example, verify_decision_receipt reported signer_trusted, ok and safeForAutomation True for a receipt signed by an untrusted key |
6.2.0 uses a fixed reading of the affected inputs, or refuses their types (#312) |
| Wrong-typed policy fields, callback mutation and malformed containers affected verification | 6.0.0, 6.1.0 for these cases; Python API, plus malformed falsy --anchors input on the CLI |
Python API example: a wrong-typed trusted_decision_makers let an untrusted signer pass. On the CLI, malformed falsy anchors were read as absent |
6.2.0 shares policy-field validation, rejects the affected malformed containers, and snapshots affected inputs before callbacks (#313) |
| An attached target's subject state outside the four words of its resolver was read as present | 6.0.0, 6.1.0; Python API | A target labelled AMBIGUOUS or multiple bound a declared targetSubjectDigest to its first subject, and verify_decision_receipt, verify_outcome_receipt and verify_relation_statement returned lineage VERIFIED and ok=True |
When binding a declared targetSubjectDigest, states other than None must be present, absent, ambiguous or malformed; other values fail on direct edges and attached hops. Missing or None states remain inferred from the digest (#311) |
| A restricting CLI option given an empty value was read as absent | 6.0.0, 6.1.0; CLI | Nine command/option combinations, including verify --policy '', verify --anchor-type '' and decision verify --anchors '', exited 0 when their empty values were ignored |
These options are read with is not None; empty paths and an empty nonce are refused with exit 2, while verify --anchor-type '' exits 3 (#311) |
| A verifier read a caller's related map twice, and an anchors file holding null read as no option | 6.0.0, 6.1.0; Python API for the related map, CLI for --anchors |
Under a policy that refuses both the full and the empty map, a gc callback of the caller that emptied its map between the two readings let verify_decision_receipt and verify_outcome_receipt return ok=True. decision verify --anchors FILE with the content null or [] exited 0 like no --anchors |
The verifiers read the map once, and every public function now reads all of its arguments in one reading at its call; such an anchors file is refused with exit 2, and so is a policy file with nothing in it the command evaluates (#311) |
| A policy rule the command does not apply was dropped in silence | 6.0.0, 6.1.0; CLI and Python API, outcome verify and decision verify |
Under a policy whose only rule was reject_retracted, which only relation-statement verify applies, outcome verify printed POLICY: OK over an attached, verified retraction of its receipt, and decision verify ended like a verify without the policy; the same held beside a rule the command applies |
Every rule a policy sets is applied by the command it is given to, or the policy is refused with exit 2 (policy_ok False in the library); validity, purpose and the raw-template flag apply at every receipt command (#311) |
evaluate_policy did not apply a policy's sd_jwt.expected_aud |
6.0.0, 6.1.0; Python API evaluate_policy (the CLI binds the audience itself) |
A caller who verified with verify_bundle(bundle) and handed the policy to evaluate_policy got policy_ok True for a KB-JWT bound to another audience than the policy's expected_aud |
evaluate_policy applies sd_jwt.expected_aud from a verified key binding, and a test checks that every rule a check path lists as applied turns its verdict (#311) |
sd_jwt.expected_vct, the key binding rules and verify trusted values under an issuer key the policy never pinned |
6.0.0, 6.1.0; CLI verify and verify --policy, Python API verify_bundle and evaluate_policy |
The issuer key of an SD-JWT comes from sd_jwt_vc.issuer_public_key_b64, outside the bundle's signed payload, and the rules asked only whether the issuer signature or the key binding verified under that key |
expected_vct, expected_aud, require_nonce and require_key_binding_when_cnf_present pass only when the verifying key matches the new, algorithm-bound sd_jwt.issuer_key_pin or the SD-JWT is bound to the signed eval claim, and fail otherwise; verify_bundle and verify report a Key Binding JWT positive only under the same anchor (check sd-jwt-issuer-trust) (#311) |
anchor verify-pack did not bind the timestamp to a target |
6.0.0, 6.1.0; CLI | The command checked the proof against the pack's own canonicalRoot and read no target, so a valid proof of another root could confirm |
verify-pack requires exactly one of --target-file or --expected-root and refuses a pack whose root differs before the proof is read, exit 1; without a target it exits 2 (#311) |
| A trust pack conferred role trust without an anchor of the relying party | 6.0.0, 6.1.0; Python API verify_outcome_receipt |
A v2 trust-pack predicate passed as trust_pack without any anchor of the relying party made executor_role_trusted True |
Role trust from a trust pack needs a relying-party anchor bound to its content and its full key identity, and the receiver role is never positive from a resolver answer alone (#311) |
| A judge adopted a verification result for other data than that result verified | Python API evaluate_policy, evaluate_decision_policy, evaluate_relations_policy, `svr_p... |
v6.1.0
Verifier build identity, CAP-1 coverage rules and stricter claim validation. Beta. Closing audit not run.
Changelog · Known limitations · Release scope
What changed
| Area | Change | Evidence |
|---|---|---|
| Verifier identity | agent-review/v0.3 can include a build digest, vector set digest and test result reference. The block is self-declared and does not change the verification verdict. | #224 · Detail |
| Coverage checks | CAP-1 rules and 15 conformance vectors are included. Partial or skipped conformance runs are distinguished from fully passed runs. | #209 · #214 · Detail |
| Claim validation | Malformed claim values are refused. A string such as passed: "false" is no longer treated as a true verdict by the affected exporters. | #231 · Detail |
Before upgrading
- Receipt versions. The default emitted format is unchanged from 6.0.0. Use a compatible reader for agent-review/v0.3. A 6.0.0 reader refuses a v0.2 receipt carrying the new verifier field. Details.
- Stricter input handling. Previously accepted malformed claims can now be refused. Check callers that relied on implicit type coercion. Details.
- Separate Action release. The Action input fix is in this source tree. That does not update the documented [email protected] tag. Its version and extras inputs retain the documented restriction on untrusted values. Details.
Audit status and known limitations
The closing adversarial round was not run because the required model family floor was not met. C6.2, C6.3 and C8.2 remain red. The full 24 hour soak was not included at tag time. The v2 findings register is unsigned. A separate signed pre-tag receipt does not sign that register.
Audit record · Residual risks · README status
The published package and a passed closing audit are separate facts.
All changes
48 pull requests, grouped by area. Shortened descriptions link to the original discussions.
Verifier and receipt formats · 3 pull requests
Build, CI and test infrastructure · 19 pull requests
- Reject package builds that would include key material. #200.
- Fix shell interpolation of Action inputs in this source tree. #235.
- Revise CI queue handling at four points. #202.
- Correct CI change records and time budget figures. #203.
- Handle queue entries that produce no required check. #204.
- Run the complete set of budget assertions. #205.
- Refresh the conformance ratchet baseline. #206.
- Bind the baseline case count to tests. #208.
- Test the ADR 0008 rule as a property. #210.
- Fix pinned Rust formatting and clippy checks. #211.
- Name required checks that no workflow can produce. #213.
- Distinguish skipped checks from executed checks. #214.
- Bind marked PR titles to a release scope entry. #215.
- Evaluate check reachability on the live pull request. #219.
- Run the full test matrix on repository pull requests. #220.
- Add a required check collector that always reports. #222.
- Declare both required collector contexts. #225.
- Check whether required contexts exist on the current head. #230.
- Run the English text gate against the requested tree. #234.
Audit and evidence · 12 pull requests
- Add findings register object classes and evidence binding tests. #198.
- Document register extraction rules for Migration 1A. #218.
- Report PASS, FAIL and NOT_MEASURED separately. #221.
- Assign identifiers to three residual risk entries. #228.
- Derive three published figures from the tree. #232.
- Record the agent review receipt for PR 236. #237.
- Add a carrier for a promised register entry. #238.
- Run the pre-tag audit between two clean tree measurements. #239.
- Record seven signed review reply receipts. #240.
- Document readiness and the closing audit that was not run. #241.
- Make the register test assert its specific claim. #243.
- Record owner-signed pre-tag receipt and readiness evidence. #244.
Documentation and interoperability · 11 pull requests
- Remeasure five Cedulon mapping cells. #188.
- Document the Cedulon refusal fixture and its implications. #189.
- Document the release scope and research programme. #197.
- Consolidate the contributor identity mapping. #201.
- Update the SCITT mapping to architecture draft 05. #207.
- Correct four CPB draft claims against their evidence. #212.
- Record two Merkle roots from two document interpretations. #226.
- Update the research coverage record after CAP-1 landed. #227.
- Document the shipped Merkle interpretation with vectors. #229.
- Limit 6.1.0 to the cut and defer the remaining scope to 6.2.0. #233.
- Remove duplicated and outdated README release notes. #236.
Dependencies · 3 pull requests
Contributors
Thanks to @b7n0de and @dependabot.
v6.0.0
proofbundle 6.0.0 is the verifier release whose emitter produces bundle format v0.2.
The full release notes are the section [6.0.0] of CHANGELOG.md at this tag, including "Known issues at the tag" with the register rows S102 to S120 and the Rust cross-verifier marked experimental and advisory.
Tag v6.0.0 points at 4e32e83, the documentation head c82a5a3 plus the commit carrying the signed pre-tag audit receipt audit_artifacts/600/pre_tag_receipt_v6.0.0.json.
The assets of this release are the wheel and the sdist built once in this workflow, SHA256SUMS over exactly these files, and the SLSA build provenance next to them.
A local rebuild of the tagged commit with the same source date epoch produced byte-identical files, wheel sha256 3c206fcff592833a75d712ed421e4b9f6aaf7d1fa857b2fc0ba50839d3dfe14d and sdist sha256 c24f91e5f137783de500f1e1269b66e77f64dcbae9c125ef3b07d94e850b7ecb.
Prepared with AI agent involvement, reviewed and submitted under human oversight.
v5.1.0.post1
Full Changelog: v5.1.0...v5.1.0.post1