Skip to content

chore(release): Prepare signer-aligned 1.0.9 dependency - #9

Merged
mstattma merged 1 commit into
feat/trusted-vsi-functionalfrom
release/signer-1.0.9
Oct 27, 2026
Merged

mstattma merged 1 commit into
feat/trusted-vsi-functionalfrom
release/signer-1.0.9

Conversation

@mstattma

@mstattma mstattma commented Oct 21, 2026 •

Copy link
Copy Markdown

Purpose

Prepare the signer-aligned dependency version 0.37.13+signer.1.0.9 for signer
1.0.9. The intended tag is castlabs-v0.37.13+signer.1.0.9.
This PR only prepares the release. It does not authorize a tag, a release or
publication. Publication waits for reviewer approval (Bibin or thasso) and then
the protected-environment gate.

Inputs (unchanged from published 0.37.13+signer.1.0.8)

  • Native castlabs/c2pa-rs@6021100cc5060b06061ca15b634281cfeb97c718. This is
    still the tip of c2pa-rs feat/trusted-vsi-functional, so no native change is
    pending.
  • Cargo.lock SHA-256 ff5cf2de2403ff491957fc8a2206c289203d2799a30425bd615f7c9e69974a8f.
    I re-checked it against the blob at 6021100.
  • Rust 1.96.0, native 0.92.0-dev, trusted contract revision 3, capability mask
    63, the feature set and the Python runtime API are all unchanged.
  • The base branch tip is abc9a034, which is the published 1.0.8 source
    (release ID 415634231, tagged run 39010024287). That tag, its release and
    its assets/evidence stay untouched and are not relabeled.

The base remains 0.37.13 because neither the Python line nor the native line
changed. Only the +signer.<version> label moves. The policy example in the
release notes used to say 0.37.14+signer.1.0.9. I changed it to the actual
identity, so please confirm that 0.37.13 is the intended base.

Changes (version label and release metadata only)

  • pyproject.toml, the c2pa.py version header, the inputs lock, the input
    and evidence schemas, and castlabs_release.py (RELEASE_VERSION, release
    body) now carry 0.37.13+signer.1.0.9.
  • castlabs-vsi-release.yml:
    • Tag trigger 'castlabs-v0.37.13\+signer.1.0.9', with the literal + still
      escaped.
    • Updated the concurrency group, the Linux/Windows wheel and bundle names,
      the expected versions, and the tag gate of the release job.
    • The release-tag check and the no-clobber draft discovery jq filter now
      use the new tag.
    • Unchanged: the castlabs-vsi-release environment, owned no-clobber draft
      creation, prerelease=false, the marker/label checks, source/branch-tip
      validation and attestations.
  • trusted-vsi-paired.yml: FUNCTIONAL_BUILD_VERSION and
    CASTLABS_RELEASE_EXPECTED_VERSION.
  • Tests:
    • Updated to the new identity.
    • New negative cases cover the published 1.0.8 identity: as a tag ref
      against the 1.0.9 lock, as a wheel dist-info, as a functional build
      version, and as a PyPI version.
    • A guard fails if the release or paired workflow still mentions
      signer.1.0.8.
  • Docs: README, release notes and the trusted-VSI contract record 1.0.8 as
    published and describe 1.0.9 as preparation only.

Verification so far

  • Locally: tests/test_castlabs_release_tooling.py and
    tests/test_trusted_vsi_build.py passed (66 tests, no native code), along
    with the lock-value and release-value helpers and git diff --check. There
    were no local cargo or native builds.
  • Hosted, non-publishing: paired Linux/Windows qualification of head
    98ccd6de63d89eca9c23f27658f6b29fe99daffc passed:
    https://github.com/castlabs/c2pa-python/actions/runs/39622774539
    (castlabs-vsi-release.yml, trusted_vsi_only=true, native 6021100c).
    Each platform ran 286 focused, 929 non-threaded (release smoke required) and
    54 threaded tests, plus the real-native ladder harness and 286 tests against
    the installed 0.37.13+signer.1.0.9 wheel. Nothing was skipped. All
    release jobs were skipped and no artifacts were uploaded. The PR Build run
    39622768702 passed, including Castlabs release tooling.

