From dffe0ff05be8e6eedb077fa9244637bcd7476bcc Mon Sep 17 00:00:00 2001 From: Trecek Date: Sat, 30 May 2026 20:19:41 -0700 Subject: [PATCH 1/3] feat(test-filter): add MODULE_CASCADE_CORE entries for 5 unclassified core modules Adds cascade entries for _type_constants_env, _type_constants_features, _type_constants_registries, _type_exceptions, and _step_context to route them to their actual import consumers instead of falling through to the full 18-directory cascade. Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/_test_filter.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/_test_filter.py b/tests/_test_filter.py index dbce0c1c28..d47ccf7341 100644 --- a/tests/_test_filter.py +++ b/tests/_test_filter.py @@ -233,6 +233,17 @@ class ImportContext(enum.StrEnum): "_type_session_env": frozenset({"core", "cli"}), "_type_capture": frozenset({"core", "fleet", "recipe", "cli"}), "_type_token": frozenset({"core", "execution"}), + "_type_constants_env": frozenset( + {"cli", "config", "core", "execution", "recipe", "server", "smoke_utils", "workspace"} + ), + "_type_constants_features": frozenset( + {"cli", "config", "core", "fleet", "recipe", "server", "workspace"} + ), + "_type_constants_registries": frozenset( + {"cli", "config", "core", "pipeline", "recipe", "server", "workspace"} + ), + "_type_exceptions": frozenset({"core", "fleet", "recipe", "server"}), + "_step_context": frozenset({"core", "execution", "pipeline", "server"}), } # Narrow per-module cascade for execution/. Modules not listed here fall through From f5e93efa78fccd9ef33a21f12422c30d65001018 Mon Sep 17 00:00:00 2001 From: Trecek Date: Sat, 30 May 2026 20:21:18 -0700 Subject: [PATCH 2/3] test(test-filter-core-cascade): add tests for 5 new MODULE_CASCADE_CORE entries - Expand expected_stems to 38 entries (was 33) - Add 5 cascade value assertions (T2) to TestModuleCascadeCore - Add 5 routing tests (T3) to TestBuildTestScopeCoreCascade - Add REQ-FILT-007 completeness guard TestCoreStemCompleteness Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/test_test_filter_core_cascade.py | 137 +++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/tests/test_test_filter_core_cascade.py b/tests/test_test_filter_core_cascade.py index 3c821d6386..1d25b16dee 100644 --- a/tests/test_test_filter_core_cascade.py +++ b/tests/test_test_filter_core_cascade.py @@ -101,6 +101,11 @@ def test_all_entries_present(self) -> None: "_type_session_env", "_type_capture", "_type_token", + "_type_constants_env", + "_type_constants_features", + "_type_constants_registries", + "_type_exceptions", + "_step_context", } assert set(MODULE_CASCADE_CORE.keys()) == expected_stems @@ -176,6 +181,31 @@ def test_json_cascade(self) -> None: {"core", "execution", "pipeline", "recipe", "server"} ) + def test_type_constants_env_cascade(self) -> None: + assert MODULE_CASCADE_CORE["_type_constants_env"] == frozenset( + {"cli", "config", "core", "execution", "recipe", "server", "smoke_utils", "workspace"} + ) + + def test_type_constants_features_cascade(self) -> None: + assert MODULE_CASCADE_CORE["_type_constants_features"] == frozenset( + {"cli", "config", "core", "fleet", "recipe", "server", "workspace"} + ) + + def test_type_constants_registries_cascade(self) -> None: + assert MODULE_CASCADE_CORE["_type_constants_registries"] == frozenset( + {"cli", "config", "core", "pipeline", "recipe", "server", "workspace"} + ) + + def test_type_exceptions_cascade(self) -> None: + assert MODULE_CASCADE_CORE["_type_exceptions"] == frozenset( + {"core", "fleet", "recipe", "server"} + ) + + def test_step_context_cascade(self) -> None: + assert MODULE_CASCADE_CORE["_step_context"] == frozenset( + {"core", "execution", "pipeline", "server"} + ) + class TestBuildTestScopeCoreCascade: """REQ-CORE-003/004: build_test_scope routes core modules correctly.""" @@ -549,6 +579,113 @@ def test_json_narrow_cascade(self, tmp_path: Path) -> None: for excluded in ["config", "fleet", "migration", "workspace", "cli", "planner"]: assert excluded not in dir_names, f"narrow cascade should not include {excluded}" + def test_type_constants_env_narrow_cascade(self, tmp_path: Path) -> None: + """_type_constants_env → narrow cascade (smoke_utils silently dropped, no test dir).""" + tests_root = self._make_tests_root(tmp_path, self.ALL_DIRS) + result = build_test_scope( + changed_files={"src/autoskillit/core/types/_type_constants_env.py"}, + mode=FilterMode.CONSERVATIVE, + tests_root=tests_root, + ) + assert result is not None + dir_names = {p.name for p in result} + for pkg in ["core", "cli", "config", "execution", "recipe", "server", "workspace"]: + assert pkg in dir_names, f"_type_constants_env cascade should include {pkg}" + for excluded in ["fleet", "pipeline", "migration", "planner", "hooks"]: + assert excluded not in dir_names, ( + f"_type_constants_env cascade should not include {excluded}" + ) + + def test_type_constants_features_narrow_cascade(self, tmp_path: Path) -> None: + """_type_constants_features → narrow cascade of 7 dirs.""" + tests_root = self._make_tests_root(tmp_path, self.ALL_DIRS) + result = build_test_scope( + changed_files={"src/autoskillit/core/types/_type_constants_features.py"}, + mode=FilterMode.CONSERVATIVE, + tests_root=tests_root, + ) + assert result is not None + dir_names = {p.name for p in result} + for pkg in ["core", "cli", "config", "fleet", "recipe", "server", "workspace"]: + assert pkg in dir_names, f"_type_constants_features cascade should include {pkg}" + for excluded in ["execution", "pipeline", "migration", "planner", "hooks"]: + assert excluded not in dir_names, ( + f"_type_constants_features cascade should not include {excluded}" + ) + + def test_type_constants_registries_narrow_cascade(self, tmp_path: Path) -> None: + """_type_constants_registries → narrow cascade of 7 dirs.""" + tests_root = self._make_tests_root(tmp_path, self.ALL_DIRS) + result = build_test_scope( + changed_files={"src/autoskillit/core/types/_type_constants_registries.py"}, + mode=FilterMode.CONSERVATIVE, + tests_root=tests_root, + ) + assert result is not None + dir_names = {p.name for p in result} + for pkg in ["core", "cli", "config", "pipeline", "recipe", "server", "workspace"]: + assert pkg in dir_names, f"_type_constants_registries cascade should include {pkg}" + for excluded in ["execution", "fleet", "migration", "planner", "hooks"]: + assert excluded not in dir_names, ( + f"_type_constants_registries cascade should not include {excluded}" + ) + + def test_type_exceptions_narrow_cascade(self, tmp_path: Path) -> None: + """_type_exceptions → narrow cascade of 4 dirs.""" + tests_root = self._make_tests_root(tmp_path, self.ALL_DIRS) + result = build_test_scope( + changed_files={"src/autoskillit/core/types/_type_exceptions.py"}, + mode=FilterMode.CONSERVATIVE, + tests_root=tests_root, + ) + assert result is not None + dir_names = {p.name for p in result} + for pkg in ["core", "fleet", "recipe", "server"]: + assert pkg in dir_names, f"_type_exceptions cascade should include {pkg}" + for excluded in [ + "cli", + "config", + "execution", + "pipeline", + "migration", + "workspace", + "hooks", + ]: + assert excluded not in dir_names, ( + f"_type_exceptions cascade should not include {excluded}" + ) + + def test_step_context_narrow_cascade(self, tmp_path: Path) -> None: + """_step_context → narrow cascade of 4 dirs.""" + tests_root = self._make_tests_root(tmp_path, self.ALL_DIRS) + result = build_test_scope( + changed_files={"src/autoskillit/core/_step_context.py"}, + mode=FilterMode.CONSERVATIVE, + tests_root=tests_root, + ) + assert result is not None + dir_names = {p.name for p in result} + for pkg in ["core", "execution", "pipeline", "server"]: + assert pkg in dir_names, f"_step_context cascade should include {pkg}" + for excluded in ["cli", "config", "fleet", "migration", "workspace", "recipe", "hooks"]: + assert excluded not in dir_names, ( + f"_step_context cascade should not include {excluded}" + ) + + +class TestCoreStemCompleteness: + """REQ-FILT-007: every core/ .py stem must be classified.""" + + def test_all_core_stems_classified(self) -> None: + core_root = Path("src/autoskillit/core") + actual_stems = {p.stem for p in core_root.rglob("*.py") if p.stem != "__init__"} + classified = set(_CORE_UNIVERSAL_MODULES) | set(MODULE_CASCADE_CORE) + unclassified = actual_stems - classified + assert not unclassified, ( + f"Unclassified core stems (will fall through to full 18-dir cascade): " + f"{sorted(unclassified)}" + ) + class TestClosureCoreNarrowCascade: """Closure-added core/__init__.py uses MODULE_CASCADE_CORE when all causes are narrow.""" From 343b1924bc4279b4a1184475f73d10f07a7d9ab4 Mon Sep 17 00:00:00 2001 From: Trecek Date: Sat, 30 May 2026 20:37:30 -0700 Subject: [PATCH 3/3] fix(review): add non-emptiness guard to TestCoreStemCompleteness Prevents the REQ-FILT-007 completeness assertion from trivially passing when pytest runs from a non-root directory where the relative path resolves to zero files. Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/test_test_filter_core_cascade.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_test_filter_core_cascade.py b/tests/test_test_filter_core_cascade.py index 1d25b16dee..d736144872 100644 --- a/tests/test_test_filter_core_cascade.py +++ b/tests/test_test_filter_core_cascade.py @@ -679,6 +679,9 @@ class TestCoreStemCompleteness: def test_all_core_stems_classified(self) -> None: core_root = Path("src/autoskillit/core") actual_stems = {p.stem for p in core_root.rglob("*.py") if p.stem != "__init__"} + assert actual_stems, ( + f"No .py files found under {core_root} — is pytest running from the project root?" + ) classified = set(_CORE_UNIVERSAL_MODULES) | set(MODULE_CASCADE_CORE) unclassified = actual_stems - classified assert not unclassified, (