From 2f8fe388d326f6618841913654624f2de109a810 Mon Sep 17 00:00:00 2001 From: Jonah Gray Date: Thu, 27 Aug 2026 00:06:15 -0400 Subject: [PATCH] fix(OMN-16709): restore sys.modules in the scaffold fixture so the OMN-14985 ratchet passes `Tests Gate` -> `CI Summary` (a REQUIRED check on dev) has been failing closed on every omnibase_core branch since #1598 (OMN-16679) merged at 2026-08-27T00:00:29Z. The failing test is test_no_unrestored_del_sys_modules_in_tests, a static scan of the whole tests/ tree, so it fails regardless of what the PR under test changes -- observed on the docs-only #1600 (OMN-16581), reproduced byte-identically twice. The flagged fixture is NOT the OMN-14944 contaminator class. That class evicts PRE-EXISTING omnibase_core.* entries and never restores them. This fixture does the opposite: it deletes only `set(sys.modules) - original_modules`, i.e. names that did not exist before the test, which is the scaffold-package purge that keeps a temp package from leaking across xdist-shared workers. The ratchet's AST scan cannot see that set-difference semantics, so it is a true-positive lexical hit on a semantically correct fixture. Deliberately NOT fixed by wrapping the block in isolated_sys_modules(): that helper evicts pre-existing entries and restores them on exit while explicitly LEAVING newly-imported entries in place. Substituting it would satisfy the guard while deleting the purge this fixture exists to perform, reintroducing the cross-worker leak OMN-16679 guarded against. Instead: snapshot sys.modules as a dict, keep the newly-added-name purge exactly as-is, then sys.modules.update(original_modules). The purge behavior is unchanged, the fixture additionally restores any pre-existing entry a scaffold import displaced (strictly stronger than before), and the restore is the real one the ratchet's _function_restores_sys_modules looks for -- not a no-op added to appease the guard. Verified on the .201 gate host before commit: tests/unit/test_omn_14944_sys_modules_purge_regression.py -> 3 passed tests/unit/cli/test_cli_new_scaffold_runnable.py -> 8 passed i.e. the ratchet is green and every OMN-16679 acceptance test still passes. OMN-16709 --- tests/unit/cli/test_cli_new_scaffold_runnable.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/unit/cli/test_cli_new_scaffold_runnable.py b/tests/unit/cli/test_cli_new_scaffold_runnable.py index 17fcd159c6..57a5d31b22 100644 --- a/tests/unit/cli/test_cli_new_scaffold_runnable.py +++ b/tests/unit/cli/test_cli_new_scaffold_runnable.py @@ -43,11 +43,18 @@ def importable_src() -> Iterator[list[str]]: """ added: list[str] = [] original_path = list(sys.path) - original_modules = set(sys.modules) + original_modules = dict(sys.modules) yield added sys.path[:] = original_path - for name in set(sys.modules) - original_modules: + for name in set(sys.modules) - set(original_modules): del sys.modules[name] + # Put the pre-existing entries back verbatim. The purge above only removes + # names the scaffold run itself introduced, so this restore is a no-op in + # the common case -- but it makes the fixture provably incapable of leaking + # an OMN-14944-class eviction even if a scaffold import displaces an + # already-cached module, and it is the explicit restore the OMN-14985 + # ratchet (test_no_unrestored_del_sys_modules_in_tests) requires to see. + sys.modules.update(original_modules) def _scaffold(