Remaining after approval (not done here)

  1. Integrate into feat/trusted-vsi-functional. A fast-forward keeps the
    qualified SHA equal to the release source. If a merge commit is used, its
    tree must match the qualified tree.
  2. Optionally, a build-only artifact run on the exact branch tip.
  3. Push the tag castlabs-v0.37.13+signer.1.0.9 at that tip. The tagged run
    builds and tests both platforms. Its release job waits for the protected
    castlabs-vsi-release environment and then creates an owned no-clobber
    draft.
  4. Validate the tagged assets, evidence and attestations, then publish by exact
    release ID.

No PyPI. Signer pins must be updated only after these immutable facts exist.

…native 6021100c

Select the release identity 0.37.13+signer.1.0.9 (intended tag
castlabs-v0.37.13+signer.1.0.9) for signer 1.0.9. Only the version label
and its release metadata change: the Python runtime, native
castlabs/c2pa-rs 6021100cc5060b06061ca15b634281cfeb97c718, Cargo.lock
SHA-256 ff5cf2de..., Rust 1.96.0, revision 3 / mask 63 and all release
controls are unchanged from the published 0.37.13+signer.1.0.8.

- Package, c2pa.py header, lock, input/evidence schemas, release helper
  and body, escaped tag trigger, concurrency group, wheel/bundle names,
  expected versions and the release job tag gate select 1.0.9.
- Tests reject the published 1.0.8 identity as a tag ref, dist-info,
  functional build version or workflow reference.
- Docs record 1.0.8 as published and add 1.0.9 preparation notes.

No tag, release or publication.
@mstattma
mstattma requested a review from BibinBaby444 October 21, 2026 15:07
@mstattma

Copy link
Copy Markdown
Author

@cl-percy start

@mstattma

Copy link
Copy Markdown
Author

Hosted non-publishing qualification of head 98ccd6de63d89eca9c23f27658f6b29fe99daffc

Paired Linux/Windows qualification passed:
https://github.com/castlabs/c2pa-python/actions/runs/39622774539. It was
dispatched from castlabs-vsi-release.yml with trusted_vsi_only=true. Both jobs
logged Python 98ccd6de and native 6021100c.

Job Focused Non-threaded (release smoke required) Threaded Installed 0.37.13+signer.1.0.9 wheel
ubuntu-24.04 (119300271632) 286 passed 929 passed 54 passed 286 passed
windows-2022 (119300272011) 286 passed 929 passed 54 passed 286 passed

Both jobs also ran the real-native ladder harness, with no skips.

  • All release prepare/build/test/publish jobs were skipped.
  • The run uploads no artifacts by design. Its isolated wheels are qualification
    bytes, not release candidates.
  • The PR Build run 39622768702 passed, including Castlabs release tooling.

What I did not run, and why:

  • Native was not re-qualified. 6021100c is unchanged, is still the c2pa-rs
    feat/trusted-vsi-functional tip, and was already qualified by c2pa-rs runs
    39004441528 and 39004441573.
  • A branch-tip build-only artifact run is not possible yet. It requires this
    commit on feat/trusted-vsi-functional, so it can run only after review.
  • No tag or draft was created.

@thasso, the REST review request rejected you as a non-collaborator on this
repository, so I'm asking for your review here instead. BibinBaby444 has been
requested formally. Either approval is enough for the publication gate.

@sripadmasm sripadmasm left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 98ccd6d): approve

Read-only review. No blocker, major or minor findings.

Native: unchanged.

  • The lock still pins c2pa-rs 6021100c. compare 6021100c...feat/trusted-vsi-functional reports identical.
  • Cargo.lock, toolchain, features and targets are unchanged.
  • sdk/src/settings/builder.rs:413/425 (all_actions_included / auto_all_actions_included) are present.
  • So the specVersion 2.4 / allActionsIncluded behaviour that signer contentauth#62 relies on, and verified natively on +signer.1.0.8, is preserved.

