Producer signatures + two-class base-judged PRs for the witnessed journal#94
Merged
Merged
Conversation
…rnal Adapted from the Axiom corpus signing architecture. Every release now carries a fourth sibling, NNNN-<hash16>.producer.sig: a raw Ed25519 signature over the manifest's exact bytes, verified against the committed releases/anchors/producer-ed25519.pub whose DER SPKI sha256 is pinned in code (same pattern as the TSA anchor pins). The genesis release is retro-signed in this commit, and verification requires a valid producer signature on every release unconditionally — an admin push carrying a valid manifest triple but no authorized signature is now detectably unsigned, closing the authorship gap documented in releases/README.md. PRs are split into two classes enforced by the gate itself: a change to GATE_SURFACE (gate, verifier, canonicalization, cutter, workflow, anchors) may not touch ledger/** or releases/manifests/**, and vice versa. For data PRs the workflow checks out the BASE commit's gate surface into a detached directory and judges the PR with the base's code — the PR's own gate copy is never executed — mirroring the axiom-corpus base-ref verifier isolation. A pull_request_target job (sourced by GitHub from the default branch, not the candidate) is added as the future unspoofable trust root; installing it on the default branch plus a ruleset-required workflow is a follow-up, and until then the ordinary pull_request job performs the same detached-base invocation. The cutter signs via key path only (--signing-key / --no-sign), never reading private-key bytes into Python, with staged verification and dirfd-anchored atomic writes. Ed25519 verification uses the cryptography package with an exact OpenSSL 3 fallback. Implemented by GPT-5.6 Sol to its own spec; reviewed, integrated, and genesis-signed by the orchestrator (private key never entered the implementation checkout). 99 tests pass including adversarial signature, mixed-PR, and base-isolation cases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaxGhenis
pushed a commit
to MaxGhenis/brier
that referenced
this pull request
Jul 11, 2026
Upstream (PolicyEngine/ledger#94) added Ed25519 producer signatures as a fourth release sibling and refuses unsigned proposals. This keeps brier ahead of the next resolution cycle on both sides of that boundary. Producer: propose_ledger_append signs each new manifest's exact bytes before any remote object exists. The private key arrives only as the LEDGER_PRODUCER_SIGNING_KEY env var (wired to exactly one workflow step), is popped from the process environment before any network client can inherit it, is materialized solely as an O_EXCL 0600 file in a 0700 tempdir for an argv-only openssl invocation, and is unlinked in finally. The signature self-verifies against the public key taken from the fetched BASE tree's committed anchor — not a local copy — and the staged four-sibling release is fully verified before the proposal branch or PR is created. Missing secret, signing failure, or self-verify failure abort with no visible partial state and without leaking diagnostics. Consumer: the vendored verifier is re-vendored byte-for-byte from the post-#94 upstream, so pin refreshes now require a valid producer signature on every historical release, refuse unsigned or wrong-key states and tampered anchors (SPKI pin), and history-bind signature blobs like receipts. Witness runs archive and inventory-bind .producer.sig bytes into custody alongside manifests and receipts. Implemented by GPT-5.6 Sol; reviewed and integrated with the real key never entering the implementation checkout. 231 tests pass across the pin, resolver, witness, registration, and publication suites. Co-Authored-By: Claude Fable 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.
Adds Ed25519 producer signatures (fourth release sibling, genesis retro-signed, SPKI-pinned committed public key) and the two-class PR rule with base-ref gate isolation, adapted from the Axiom corpus signing architecture. Full rationale in the commit message and releases/README.md.
Bootstrap note: the predecessor gate cannot admit its own successor — the genesis .producer.sig is a release-file addition without a ledger append, which the OLD gate correctly refuses. This PR is therefore the one-time documented bootstrap merge, exactly like genesis itself: the incoming gate validates this state (verify_release_chain --full passes with the signature required), the push-time CI on the merged branch re-verifies immediately, and every subsequent PR is judged by this code as base. Follow-up tracked: install the pull_request_target trust-root job on the default branch + ruleset-required workflow.
🤖 Generated with Claude Code