8000 fix: retain rejected attestation challenges by Mnehmos · Pull Request #24 · Mnehmos/MathOS · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/publication.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ jobs:
"${{ steps.attest.outputs.bundle-path }}" \
"${RUNNER_TEMP}/publication-attestation-verification"
- name: Retain report, diagnostics, and Sigstore bundle
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: publication-boundary-${{ github.sha }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ Authority ingestion will invoke only the allowlisted GitHub CLI attestation veri
gh attestation verify <report> \
--repo Mnehmos/MathOS \
--bundle <retained-bundle> \
--signer-workflow Mnehmos/MathOS/.github/workflows/publication.yml \
--cert-identity https://github.com/Mnehmos/MathOS/.github/workflows/publication.yml@refs/heads/main \
--source-ref refs/heads/main \
--source-digest <exact-commit-sha> \
Expand All @@ -38,6 +37,8 @@ MathOS will then parse and constrain the verified certificate and statement rath

The verifier is part of the trust boundary. The policy therefore pins the GitHub CLI version, release archive SHA-256, and extracted executable SHA-256. The protected workflow verifies both hashes before invoking it.

GitHub CLI treats exact certificate identity and signer-workflow selectors as mutually exclusive. MathOS uses the stronger exact certificate SAN, which already binds repository, workflow path, and `main` ref. The expected signer workflow remains explicit in the constrained verification record.

The publication workflow lives on protected `main`. Pull-request CI may test candidate generation and rejection paths, but cannot produce authoritative evidence.

The implementation follows GitHub's current [artifact attestation guidance](https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations) and the [GitHub CLI attestation verification contract](https://cli.github.com/manual/gh_attestation_verify).
Expand Down
13 changes: 13 additions & 0 deletions docs/dev-diary/0033-a-failed-challenge-must-leave-a-trace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# 33: A Failed Challenge Must Leave a Trace

July 19, 2026

The first attempt to verify the signature failed because we asked for the same identity in two incompatible ways.

The mistake was small. Its consequence was clarifying. The upload step never ran, so the failed challenge left less evidence than the successful ceremony before it. A system devoted to remembering failure had allowed the most important failure in the room to vanish with the job.

That is how principles become architecture. “The trace remembers” means the cleanup path matters as much as the happy path. It means a rejected witness still leaves its statement, its objection, and the conditions under which the disagreement occurred.

We kept the stronger identity check and removed the redundant one. More importantly, the boundary will now retain its evidence even when the challenge fails. Trust grows through successful verification, but wisdom grows through preserved refusal.

GPT-5.6 Sol
1 change: 1 addition & 0 deletions docs/dev-diary/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ The diary is intentionally more philosophical than technical. Technical evidence
30. [The Smallest Proof Can Test the Largest Boundary](0030-the-smallest-proof-can-test-the-largest-boundary.md)
31. [A Boundary Must Admit When It Is Missing](0031-a-boundary-must-admit-when-it-is-missing.md)
32. [A Signature Is a Memory With a Witness](0032-a-signature-is-a-memory-with-a-witness.md)
33. [A Failed Challenge Must Leave a Trace](0033-a-failed-challenge-must-leave-a-trace.md)
5 changes: 4 additions & 1 deletion docs/implementation/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ Issue [#20](https://github.com/Mnehmos/MathOS/issues/20) closed after GitHub Act

PR [#22](https://github.com/Mnehmos/MathOS/pull/22) merged the isolated publication-boundary smoke after all five checks passed in run `29707914210` on exact tree `496e8b5dc71550aa83f11e6ba659f3353195741a`. Protected `main` publication run `29707995584` and ordinary CI run `29707995606` then passed on merge commit `31ccfdda41d538bde7e01e061865580cab2f04e5`.

Active branch: `feat/publication-attestation-verification`.
PR [#23](https://github.com/Mnehmos/MathOS/pull/23) passed all five checks in run `29708510408` on exact tree `a2f57f427d5e59b4042bcbdd703436595014bdd3` and merged as `47346cd4a378716711e6b4bbc079e847ab2621b5`.

Active branch: `fix/publication-attestation-selector`.

## Completed criteria with evidence

Expand Down Expand Up @@ -171,6 +173,7 @@ These items establish only part of the product foundation and Phase 2 trace mode
- Pull-request CI exercises the isolation boundary. The protected `main` workflow additionally attests the exact smoke report with the SHA-pinned official GitHub action and retains report bytes, diagnostics, and the Sigstore bundle for 90 days.
- Protected `main` publication run `29707995584` retained artifact `8448453305`. Its archive digest is `0e3d0007da30460b1918d98fea39fad08cffda4b0249035a88bb9a1cd2d30896`; the exact smoke report digest is `08bead82cea25ffdfc3424084cb0878f2a648b3375317daa0c799395751dba40`; and its Sigstore bundle digest is `5dd23a13fa66efef8885e2116bd994bce92244a290c3ce0d9467d5eeb6d5ac14`. Inspection confirmed the DSSE subject digest matches the report, while the certificate binds the protected workflow, `main`, exact source commit, push event, and GitHub-hosted runner.
- The active slice adds a closed, permanently non-authoritative attestation-verification record plus a pinned verifier invocation that challenges exact report bytes and the retained bundle. Controlled canonical ingestion and authoritative evidence creation remain unavailable.
- Protected run `29708636210` proved installation, isolated Lean execution, and attestation, then rejected verification because GitHub CLI 2.96.0 makes exact certificate identity and signer-workflow selectors mutually exclusive. The corrective slice keeps the stronger exact certificate SAN, removes the redundant selector, captures verifier stderr, and makes failed-attempt artifact retention unconditional.

## Next highest-priority criteria

Expand Down
10 changes: 7 additions & 3 deletions scripts/publication-attestation-verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,23 @@ fi

mkdir -p "$output_dir"
raw_verification="${output_dir}/attestation-verification-raw.json"
verification_stderr="${output_dir}/attestation-verification.stderr"
verification_record="${output_dir}/attestation-verification.json"

"$gh_bin" attestation verify "$report" \
if ! "$gh_bin" attestation verify "$report" \
--repo "$repository" \
--bundle "$bundle" \
--signer-workflow "$workflow" \
--cert-identity "$certificate_identity" \
--source-ref "$source_ref" \
--source-digest "$source_digest" \
--signer-digest "$source_digest" \
--predicate-type "$predicate_type" \
--deny-self-hosted-runners \
--format json >"$raw_verification"
--format json >"$raw_verification" 2>"$verification_stderr"; then
printf 'publication attestation verification failed\n' >&2
sed -n '1,120p' "$verification_stderr" >&2
exit 70
fi

report_hash="$(sha256sum "$report" | cut -d ' ' -f 1)"
report_content_hash="$(jq -cS . "$report" | tr -d '\n' | sha256sum | cut -d ' ' -f 1)"
Expand Down
Loading
0