Private
Public Access
0
0

revert(scripts): REVERT 5 LAUNDERING HEURISTICS (#22-#26) from Phase 10.3

Phase 10 added 5 heuristics to scripts/audit_exception_handling.py that
classified non-Result narrowing patterns as INTERNAL_COMPLIANT. These
were LAUNDERING heuristics — they made the audit say 'G4 resolved'
without actually doing the work. The convention requires Result[T] for
every try/except site that can fail; non-Result narrowing is not a
Result migration.

Reverted:
- #22: 'Narrow except + return fallback value' (non-Result return)
- #23: 'Narrow except + use error inline' (uses e/exc in non-pass way)
- #24: 'Narrow except + assign fallback' (sets var to fallback)
- #25: 'Narrow except + uses traceback' (uses traceback.format_exc())
- #26: 'Narrow except + runs fallback function/loop' (catch-all for
  non-trivial body; the worst of the 5)

Tests:
- The 2 existing tests for #22 and #23 are now @pytest.mark.xfail with
  reason citing the Phase 11 plan section. This preserves traceability
  and keeps the 11 test-tier count intact.
- Added 'import pytest' to the test file (was missing; required for the
  xfail decorator).

Heuristic #19 (catch+log via sys.stderr.write/logging.*) is NOT
reverted — it is the LEGITIMATE catch+log pattern, not a laundering
heuristic. The 2 warmup.py sites (_log_canary L276, _log_summary L301)
remain INTERNAL_COMPLIANT via Heuristic #19.

Per conductor/tracks/result_migration_small_files_20260617/plan.md
section 11.1.
This commit is contained in:
2026-06-17 23:54:59 -04:00
parent 133457a6d7
commit 37872544d5
2 changed files with 8 additions and 58 deletions
-41
View File
@@ -591,47 +591,6 @@ class ExceptionVisitor(ast.NodeVisitor):
f"Compliant: `try: ...; except Exception: return <string>` in a `-> str` tool function is the canonical MCP tool boundary pattern (per result_migration_review_pass_20260617).",
)
# 22. Narrow except + return fallback value (the function's return type is NOT Result)
if len(except_body) > 0 and not exc_set & {"Exception", "BaseException", ""} and self._has_simple_return(except_body):
enclosing_func = self._current_func_node()
if enclosing_func is None or enclosing_func.returns is None or "Result[" not in ast.unparse(enclosing_func.returns):
return (
"INTERNAL_COMPLIANT",
f"Compliant: `try: ...; except ({', '.join(sorted(exc_set))}): return <fallback>` in a non-Result-returning function is the canonical fallback pattern (per result_migration_small_files_20260617 Phase 10.3).",
)
# 23. Narrow except + use error inline (the except body uses `e`/`exc` in a non-pass way)
if len(except_body) > 0 and not exc_set & {"Exception", "BaseException", ""} and self._uses_exception_inline(except_body):
return (
"INTERNAL_COMPLIANT",
f"Compliant: `try: ...; except ({', '.join(sorted(exc_set))}) as exc: <use exc>` is the canonical inline-error pattern (per result_migration_small_files_20260617 Phase 10.3).",
)
# 24. Narrow except + assign fallback (no return, just sets a variable to a fallback value)
if len(except_body) > 0 and not exc_set & {"Exception", "BaseException", ""} and self._has_assign_fallback(except_body):
return (
"INTERNAL_COMPLIANT",
f"Compliant: `try: ...; except ({', '.join(sorted(exc_set))}): <var> = <fallback>` is the canonical assign-fallback pattern (per result_migration_small_files_20260617 Phase 10.3).",
)
# 25. Narrow except + uses traceback module (e.g., traceback.format_exc())
if len(except_body) > 0 and not exc_set & {"Exception", "BaseException", ""} and self._uses_traceback(except_body):
return (
"INTERNAL_COMPLIANT",
f"Compliant: `try: ...; except ({', '.join(sorted(exc_set))}): <use traceback.format_exc()>` is the canonical detailed-error pattern (per result_migration_small_files_20260617 Phase 10.3).",
)
# 26. Narrow except + runs fallback function/loop (no `e` use, just calls something else or loops)
if len(except_body) > 0 and not exc_set & {"Exception", "BaseException", ""} and len(except_body) > 0:
# If we have any non-trivial body (excluding just `pass`), and it's a narrow catch,
# assume it's a fallback pattern.
has_trivial_body = all(isinstance(s, ast.Pass) for s in except_body)
if not has_trivial_body:
return (
"INTERNAL_COMPLIANT",
f"Compliant: `try: ...; except ({', '.join(sorted(exc_set))}): <fallback body>` is the canonical fallback pattern (per result_migration_small_files_20260617 Phase 10.3).",
)
return None
def _has_string_return(self, stmts: list[ast.stmt]) -> bool: