mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 11:49:28 +00:00
fix(pre-push-safety-net): bind dependency gaps to the candidate (M1b 10.7)
The runner handed every candidate the whole transaction's coverage reason list as its unresolved dependencies, so admission always answered dependency_unresolved. That list even included other candidates' comparison outcomes, so one unresolved comparison anywhere marked every other claim as having an unresolved dependency. Gaps are now attributed. A boundary carrying a question id counts only when that question is in this candidate's required comparison scope, the same scope 10.2 established. A gap nothing attributed to any question always counts, because unknown ownership is not evidence of independence. Integrity degradations count. A declared exclusion, a correspondence ambiguity and a bounded reachability do not, because each was already weighed against this specific claim: the first is a scope choice, the second is decided per operation, and the third is decided per claim by the comparison. Found by the M1b production rerun rather than by the suite: the comparison reached a correct new verdict and admission still rejected it for a dependency belonging to unrelated questions. It is not an M1b exit blocker, since eligibility stays disabled, but it would have blocked admission forever once capabilities qualify. 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:
co-authored by
Claude Opus 5
parent
b8b46f1c19
commit
9a67f54ea1
@@ -549,3 +549,54 @@ def test_a_declared_exclusion_boundary_does_not_block_either():
|
||||
base = scan(rows=inventory_rows(), findings=False)
|
||||
base = replace(base, scope=replace(base.scope, unresolved_boundaries=("vendor_semantics_unresolved",)))
|
||||
assert delta(scan(), base, changed_line_context()).novelty == "new"
|
||||
|
||||
|
||||
def test_dependency_gaps_are_bound_to_the_candidate():
|
||||
"""M1b 10.7: an unrelated question's gap is not this claim's unresolved dependency."""
|
||||
from openultrasast.push.policy import dependency_gaps
|
||||
|
||||
head = scan()
|
||||
mine = head.scope.selected[0].identity
|
||||
other = replace(mine, family="path")
|
||||
head = replace(
|
||||
head,
|
||||
scope=replace(
|
||||
head.scope,
|
||||
selected=(*head.scope.selected, RankedQuestion(other, 0.0, ())),
|
||||
unresolved_boundaries=(
|
||||
"context_projection_unavailable:contributor-scan:" + other.question_id,
|
||||
"context_projection_unavailable:contributor-scan:" + mine.question_id,
|
||||
"dynamic_external_or_depth_context_unresolved:contributor-scan:" + mine.question_id,
|
||||
"vendor_semantics_unresolved",
|
||||
"612e6a73:ambiguous_line_correspondence",
|
||||
"snapshot:lfs_blob_unavailable",
|
||||
),
|
||||
),
|
||||
question_outcomes=(*head.question_outcomes, QuestionOutcome(other, "unresolved", "unsupported_family", "[]")),
|
||||
)
|
||||
candidate = delta(head, scan(rows=inventory_rows(), findings=False), changed_line_context())
|
||||
gaps = dependency_gaps(candidate, context=changed_line_context(), head=head)
|
||||
assert "context_projection_unavailable:contributor-scan:" + mine.question_id in gaps
|
||||
assert "snapshot:lfs_blob_unavailable" in gaps
|
||||
# Another question's problem, a scope choice, a per-operation decision and a weighed bound.
|
||||
assert "context_projection_unavailable:contributor-scan:" + other.question_id not in gaps
|
||||
assert "vendor_semantics_unresolved" not in gaps
|
||||
assert not any(g.endswith("ambiguous_line_correspondence") for g in gaps)
|
||||
assert not any(g.startswith("dynamic_external_or_depth") for g in gaps)
|
||||
|
||||
|
||||
def test_an_integrity_degradation_is_this_candidate_s_dependency():
|
||||
from openultrasast.push.policy import dependency_gaps
|
||||
|
||||
head = degraded(scan(), "cpg_sharded", "vendor_semantics_unresolved")
|
||||
candidate = delta(scan(), scan(rows=inventory_rows(), findings=False), changed_line_context())
|
||||
gaps = dependency_gaps(candidate, context=changed_line_context(), head=head)
|
||||
assert "cpg_sharded" in gaps and "vendor_semantics_unresolved" not in gaps
|
||||
|
||||
|
||||
def test_a_candidate_without_an_operation_reports_no_dependency_gaps():
|
||||
"""Witness resolution is its own admission reason; this one has nothing to attribute gaps to."""
|
||||
from openultrasast.push.policy import dependency_gaps
|
||||
|
||||
candidate = replace(delta(scan(), scan(rows=inventory_rows(), findings=False), changed_line_context()), head_operation=None)
|
||||
assert dependency_gaps(candidate, context=changed_line_context(), head=scan()) == ()
|
||||
|
||||
Reference in New Issue
Block a user