Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f68b63a
Add execution receipt schema v1 with RFC 8785 digests
MaxGhenis Oct 11, 2026
2d4cb9a
Fix review findings: strict digests, bindable modifiers, core in cert…
MaxGhenis Oct 11, 2026
7df93cf
Fix round-2 review findings on execution receipt v1
MaxGhenis Oct 11, 2026
5174fd6
Add candidate qualification contracts and the scorecard replay interface
MaxGhenis Oct 11, 2026
2722a71
Qualify UK candidates: gates, ledger, ordered promotion and release d…
MaxGhenis Oct 11, 2026
d810066
Verify wheels through the shared provenance.wheels module
MaxGhenis Oct 11, 2026
d3bde21
Use the reform contract runner's default sample size
MaxGhenis Oct 11, 2026
a087276
Re-pin the scorecard replay schemas at 91f46c1
MaxGhenis Oct 11, 2026
ca3840d
Gate on the whole reform contract report, bound to the candidate
MaxGhenis Oct 11, 2026
da267e2
Test the contract gate on W1's real full all-pass report
MaxGhenis Oct 11, 2026
def8b8d
Follow the scorecard's tightened replay interface (dc040de)
MaxGhenis Oct 11, 2026
28c90ea
Fail a candidate whose standard reforms do not move the balance
MaxGhenis Oct 11, 2026
4da37e4
Read the metrics tool's own responsiveness checks
MaxGhenis Oct 11, 2026
68820f2
Follow the metrics tool at c7a6c9639: no-worsening by scope, skipped …
MaxGhenis Oct 11, 2026
3ea0b19
Pin the metrics tool with failing scopes; test on a real report
MaxGhenis Oct 11, 2026
b424ffb
Test scope-based no-worsening on the tool's real failing scopes
MaxGhenis Oct 11, 2026
ee78f5e
Close gate holes found by review: partial reports and self-contradict…
MaxGhenis Oct 12, 2026
abffac1
Close certification holes found by review
MaxGhenis Oct 12, 2026
a17f801
Close promotion and ledger holes found by review
MaxGhenis Oct 12, 2026
0d5cc12
Pin W3's metrics tool at 9b33fe19f
MaxGhenis Oct 12, 2026
23698f4
Enforce the qualified core before online compatibility acceptance
MaxGhenis Oct 12, 2026
537c0c1
Require exact replay wheel evidence and record baseline wheel identity
MaxGhenis Oct 12, 2026
3d19e3c
Prepare exact UK candidate sidecars and keep staged receipts ordered …
MaxGhenis Oct 12, 2026
b87a776
Require full contract coverage and bind finalized gate evidence to th…
MaxGhenis Oct 12, 2026
f58b11a
Attach the deferred-import lint suppression to the import statement
MaxGhenis Oct 12, 2026
ca93076
Merge remote-tracking branch 'origin/main' into w4/qualification-resp…
MaxGhenis Oct 12, 2026
d30e3f0
Gate W1's full run on released policyengine-uk 2.126.12 against the r…
MaxGhenis Oct 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 36 additions & 13 deletions .github/dispatch-policyengine-release.sh
Original file line number Diff line number Diff line change
@@ -1,28 +1,51 @@
#!/usr/bin/env bash
#
# Notify consumer repositories that a policyengine release is available on
# PyPI by sending a policyengine-release repository dispatch, which triggers
# their update workflows to open single-version bump PRs.
# PyPI by sending a repository dispatch, which triggers their update
# workflows.
#
# Environment:
# VERSION Exact policyengine version that was released.
# GH_TOKEN PolicyEngine GitHub App token with Contents write access to the
# consumer repositories.
# VERSION Exact policyengine version that was released.
# GH_TOKEN PolicyEngine GitHub App token with Contents write access to
# the consumer repositories.
# CONSUMER_REPOS Space-separated repositories to notify (default:
# policyengine-api policyengine-sim-api).
# PAYLOAD_FILE Optional JSON file holding the whole dispatch body
# ({"event_type": ..., "client_payload": {...}}), as written
# by scripts/release_consumers.py. Without it, a
# policyengine-release event carrying only the version is sent.
set -euo pipefail

if [[ -z "${VERSION:-}" ]]; then
echo "ERROR: VERSION must be set." >&2
exit 1
fi

