From cac41edceb3089d0ebcf3f6e22104c555c23b21a Mon Sep 17 00:00:00 2001 From: Codex Date: Sat, 31 Oct 2026 03:13:23 +0800 Subject: [PATCH] fix(ci): select exact Pelican contracts instead of feature suites --- .github/scripts/ci_plan.py | 42 ++++++++++++++++++++++++++--- .github/scripts/ci_run.py | 5 +--- .github/scripts/test_ci_plan.py | 48 ++++++++++++++++++++++++++++++++- .github/scripts/test_ci_run.py | 8 +++--- 4 files changed, 91 insertions(+), 12 deletions(-) diff --git a/.github/scripts/ci_plan.py b/.github/scripts/ci_plan.py index be1bcdb0f177..a55ca8afc9bc 100644 --- a/.github/scripts/ci_plan.py +++ b/.github/scripts/ci_plan.py @@ -18,8 +18,6 @@ RISK_RULES = ( (r"backend/internal/(?:service/deepseek_reasoning[^/]*|handler/admin/deepseek_reasoning[^/]*|server/routes/deepseek_reasoning[^/]*)\.go$", ("deepseek",)), (r"backend/internal/(?:service|handler)/.*claude.*(?:signature|thinking)[^/]*\.go$", ("claude",)), - (r"backend/internal/(?:service|handler(?:/admin)?)/pelican[^/]*\.go$", ("pelican",)), - (r"backend/internal/repository/pelican[^/]*\.go$|backend/migrations/(?:275|276|279|280|281)_[^/]*\.sql$", ("pelican", "pelican_db")), (r"backend/internal/service/pelican_(?:test_runner|execution|repeats|background)[^/]*\.go$", ("pelican_race",)), (r"backend/internal/service/account_test_sse_keepalive[^/]*\.go$", ("keepalive_race",)), (r"backend/internal/service/openai_account_runtime_block_fastpath[^/]*\.go$", ("probe_race",)), @@ -33,9 +31,29 @@ (r"backend/migrations/236_[^/]*\.sql$|backend/internal/repository/(?:audit_log|system_log)[^/]*\.go$", ("repository_audit",)), (r"backend/internal/pkg/codextransport/[^/]+$|backend/cmd/codex-transport-probe/[^/]+\.go$|\.github/scripts/(?:verify|capture)_codex_transport\.py$", ("transport",)), (r"backend/internal/(?:pkg/apicompat/[^/]+\.go|web/(?:agent[^/]*\.go|testdata/agent_cache_fixture\.js))$|\.github/scripts/test_agent_protocol\.sh$", ("agent_protocol",)), - (r"backend/internal/service/pelican_(?:chromium|renderer)[^/]*\.go$", ("renderer",)), + (r"backend/internal/service/pelican_renderer\.go$", ("renderer",)), ) +# A shared feature prefix is not a test boundary. Only reviewed source inputs +# may select these exact test files; new shared inputs require their own rule. +SOURCE_TEST_FILES = { + "backend/internal/handler/admin/pelican_gallery_handler.go": ( + "backend/internal/handler/admin/pelican_gallery_handler_test.go", + ), + "backend/internal/repository/pelican_deletion_repo.go": ( + "backend/internal/repository/pelican_deletion_repo_integration_test.go", + ), + "backend/internal/repository/pelican_background_repo.go": ( + "backend/internal/repository/pelican_background_repo_integration_test.go", + ), + "backend/migrations/279_pelican_test_deletion.sql": ( + "backend/internal/repository/pelican_deletion_repo_integration_test.go", + ), + "backend/migrations/281_pelican_repeat_samples.sql": ( + "backend/internal/repository/pelican_repeats_repo_integration_test.go", + ), +} + DEPLOY_RULES = { "deploy/apple-container.sh": ["deploy/tests/apple-container-test.sh"], "deploy/docker-compose.yml": ["deploy/tests/docker-compose-security-test.sh", @@ -174,6 +192,18 @@ def select(group: str, path: str): failures.append("linked_input:" + relative) continue known = False + source_tests = SOURCE_TEST_FILES.get(relative, ()) + if source_tests: + known = True + for target in source_tests: + selected = _go_test(repo / target, target) + if selected is None: + failures.append("source_test_selection_requires_mapping:" + relative) + known = False + continue + selected["reason"] = relative + tests.append(selected) + select("backend_focused", relative) if relative.startswith("docs/legal/") and path.suffix == ".md": select("static_docs", relative) select("frontend_validate", relative) @@ -269,7 +299,11 @@ def select(group: str, path: str): elif matched: for group in matched: select(group, relative) - known = True + # A shared Pelican runner also owns ordinary behavior; a race + # marker alone cannot claim that behavior has been validated. + if not (relative.startswith("backend/internal/service/pelican_") and + all(group.endswith("_race") for group in matched)): + known = True else: target = relative if relative.endswith("_test.go") else relative[:-3] + "_test.go" selected = _go_test(repo / target, target) diff --git a/.github/scripts/ci_run.py b/.github/scripts/ci_run.py index be0bbc3dedb6..bddfd08679cd 100644 --- a/.github/scripts/ci_run.py +++ b/.github/scripts/ci_run.py @@ -25,7 +25,7 @@ "release-helpers": {"generic_release_contracts"}, "Downstream backend": { "static_docs", "ci_contracts", "release_contracts", "upstream_contracts", - "transport", "agent_protocol", "deepseek", "claude", "pelican", "pelican_db", + "transport", "agent_protocol", "deepseek", "claude", "pelican_race", "keepalive_race", "probe_race", "management_race", "request_body", "account_jobs", "taxonomy_db", "retirement_migration", "repository_audit", "model_list", "turn_state", @@ -36,7 +36,6 @@ "frontend-security": {"frontend_security"}, } EXTERNAL = {"backend_lint", "candidate_image", "renderer"} -INTEGRATION = {"pelican_db", "taxonomy_db", "retirement_migration", "repository_audit"} def write_json(path: Path, value: dict) -> None: @@ -152,8 +151,6 @@ def go_test(packages: list[str], pattern: str, tags=(), race: bool = False) -> l GO_GROUPS = { "deepseek": (["./internal/service", "./internal/handler/admin", "./internal/server/routes"], "^TestDeepSeekDefault", ("unit",), False), "claude": (["./internal/service", "./internal/handler"], "^TestClaude(ThinkingSignatureError|Signature|OpsErrorLogger)|^TestGatewayService_Forward_(PreOutputSSE|PostOutputSSE)", ("unit",), False), - "pelican": (["./internal/service", "./internal/repository", "./internal/handler", "./internal/handler/admin", "./internal/server/routes"], "^Test(Pelican|AccountObservation|ObservedAccountLease)", ("unit",), False), - "pelican_db": (["./internal/repository"], "^TestPelican(TestRepositoryIntegrationLifecycle|DeletionIntegration|RepeatSamplesIntegration|OriginalHTMLGalleryIntegration)$", ("integration",), False), "pelican_race": (["./internal/service"], "^TestPelican(RunnerCancellationStopsQueuedAndInflightAndRetainsRawOutput|RepeatModel.*|AccountWaitReleases.*)$", ("unit",), True), "keepalive_race": (["./internal/service"], "^TestAccountTestKeepalive", ("unit",), True), "probe_race": (["./internal/service"], "TestOpenAIRuntimeBreaker_(APIKeySameAccountRetryDoesNotUseRedisLease|OAuthSameAccountRetryTransfersProbeUntilFinalFailure|SuppressedRetryReleasesSelectionClaim)", ("unit",), True), diff --git a/.github/scripts/test_ci_plan.py b/.github/scripts/test_ci_plan.py index 308250fd264d..7eb3a5d42238 100644 --- a/.github/scripts/test_ci_plan.py +++ b/.github/scripts/test_ci_plan.py @@ -97,12 +97,58 @@ def test_db_and_concurrency_are_opt_in_by_source_risk(self): self.assertFalse(any(group.endswith("_race") or group.endswith("_db") for group in ordinary["groups"])) database = ci_plan.classify_paths(["backend/migrations/281_pelican_repeat_samples.sql"]) self.assertTrue(database["passed"]) - self.assertIn("pelican_db", database["groups"]) + self.assertEqual(1, len(database["backend_tests"])) + self.assertEqual("^(?:TestPelicanRepeatSamplesIntegration)$", database["backend_tests"][0]["pattern"]) + self.assertEqual(["integration"], database["backend_tests"][0]["tags"]) self.assertIn("candidate_image", database["groups"]) concurrency = ci_plan.classify_paths(["backend/internal/service/account_test_sse_keepalive.go"]) self.assertTrue(concurrency["passed"]) self.assertIn("keepalive_race", concurrency["groups"]) + def test_gallery_source_selects_only_its_handler_contract(self): + plan = ci_plan.classify_paths(["backend/internal/handler/admin/pelican_gallery_handler.go"]) + self.assertTrue(plan["passed"], plan["failures"]) + self.assertEqual(1, len(plan["backend_tests"])) + selected = plan["backend_tests"][0] + self.assertEqual(["./internal/handler/admin"], selected["packages"]) + self.assertEqual("^(?:TestPelicanGalleryReadAndSVGFailurePreview)$", selected["pattern"]) + self.assertEqual(["unit"], selected["tags"]) + self.assertFalse(selected["race"]) + self.assertFalse(any(group in plan["groups"] for group in ("pelican", "pelican_db", "pelican_race", "renderer"))) + + def test_unmapped_shared_pelican_sources_block_even_with_race_marker(self): + for path in ("backend/internal/service/pelican_test_runner.go", + "backend/internal/service/pelican_execution.go", + "backend/internal/service/pelican_background.go", + "backend/internal/repository/pelican_test_repo.go", + "backend/internal/handler/admin/pelican_test_handler.go", + "backend/migrations/280_pelican_evaluation.sql"): + with self.subTest(path=path): + plan = ci_plan.classify_paths([path]) + self.assertFalse(plan["passed"]) + self.assertIn("unclassified_input:" + path, plan["failures"]) + self.assertFalse(plan["backend_tests"]) + + def test_reviewed_pelican_repository_inputs_select_only_their_own_integration(self): + for path, name in ( + ("backend/internal/repository/pelican_deletion_repo.go", "TestPelicanDeletionIntegration"), + ("backend/migrations/279_pelican_test_deletion.sql", "TestPelicanDeletionIntegration"), + ("backend/internal/repository/pelican_background_repo.go", "TestPelicanBackgroundSummaryPaginationRetainsFullDetails"), + ): + with self.subTest(path=path): + plan = ci_plan.classify_paths([path]) + self.assertTrue(plan["passed"], plan["failures"]) + self.assertEqual(1, len(plan["backend_tests"])) + self.assertEqual("^(?:" + name + ")$", plan["backend_tests"][0]["pattern"]) + self.assertEqual(["integration"], plan["backend_tests"][0]["tags"]) + + def test_renderer_source_keeps_only_its_explicit_runtime_risk(self): + plan = ci_plan.classify_paths(["backend/internal/service/pelican_renderer.go"]) + self.assertTrue(plan["passed"], plan["failures"]) + self.assertIn("renderer", plan["groups"]) + self.assertFalse(plan["backend_tests"]) + self.assertNotIn("pelican", plan["groups"]) + def test_embedded_transport_reference_is_a_runtime_build_input(self): plan = ci_plan.classify_paths(["backend/internal/pkg/codextransport/reference.json"]) self.assertTrue(plan["passed"]) diff --git a/.github/scripts/test_ci_run.py b/.github/scripts/test_ci_run.py index 988f24343e33..d26a24605ad4 100644 --- a/.github/scripts/test_ci_run.py +++ b/.github/scripts/test_ci_run.py @@ -67,10 +67,12 @@ def test_race_covers_duplicate_normal_function_once(self): directory = root / "backend/internal/service" directory.mkdir(parents=True) (directory / "pelican_test.go").write_text("//go:build unit\npackage service\nfunc TestPelicanOrdinary(t *testing.T) {}\nfunc TestPelicanRepeatModelOne(t *testing.T) {}\n", encoding="utf-8") - plan = {"groups": ["pelican", "pelican_race"]} + plan = {"groups": ["backend_focused", "pelican_race"], "backend_tests": [ + {"packages": ["./internal/service"], "pattern": "^TestPelican", "tags": ["unit"], "race": False}, + ]} with patch.object(ci_run, "ROOT", root): ci_run.resolve_go_checks(plan) - ordinary = plan["go_checks"]["pelican"][0]["pattern"] + ordinary = plan["go_checks"]["backend_focused"][0]["pattern"] raced = plan["go_checks"]["pelican_race"][0]["pattern"] self.assertIn("TestPelicanOrdinary", ordinary) self.assertNotIn("TestPelicanRepeatModelOne", ordinary) @@ -79,7 +81,7 @@ def test_race_covers_duplicate_normal_function_once(self): def test_empty_mapping_fails_instead_of_go_zero_test_success(self): with tempfile.TemporaryDirectory() as temporary, patch.object(ci_run, "ROOT", Path(temporary)): with self.assertRaisesRegex(ValueError, "matches_no_functions"): - ci_run.resolve_go_checks({"groups": ["pelican"]}) + ci_run.resolve_go_checks({"groups": ["pelican_race"]}) def test_embed_and_negative_unit_tags_follow_selected_build(self): with tempfile.TemporaryDirectory() as temporary: