mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-18 04:29:27 +00:00
feat(pre-push-safety-net): bind the reachability boundary to what it limits (M1b 10.5)
dynamic_external_or_depth_context_unresolved was applied as though it invalidated everything about a question. It does not. Bounded reachability can hide further flows; it cannot invalidate a flow that was traced, and it cannot remove a call from a structurally scoped enumeration. At scan level the boundary is now recorded against its owning question without demoting that question's answer. An unavailable context projection, an empty context scope and an unreadable method extent are unknown ownership and still demote. In comparison it no longer blocks the head's own claim, since the finding rests on a path that was actually traced, and no longer blocks an absence read off the enumerated inventory. It still blocks every claim that rests on a flow not having been traced, including the anchored source-connection branch, which now reports base_reachability_bounded rather than silently passing. The query declares the basis of its enumeration. A file- or nesting-scoped question walks calls structurally, so an unresolved destination cannot remove one from scope. Following the call graph makes the reachable set the scope, so the same unresolved destination can shrink what was enumerated; that inventory cannot establish absence while reachability is bounded, and says so. One prior control asserted a question's own reachability gap blocks its own claim. It is updated with its reason and split, so an own projection gap is still proven to block while an own reachability gap no longer does. 1,362 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
c73efd2bde
commit
b202aabd8b
@@ -180,6 +180,11 @@ def _families(language: str, *, has_handler: bool) -> tuple[str, ...]:
|
||||
|
||||
|
||||
AMBIGUOUS_CORRESPONDENCE = "ambiguous_line_correspondence"
|
||||
# Reachability from or through the scoped methods was bounded. It limits which further flows
|
||||
# could be seen; it does not make this question's own answer or context ownership unknown, so
|
||||
# it is recorded as a boundary without marking the question's context incomplete. The later
|
||||
# comparison consults it for exactly the claims that rest on a flow not having been traced.
|
||||
REACHABILITY_BOUNDED = "dynamic_external_or_depth_context_unresolved"
|
||||
|
||||
|
||||
def affected_context(
|
||||
@@ -223,9 +228,11 @@ def affected_context(
|
||||
local_gaps.append("context_projection_unavailable:contributor-scan")
|
||||
elif not any(r.get("kind") == "context_method" for r in rows):
|
||||
local_gaps.append("context_scope_empty:contributor-scan")
|
||||
recorded_only: list[str] = []
|
||||
for row in rows:
|
||||
if row.get("kind") == "context_boundary":
|
||||
local_gaps.append(str(row.get("reason", "context_unresolved")))
|
||||
reason = str(row.get("reason", "context_unresolved"))
|
||||
(recorded_only if reason.startswith(REACHABILITY_BOUNDED) else local_gaps).append(reason)
|
||||
if row.get("kind") != "context_method":
|
||||
continue
|
||||
path = Path(str(row.get("path", "")))
|
||||
@@ -260,5 +267,5 @@ def affected_context(
|
||||
relationships.append(relation)
|
||||
if local_gaps or inherited_gap:
|
||||
affected_gaps.add(identity)
|
||||
gaps.extend(reason + ":" + identity.question_id for reason in local_gaps)
|
||||
gaps.extend(reason + ":" + identity.question_id for reason in (*local_gaps, *recorded_only))
|
||||
return replace(context, relationships=tuple(relationships), unresolved_boundaries=tuple(dict.fromkeys(gaps))), affected_gaps
|
||||
|
||||
Reference in New Issue
Block a user