From bf6acaa1b6813adc02f9aca613b64bd013b297e5 Mon Sep 17 00:00:00 2001 From: luckyPipewrench Date: Mon, 12 Oct 2026 17:56:53 -0400 Subject: [PATCH 1/3] release: prepare v0.4.1 --- CHANGELOG.md | 14 ++++++++++++++ pipelock_verify/__init__.py | 2 +- pyproject.toml | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aeeb545..5d5c9be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.4.1] - 2026-10-12 + +### Fixed + +- **Receipts from Pipelock parallel receipt chains now verify.** `verify()` and + `verify_chain()` accept the optional `group_binding` object that Pipelock signs + into `session_open` when `flight_recorder.receipt_chains` is greater than 1. + Before this release every shard of a grouped run failed with an unknown signed + field error. The binding is part of the signed projection in Go field order. + This is per-receipt and per-chain compatibility only: whole-group verification + (signed open and close manifests, shard membership, missing shards, the link to + a previous group and recovery tails) still needs Pipelock's own group verifier. + Receipts from single-chain runs verify as before. + ## [0.4.0] - 2026-07-30 ### Added diff --git a/pipelock_verify/__init__.py b/pipelock_verify/__init__.py index 24a5475..05fb007 100644 --- a/pipelock_verify/__init__.py +++ b/pipelock_verify/__init__.py @@ -65,7 +65,7 @@ verify_chain, ) -__version__ = "0.4.0" +__version__ = "0.4.1" __all__ = [ "PAYLOAD_AUTHORITY", diff --git a/pyproject.toml b/pyproject.toml index 1553924..2c50099 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pipelock-verify" -version = "0.4.0" +version = "0.4.1" description = "Verify Pipelock receipts: ActionReceipt v1 chains and individual EvidenceReceipt v2 envelopes." readme = "README.md" license = "Apache-2.0" From de785cbc1c5b9ba653c55b7451790261705d79e5 Mon Sep 17 00:00:00 2001 From: luckyPipewrench Date: Mon, 12 Oct 2026 18:12:40 -0400 Subject: [PATCH 2/3] docs: state what a valid chain result does not prove --- CHANGELOG.md | 4 ++++ README.md | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d5c9be..b3e0d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 a previous group and recovery tails) still needs Pipelock's own group verifier. Receipts from single-chain runs verify as before. +### Documentation + +- **The README states what a valid result does not prove.** It no longer says exit codes match `pipelock verify-receipt` or that the package mirrors the Go verifier without qualification. A valid chain is not proof that its end is present, and a valid shard is not proof that a parallel-chain group is complete. + ## [0.4.0] - 2026-07-30 ### Added diff --git a/README.md b/README.md index d182737..19890bf 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ **Python verifier for [Pipelock](https://github.com/luckyPipewrench/pipelock) receipts.** Supports **ActionReceipt v1** chains and individual **EvidenceReceipt v2** envelopes for contract-aware lifecycle events. Verifies Ed25519 signatures, v1 chain linkage, v2 payload schemas, key-purpose authority, and flight-recorder wrapping. -Mirrors the Go reference implementation byte-for-byte. The conformance golden files in `tests/conformance/` are generated by Pipelock's Go code and verified identically by both sides. +Mirrors the Go reference implementation's signature, chain-linking and canonical-form checks byte-for-byte. The conformance golden files in `tests/conformance/` are generated by Pipelock's Go code and verified identically by both sides. It does not implement the end-of-chain proof or the whole-group verification that newer Pipelock releases add; see [What a valid result does and does not prove](#what-a-valid-result-does-and-does-not-prove). [Install](#install) · [Usage](#usage) · [EvidenceReceipt v2](#evidencereceipt-v2) · [Well-known directory](#well-known-directory) · [What gets verified](#what-gets-verified) · [Spec](https://pipelab.org/learn/action-receipt-spec/) · [Go reference](https://github.com/luckyPipewrench/pipelock) @@ -116,7 +116,13 @@ python -m pipelock_verify evidence.jsonl \ --rotation-endorsement receipt-rotation-2026-07-30.json ``` -Exit codes match `pipelock verify-receipt`: 0 on success, 1 on failure. +Exit codes: 0 on success, 1 on failure. In Pipelock releases that add end-of-chain proofs, `pipelock verify-receipt` also exits 3 for a valid chain whose end is not proven. This package has no such state. + +### What a valid result does and does not prove + +`CHAIN VALID` means every receipt present has a valid signature, the signer matches, and each receipt links to the one before it. It does not prove the chain ends where it should. A chain cut off after any receipt still verifies, because this package has no end-of-chain proof. Pipelock's own `pipelock verify-receipt` reports a chain with no proven end as `VALID PREFIX, END UNPROVEN`. Use it when a missing tail matters. + +Parallel receipt chains (`flight_recorder.receipt_chains` greater than 1) write one chain per shard. Each shard verifies on its own with this package, but a valid shard does not show that the group is complete. Shard membership, missing shards, the signed group open and close, and the link to a previous group still need Pipelock's own group verifier. ## EvidenceReceipt v2 From 5379af0439b3bbd6d92a59808017e013f9ddad53 Mon Sep 17 00:00:00 2001 From: luckyPipewrench Date: Mon, 12 Oct 2026 18:26:46 -0400 Subject: [PATCH 3/3] docs: qualify what a valid chain result proves --- CHANGELOG.md | 2 +- README.md | 4 ++-- pipelock_verify/__main__.py | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3e0d9b..6309217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Documentation -- **The README states what a valid result does not prove.** It no longer says exit codes match `pipelock verify-receipt` or that the package mirrors the Go verifier without qualification. A valid chain is not proof that its end is present, and a valid shard is not proof that a parallel-chain group is complete. +- **The README states what a valid result does not prove.** It no longer says exit codes match `pipelock verify-receipt` or that the package mirrors the Go verifier without qualification. A valid chain is not proof that its end is present, a valid shard is not proof that a parallel-chain group is complete, and entries other than ActionReceipt v1 in a recorder file are not checked. ## [0.4.0] - 2026-07-30 diff --git a/README.md b/README.md index 19890bf..4cd03c8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ **Python verifier for [Pipelock](https://github.com/luckyPipewrench/pipelock) receipts.** Supports **ActionReceipt v1** chains and individual **EvidenceReceipt v2** envelopes for contract-aware lifecycle events. Verifies Ed25519 signatures, v1 chain linkage, v2 payload schemas, key-purpose authority, and flight-recorder wrapping. -Mirrors the Go reference implementation's signature, chain-linking and canonical-form checks byte-for-byte. The conformance golden files in `tests/conformance/` are generated by Pipelock's Go code and verified identically by both sides. It does not implement the end-of-chain proof or the whole-group verification that newer Pipelock releases add; see [What a valid result does and does not prove](#what-a-valid-result-does-and-does-not-prove). +Mirrors the Go reference implementation's signature, chain-linking and canonical-form checks byte-for-byte. The conformance golden files in `tests/conformance/` are generated by Pipelock's Go code and verified identically by both sides. It does not implement the end-of-chain proof or the whole-group verification that newer Pipelock releases add; see the section "What a valid result does and does not prove" below. [Install](#install) · [Usage](#usage) · [EvidenceReceipt v2](#evidencereceipt-v2) · [Well-known directory](#well-known-directory) · [What gets verified](#what-gets-verified) · [Spec](https://pipelab.org/learn/action-receipt-spec/) · [Go reference](https://github.com/luckyPipewrench/pipelock) @@ -120,7 +120,7 @@ Exit codes: 0 on success, 1 on failure. In Pipelock releases that add end-of-cha ### What a valid result does and does not prove -`CHAIN VALID` means every receipt present has a valid signature, the signer matches, and each receipt links to the one before it. It does not prove the chain ends where it should. A chain cut off after any receipt still verifies, because this package has no end-of-chain proof. Pipelock's own `pipelock verify-receipt` reports a chain with no proven end as `VALID PREFIX, END UNPROVEN`. Use it when a missing tail matters. +`CHAIN VALID` means every ActionReceipt v1 extracted from the file has a valid signature, the signer matches, and each receipt links to the one before it. Other entries in a flight-recorder file are not checked here: altering the signature on a wrapped EvidenceReceipt v2 entry still returns `CHAIN VALID`, while Pipelock's own `pipelock verify-receipt` rejects the recorder. It also does not prove the chain ends where it should. A chain cut off after a receipt still verifies, because this package has no end-of-chain proof. The exception is a chain verified with a rotation endorsement: cutting it before the rotation boundary leaves the endorsement unused, and that is rejected. In Pipelock releases that add end-of-chain proofs, `pipelock verify-receipt` reports a chain with no proven end as `VALID PREFIX, END UNPROVEN`. Use it when a missing tail matters. Parallel receipt chains (`flight_recorder.receipt_chains` greater than 1) write one chain per shard. Each shard verifies on its own with this package, but a valid shard does not show that the group is complete. Shard membership, missing shards, the signed group open and close, and the link to a previous group still need Pipelock's own group verifier. diff --git a/pipelock_verify/__main__.py b/pipelock_verify/__main__.py index e5752b7..75f5853 100644 --- a/pipelock_verify/__main__.py +++ b/pipelock_verify/__main__.py @@ -1,8 +1,9 @@ """Command-line interface for ``python -m pipelock_verify``. Verifies a single receipt JSON file or a flight recorder JSONL chain. -Exit code 0 on success, 1 on failure — same convention as the Go -``pipelock verify-receipt`` command. +Exit code 0 on success, 1 on failure. Pipelock releases that add end-of-chain +proofs also exit 3 from ``pipelock verify-receipt`` for a valid chain whose end +is not proven; this CLI has no such state. """ from __future__ import annotations