Python runtime: unchanged. The only change under src/ is the comment at src/c2pa/c2pa.py:14. __version__ never enters a manifest.

Release identity: consistent across pyproject, the lock, schemas, castlabs_release.py, both workflows and the tests. The body marker is now distinct from 1.0.8's, and new negative tests reject the 1.0.8 identity. No gates are weakened. The qualification run passed on Linux and Windows.

Suggestions

  • Native byte check: after the tagged run, compare the SHA-256 of libc2pa_c.so / c2pa_c.dll in the 1.0.9 bundles with the 1.0.8 release (ID 415634231). Equal hashes would prove "native unchanged" byte for byte.
  • Signer pin: signer 1.0.9 must pin the full local version, c2pa-python==0.37.13+signer.1.0.9. Under PEP 440, ==0.37.13 also matches the 1.0.8 wheel.

Release order for signer 1.0.9: see castlabs/stardustproof-c2pa-signer#55.

@mstattma

mstattma commented Oct 21, 2026 •

Copy link
Copy Markdown
Author

@sripadmasm thanks for the review. You only have read access to castlabs/c2pa-python, so GitHub cannot record a formal approval here; your review above (approve, no blocker/major/minor findings) is recorded as an advisory approval. Publication still waits for a formal approving review from a reviewer with write access. Your two suggestions are adopted for publication: (1) after the tagged run, the native libc2pa_c.so / c2pa_c.dll SHA-256 in the 1.0.9 bundles will be compared with the 1.0.8 release (ID 415634231) and recorded; (2) signer 1.0.9 will pin the full local version c2pa-python==0.37.13+signer.1.0.9.

@sripadmasm sripadmasm left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at 98ccd6d. The head is unchanged since my earlier review: native c2pa-rs is still 6021100c, the Python runtime is unchanged, the 1.0.9 release identity is consistent across all files, and no release gates are weakened. Signer 1.0.9 must pin c2pa-python==0.37.13+signer.1.0.9. Please run the native library SHA-256 comparison against 1.0.8 after the tagged run.

@mstattma
mstattma merged commit 98ccd6d into feat/trusted-vsi-functional Oct 27, 2026
26 checks passed
@mstattma
mstattma deployed to castlabs-vsi-release October 27, 2026 01:01 — with GitHub Actions Active
@mstattma

Copy link
Copy Markdown
Author

Published: c2pa-python 0.37.13+signer.1.0.9

https://github.com/castlabs/c2pa-python/releases/tag/castlabs-v0.37.13%2Bsigner.1.0.9

  • Release ID 424929277, published 2026-10-27T01:31:48Z. It is immutable=true,
    not a prerelease, and not marked latest. GitHub only; nothing was uploaded to PyPI.

  • feat/trusted-vsi-functional was fast-forwarded to 98ccd6de (tree
    07afbf43). The annotated tag castlabs-v0.37.13+signer.1.0.9 points to
    98ccd6de. Native is c2pa-rs 6021100c with Cargo.lock
    ff5cf2de...974a8f.

  • Non-publishing build on the branch tip, success:
    https://github.com/castlabs/c2pa-python/actions/runs/40425806264

  • Tagged release run, success:
    https://github.com/castlabs/c2pa-python/actions/runs/40427640583
    Both runs built Linux and Windows wheels and tested the installed wheels on
    Python 3.10-3.13 on each platform.

  • Before publishing, all 16 draft assets passed these checks:

    • GitHub server digests and the .sha256 sidecars;
    • validate-release-assets;
    • validate-evidence --source-sha 98ccd6de... for all three evidence documents;
    • strict draft verification;
    • GitHub attestations. Each was verified against castlabs-vsi-release.yml,
      the tag, source/signer digest 98ccd6de and hosted runners.

    After publishing, the asset set (IDs, names, sizes and digests) was unchanged.

