feat(prover): delivery C: the ordered trace with argument provenance for every examined pair

Codex delivery under spec access-control-prover, requirement 9. `semantic/obligations/trace.py` serialises each
(entry, operation) pair the prover examined, discharged or unguarded: the entry with its boundary, access and
parameters; each hop in order with its call line, the guards before the call and the values forwarded; the
operation with the provenance of each argument traced through the function's binds; the guards after it; the
verdict. One canonical text form and one JSON form, no language, framework, repository, size or count fields.
The prover result, the arm record and each unguarded finding carry the traces. On the ec2-plugin fix: 32
traces, 4 unguarded. Gate: 3534 tests pass; the reserved-repository guard passes on the tracked export.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Marius Ciepluch
2026-10-14 18:22:45 +02:00
co-authored by Claude Fable 5.1
parent 52ecbb76ab
commit 2f628b921b
6 changed files with 467 additions and 3 deletions
+5
View File
@@ -53,6 +53,9 @@ def test_stapler_verdict(tmp_path, guard, findings):
ctx = Context(root, change)
result = prove_change(root, change, ctx)
assert len(result.findings) == findings
assert len(result.traces) == 1
assert result.traces[0]["missing"] == ("path_guard" if findings else None)
assert result.traces[0]["dominating"] == ([] if findings else ["path_guard"])
assert result.coverage.operations_checked == 1
assert result.coverage.operations_discharged == 1 - findings
assert result.coverage.reached == 1
@@ -64,6 +67,7 @@ def test_stapler_verdict(tmp_path, guard, findings):
assert finding["entry"]["kind"] == "route" and finding["hops"] == [["Fixture.java::doTestConnection", None]]
assert finding["operation"]["calls"] == ["lookupCredentials"] and finding["missing"] == "path_guard"
assert finding["evidence"]
assert finding["trace"] is result.traces[0]
def test_unrecognised_is_coverage_only(tmp_path):
@@ -169,6 +173,7 @@ def test_declared_public_route_suppresses_premise(tmp_path):
result = prove_change(root, change)
assert not result.findings and result.coverage.operations_checked == 1
assert result.coverage.operations_discharged == 0
assert result.traces[0]["access"] == "public"
def test_nonpublic_unreached_function_in_partly_covered_repo(tmp_path):