CONSUMER_REPOS=(
policyengine-api
policyengine-sim-api
read -r -a REPOS <<< "${CONSUMER_REPOS:-policyengine-api policyengine-sim-api}"

if [[ -n "${PAYLOAD_FILE:-}" ]]; then
payload_version=$(python - "$PAYLOAD_FILE" <<'PY'
import json
import sys

payload = json.load(open(sys.argv[1]))["client_payload"]
request = payload.get("request")
print(payload.get("version") or request["candidate"]["policyengine"]["version"])
PY
)
if [[ "$payload_version" != "$VERSION" ]]; then
echo "ERROR: ${PAYLOAD_FILE} is for ${payload_version}, not ${VERSION}." >&2
exit 1
fi
fi

for repo in "${CONSUMER_REPOS[@]}"; do
gh api "repos/PolicyEngine/${repo}/dispatches" \
-f event_type=policyengine-release \
-f "client_payload[version]=${VERSION}"
echo "Dispatched policyengine-release ${VERSION} to PolicyEngine/${repo}."
for repo in "${REPOS[@]}"; do
if [[ -n "${PAYLOAD_FILE:-}" ]]; then
gh api "repos/PolicyEngine/${repo}/dispatches" --method POST --input "$PAYLOAD_FILE"
else
gh api "repos/PolicyEngine/${repo}/dispatches" \
-f event_type=policyengine-release \
-f "client_payload[version]=${VERSION}"
fi
echo "Dispatched policyengine ${VERSION} to PolicyEngine/${repo}."
done
78 changes: 78 additions & 0 deletions .github/qualification-ledger.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash
#
# Check out, or publish to, the qualification ledger branch.
#
# .github/qualification-ledger.sh checkout <dir>
# .github/qualification-ledger.sh publish <dir> "<commit message>"
#
# The ledger is an orphan branch that only grows: each candidate pair writes
# its own directory, so concurrent publishes never touch the same file and a
# rejected push is retried by replaying the single new commit on the latest
# tip. The new commit may be the branch's first (two runs can both find no
# ledger yet), so it is replayed with cherry-pick, which needs no parent.
set -euo pipefail

BRANCH="${LEDGER_BRANCH:-uk-qualification-ledger}"
command="${1:?usage: qualification-ledger.sh checkout|publish <dir> [message]}"
dir="${2:?ledger directory required}"

case "$command" in
checkout)
if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null 2>&1; then
git fetch --quiet origin "$BRANCH"
git worktree add --quiet --force -B "$BRANCH" "$dir" FETCH_HEAD
else
git worktree add --quiet --detach "$dir"
(
cd "$dir"
git switch --quiet --orphan "$BRANCH"
cat > README.md <<'README'
# UK candidate qualification ledger

Written by `.github/workflows/certify-uk-release.yaml` in PolicyEngine/policyengine.py.
Each `uk/<pair_id>/` directory holds a candidate pair, every qualification
attempt's gate evidence, the replay request and receipt, and the latest
qualification receipt. Nothing is deleted.
README
)
fi
;;
publish)
message="${3:?commit message required}"
cd "$dir"
git add -A
if git diff --cached --quiet; then
echo "Ledger unchanged."
exit 0
fi
identity=(-c user.name="policyengine-qualification[bot]"
-c user.email="qualification@policyengine.org")
git "${identity[@]}" commit --quiet -m "$message"
new_commit="$(git rev-parse HEAD)"
delay="${LEDGER_RETRY_DELAY:-5}"
for attempt in 1 2 3 4 5 6; do
if git push --quiet origin "HEAD:refs/heads/$BRANCH"; then
echo "Published ledger: $message"
exit 0
fi
# Someone else published first: replay this one commit on their tip.
if ! git fetch --quiet origin "$BRANCH"; then
sleep $((attempt * delay))
continue
fi
git reset --quiet --hard FETCH_HEAD
if ! git "${identity[@]}" cherry-pick --allow-empty "$new_commit" >/dev/null; then
git cherry-pick --abort || true
echo "::error::The ledger commit conflicts with a concurrent publish."
exit 1
fi
sleep $((attempt * delay))
done
echo "::error::Could not publish the qualification ledger after 6 attempts."
exit 1
;;
*)
echo "Unknown command: $command" >&2
exit 2
;;
esac
Loading
Loading