Asset SHA-256
c2pa_python-0.37.13+signer.1.0.9-py3-none-manylinux_2_28_x86_64.whl 62eb9eeb3778a1d2e46e66a5c579a6d2886fe378c71f505f957363f4516d229f
c2pa_python-0.37.13+signer.1.0.9-py3-none-win_amd64.whl 1bb1212451cabdd895385ba0f86d2b33e992207f7525d487d4bba6d30aaeb890
c2pa-python-0.37.13+signer.1.0.9-py3-none-wheels.tar.gz 4b9311cce58962cac674f2408343208cc57ea1940bd89cbc42d3a557e9e845d1
c2pa-python-0.37.13+signer.1.0.9-py3-none-wheels.tar.gz.evidence.json d18a91bda040c6897e6ca8f8e3f55ebcfbd7957de59cdf935e069b5b8bc819c5
features-x86_64-unknown-linux-gnu.txt (unchanged from 1.0.8) 79f4cacf1b9218c6d959e6e5e778dd022b8b5acbdd6fdc0da3d35644d2737b87
features-x86_64-pc-windows-msvc.txt (unchanged from 1.0.8) ee272410d43d722b767cd7c83c3cc94879fd62a9c7b60b993eae46d9adff9754

Native SHA-256 comparison with 1.0.8 (release 415634231), as @sripadmasm requested

Each platform's library was extracted from three places: the native bundle,
the wheel, and the wheel inside the wheels bundle. All three copies agree
within each release.

1.0.8 1.0.9
Linux libc2pa_c.so d356a7afe705381d3a4f7d2f7fbdb70aab2325ad7617cefd29d035a301ff7c99 d356a7afe705381d3a4f7d2f7fbdb70aab2325ad7617cefd29d035a301ff7c99 byte-identical
Windows c2pa_c.dll 350befbb40a94312f9b0c5aadb6ec923a26992d56f9cc522c72c3837bb054bbc ea81191e5eb259db02c9b390efd128ad8483e2afe4ca94ffc89d8eb42c852d2d differs in linker metadata only

The Windows difference:

  • Both files have the same size (25,899,520 bytes) and the same PE layout.
  • 28 bytes differ, all in these fields:
    • the COFF header TimeDateStamp. The link time is 2026-10-17T06:41:46Z for
      1.0.8 and 2026-10-27T00:59:29Z for 1.0.9;
    • the three debug-directory timestamps (CODEVIEW, VC_FEATURE, POGO);
    • the 16-byte CodeView PDB GUID.
  • The PDB path, the PE checksum and every section byte are identical.
  • With those fields zeroed, both DLLs hash to
    0ea4c4209ea8292430b2783b94720e3219dda915af1249584f1b6d32f1122038.
  • The cause is the MSVC linker without /Brepro: every link gets a new
    timestamp and PDB GUID. Two other pairs built from identical source show the
    same difference and the same normalized hash:
    • 1.0.8's branch build and its tagged build;
    • this release's dry run and its tagged run.

The release owner accepted this Windows linker-metadata difference before
publication.

Signer pin: signer 1.0.9 must pin the full version,
c2pa-python==0.37.13+signer.1.0.9. Under PEP 440, ==0.37.13 also matches 1.0.8.

Follow-up proposal: reproducible Windows linking

Issues are disabled on this repository, so the proposal is recorded here.

  • Link c2pa_c.dll with /Brepro in future releases, for example via
    CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS=-C link-arg=/Brepro.
  • The release lock, evidence and validation should record the flag.
  • Add a gate that requires byte-identical natives between the dry run and the
    tagged run.
  • This would make Windows native hashes comparable across builds, like Linux.
  • It would itself change the DLL bytes compared with 1.0.8 and 1.0.9, so it
    belongs in a reviewed native or release-tooling change, not in a
    relabel-only release.

This branch had an error being deployed

1 failed and 1 active deployments
github-pages — 98ccd6de Deployed Oct 27, 2026 by mstattma via deploy #7
castlabs-vsi-release — 98ccd6de Deployed Oct 27, 2026 by mstattma via release #30
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