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
12 changes: 10 additions & 2 deletions scripts/action_anchor_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,17 @@
"temporary failure", "cancelled", "canceled",
)
# Only these reach `contradicted`: an attestation WAS found and did not survive.
#
# `verifying with issuer` is the REAL shape, captured from live gh against this repo's
# first verifiable attestation with a deliberately wrong --signer-workflow
# (scripts/fixtures/gh_attestation_verify/signer_denied.txt). The rest of this tuple was
# a pre-merge guess, and the guess did not match: without this marker the most common
# denial fell through to the fail-closed default and was reported as `unavailable`, which
# is non-promoting either way but loses D5's observability distinction — "it said no" read
# as "I could not look". The fixture is why that was caught rather than assumed.
_CONTRADICTED_MARKERS = (
"verification failed", "failed to verify", "signature", "does not match",
"not signed by", "unable to verify", "policy", "mismatch",
"verifying with issuer", "verification failed", "failed to verify", "signature",
"does not match", "not signed by", "unable to verify", "policy", "mismatch",
)


Expand Down
2 changes: 2 additions & 0 deletions scripts/fixtures/gh_attestation_verify/signer_denied.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

Error: verifying with issuer "sigstore.dev"
22 changes: 21 additions & 1 deletion scripts/test_action_anchor_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

ROOT = pathlib.Path(__file__).resolve().parent.parent
SCRIPT = ROOT / "scripts" / "action_anchor_resolve.py"
FIXTURE_404 = ROOT / "scripts" / "fixtures" / "gh_attestation_verify" / "no_attestation_404.txt"
_FIXTURES = ROOT / "scripts" / "fixtures" / "gh_attestation_verify"
FIXTURE_404 = _FIXTURES / "no_attestation_404.txt"
FIXTURE_DENIED = _FIXTURES / "signer_denied.txt"

_HEAD = "a1" * 32
_REPO = "SollanSystems/loop-engineer"
Expand Down Expand Up @@ -150,6 +152,24 @@ def test_resolve_classifies_the_real_captured_404_stderr(tmp_path):
assert outputs["anchor-outcome"] == "unavailable"


def test_resolve_classifies_the_real_captured_denial_stderr(tmp_path):
"""M2's second half, capturable only AFTER a verifiable attestation existed.

Captured from live gh against this repo's first verifiable verdict@1 attestation with
a deliberately wrong --signer-workflow. It is the reason the marker set was corrected:
the pre-merge guess did not contain gh's real denial shape, so "it said no" was being
reported as "I could not look".
"""
assert FIXTURE_DENIED.is_file()
captured = FIXTURE_DENIED.read_text(encoding="utf-8")
assert "verifying with issuer" in captured
bin_dir, _log = _shim(tmp_path, stderr=captured, exit_code=1)
proc, outputs, _temp = _resolve(tmp_path, bin_dir=bin_dir)
assert proc.returncode == 1
assert outputs["anchor-outcome"] == "contradicted"
assert "anchor_attestation_contradicted" in proc.stdout


def test_resolve_maps_an_unclassifiable_failure_to_unavailable(tmp_path):
"""M2's fallback rule: an unrecognized shape is the most suspicious case."""
bin_dir, _log = _shim(tmp_path, stderr="weasel", exit_code=1)
Expand Down
Loading