test: enforce the presentation exclusion contract for approval digests

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
tegwick 2026-09-10 18:39:30 +02:00
parent 62233c7c52
commit adb5cb0a9a
4 changed files with 109 additions and 1 deletions

View file

@ -56,3 +56,36 @@ def test_examples_are_claim_shaped():
assert data["issuer"] == "approval-engine"
for forbidden in ("effect", "decision", "allow", "deny"):
assert forbidden not in data
def test_presentation_changes_cannot_change_the_approved_act(engine):
"""GH-DEC-2026-015: presentation cannot enter the native digest preimage."""
act = binding()
original = approve(engine, extra_binding=act)
original_claim = engine.claim(original.id)
presentation = {
"view_hash": "sha256:" + "12" * 32,
"brief": "First explanation",
"packet": {"sections": ["summary"]},
"highlights": ["target"],
"locale": "de-DE",
"ui_release": "surface-v1",
"presentation": {"binding_digest": original_claim["binding"]["digest"]},
}
first = approve(engine, extra_binding={**act, **presentation})
changed = {key: {"changed": value} for key, value in presentation.items()}
second = approve(engine, extra_binding={**act, **changed})
for obj in (first, second):
assert engine.claim(obj.id)["binding"]["digest"] == original_claim["binding"]["digest"]
assert obj.binding == original.binding
# The invariant is about presentation, not permission to ignore act changes.
for field, replacement in {
"action": "secrets.kv.read",
"actor": "different-agent",
"principal": "different-principal",
"purpose": "different-purpose",
"target": {"id": "different-lane", "stage": "prod"},
}.items():
other = approve(engine, extra_binding={**act, **presentation, field: replacement})
assert engine.claim(other.id)["binding"]["digest"] != original_claim["binding"]["digest"]