ci: PyPI release workflow (Trusted Publishing) - #2
Merged
Merged
Conversation
The package builds and passes `twine check`, but nothing ever pushed it: the name is unclaimed on PyPI and the README had to send readers to a git URL. This adds the tag-triggered release job. It uses OIDC rather than an API token, so there is no publishing secret in the repo to leak. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VWTgH2xDR5xafCX83YvQQV
MrPredic
added a commit
that referenced
this pull request
Aug 5, 2026
…ttest Two post-review hardening fixes that close the gap between the marketed USP and what the code delivered. #1 Signature tamper-evidence (was cryptographically hollow) - _sign() no longer writes a companion .pub next to the .sig. A pub that travels with the signature is no trust anchor: an attacker edits the fingerprint, re-signs with their own key, ships their own pub, verify passed. Tamper-evidence was effectively 0. - verify() now checks the signature against a PINNED public key (indelible.pub, committed) or one supplied out-of-band via --pubkey. A signature with no pinned key is a hard error, never a silent pass. - init now emits indelible.pub (and re-derives it for pre-existing keys). - Documented the honest trust model in SECURITY.md / README / llms.txt: authenticates origin+integrity relative to a pinned key, not attester honesty; cross-party verification must pin the key out-of-band. #2 Determinism (baseline was maximally noisy) - New IndelibleConfig.temperature, default 0.0, threaded through all three providers (Anthropic/OpenAI-compat temperature, Ollama options.temperature). Attestation ran at provider-default temp (~1.0), injecting sampling noise into every signal and manufacturing false breaches. - temperature is part of the canonical config hash (different temp = different behavioral baseline). Also: softened over-reaching EU AI Act claim to "supporting evidence"; documented latency as network-influenced/informational; hand-tuned tolerances flagged as uncalibrated. TDD: 17 new tests (tamper-resign attack, wrong-key, missing-anchor, temperature threading + canonical hash). Full suite 164 passed, ruff + mypy clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MrPredic
added a commit
that referenced
this pull request
Aug 5, 2026
The package builds and passes `twine check`, but nothing ever pushed it: the name is unclaimed on PyPI and the README had to send readers to a git URL. This adds the tag-triggered release job. It uses OIDC rather than an API token, so there is no publishing secret in the repo to leak. Claude-Session: https://claude.ai/code/session_01VWTgH2xDR5xafCX83YvQQV Co-authored-by: MrPredic <269417388+MrPredic@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
MrPredic
added a commit
that referenced
this pull request
Aug 7, 2026
…ttest Two post-review hardening fixes that close the gap between the marketed USP and what the code delivered. #1 Signature tamper-evidence (was cryptographically hollow) - _sign() no longer writes a companion .pub next to the .sig. A pub that travels with the signature is no trust anchor: an attacker edits the fingerprint, re-signs with their own key, ships their own pub, verify passed. Tamper-evidence was effectively 0. - verify() now checks the signature against a PINNED public key (indelible.pub, committed) or one supplied out-of-band via --pubkey. A signature with no pinned key is a hard error, never a silent pass. - init now emits indelible.pub (and re-derives it for pre-existing keys). - Documented the honest trust model in SECURITY.md / README / llms.txt: authenticates origin+integrity relative to a pinned key, not attester honesty; cross-party verification must pin the key out-of-band. #2 Determinism (baseline was maximally noisy) - New IndelibleConfig.temperature, default 0.0, threaded through all three providers (Anthropic/OpenAI-compat temperature, Ollama options.temperature). Attestation ran at provider-default temp (~1.0), injecting sampling noise into every signal and manufacturing false breaches. - temperature is part of the canonical config hash (different temp = different behavioral baseline). Also: softened over-reaching EU AI Act claim to "supporting evidence"; documented latency as network-influenced/informational; hand-tuned tolerances flagged as uncalibrated. TDD: 17 new tests (tamper-resign attack, wrong-key, missing-anchor, temperature threading + canonical hash). Full suite 164 passed, ruff + mypy clean.
MrPredic
added a commit
that referenced
this pull request
Aug 7, 2026
The package builds and passes `twine check`, but nothing ever pushed it: the name is unclaimed on PyPI and the README had to send readers to a git URL. This adds the tag-triggered release job. It uses OIDC rather than an API token, so there is no publishing secret in the repo to leak. Co-authored-by: MrPredic <269417388+MrPredic@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Package builds clean and passes
twine check, but the name is unclaimed on PyPI and there was no release job. Adds a tag-triggered publish over OIDC — no API token stored anywhere.Needs one manual step before the first tag: add the pending publisher on PyPI (project name, owner
MrPredic, workflowrelease.yml, environmentpypi).