feat(pre-push-safety-net): carry query-to-operation provenance (M1b 10.8)

M1a recorded that the NodeGoat target is selected through a file-scoped question
naming no function while the engine reports method <lambda>2, and that this did
not block the comparison once the question completed. It was still only visible by
digging the method out of a serialized detail blob.

Evidence now carries the engine-reported method beside the question that produced
it, and the relationship between them is recorded: exact when the question named
that method, file_scope when the question named no function and the engine
supplied one, unresolved when the two disagree, and method_unreported when the
engine named none.

Recorded, not applied. No region is renamed, no benchmark function name is
injected into a region, and no coincident site is counted. The recorded-veto
report now reads the field instead of reparsing the detail blob.

1,371 tests passed, nine skipped. Rollout stays NO-GO.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
Marius Ciepluch
2026-09-16 18:55:31 +02:00
co-authored by Claude Opus 5
parent 9a67f54ea1
commit 541ee5813e
3 changed files with 41 additions and 7 deletions
+5 -5
View File
@@ -34,6 +34,7 @@ from openultrasast.push.policy import (
_context_boundaries,
_counterpart,
admit_candidates,
operation_provenance,
)
FLAG = "--experimental-record-vetoes"
@@ -227,9 +228,7 @@ def _summary(scan: ModelScanResult, lifted: ModelScanResult, counts: Counter[str
def _method(op: EvidenceOperation) -> str | None:
row = json.loads(op.detail)
value = row.get("sinkMethod") if op.mechanism == "taint" else row.get("opMethod") if op.mechanism == "dominance" else None
return value if isinstance(value, str) and value.strip() else None
return op.method
def _boundary_vetoes(stage: str, boundaries: Sequence[str]) -> list[RecordedVeto]:
@@ -277,12 +276,13 @@ def _finding_vetoes(
vetoes.extend(_boundary_vetoes("head_scan", _context_boundaries(head, question)))
vetoes.extend(_degradation_vetoes("head_scan", head))
method = _method(op)
if question.function is None or (method is not None and question.function != method):
provenance = operation_provenance(op)
if provenance != "exact":
vetoes.append(
RecordedVeto(
"identity",
"query_identity_differs_from_witness",
f"question function={question.function!r}; witness method={method!r}; recorded, not a policy veto",
f"provenance={provenance}; question function={question.function!r}; engine method={method!r}",
False,
)
)