From ebee1948eaf400a8c92d570e5c87bd42e6ae998a Mon Sep 17 00:00:00 2001 From: codex-scheduled Date: Fri, 14 Aug 2026 18:12:01 -0700 Subject: [PATCH] fix(ci): reconcile the cross-repo sparse-scope mirror and the sandboxed exit test Three tests fail on `main` at edfeae684 today. They are invisible because neither file lands in `main`'s changed-file set, so delta CI never runs them -- the first branch to touch either file inherits the failures and looks like it caused them. tests/ops/test_cross_repo_python_integration.py ::test_each_downstream_declares_its_required_sparse_scope ::test_upstream_scope_includes_every_release_build_package_root tests/rotation_converter/test_scripting_env.py ::TestConsoleEnvironment::test_refresh_user_functions_system_exit_propagates ## Cross-repo sparse scope: the workflow and its mirror test drifted apart The workflow declares UpstreamDrift's scope as `src/chat`, `src/contracts.py`, `src/python/src/utils`, `src/shared`, `src/sidekick`, `tests/shared_contracts`, `tests/support`. The test asserts the pre-`src/` names: `chat`, `contracts.py`, `python/src/utils`, `shared`, `sidekick`, plus `src/shared/python`. Both are relics of an UpstreamDrift reorganization that neither side fully followed. Checked every candidate against UpstreamDrift's default branch via the API rather than a local clone: | path | exists on UD `main` | | --- | --- | | `src/shared`, `tests/shared_contracts`, `tests/support` | yes | | `shared`, `src/shared/python` | yes | | `chat`, `sidekick`, `contracts.py`, `python/src/utils` | **no, in neither form** | So four declared paths match nothing at all. I removed them rather than inventing a replacement: a sparse entry that resolves to nothing is the same vacuous-gate family as #4477. The remaining question was which side to move. The test answers it itself: assert "src" not in upstream_scope assert "ui" not in upstream_scope Narrowness is a deliberate constraint, not drift, so declaring bare `src` was not available even though UpstreamDrift's hatchling config says `packages = ["src"]`. `src/shared` is the narrow root that actually carries the packages this repo provides -- UD's own `test_tools_vendoring.py` resolves from `src/shared/python`, and cone-mode sparse checkout populates `src/shared` without pulling all of `src`. The workflow was therefore the closer side, and the test's expectation is what moved. Not changed here, deliberately: `vendor/ud-tools` and the pinned-submodule init step are added by #4447, and `tests/fixtures` (which exists, and which UD's vendoring test seeds onto `sys.path`) may be a further gap. Both are left for their owners rather than folded in. Reviewer context worth having: the Cross-Repo Python Integration workflow's last *completed* run on `main` was a **failure** on 2026-08-06, so the previously declared path set cannot be assumed to have been the working configuration either. This change makes the declaration honest about what exists; it does not claim the cross-repo job is now green end to end. ## Sandboxed SystemExit test The scripting sandbox now blocks `import sys` ("import of 'sys' is blocked in the scripting sandbox"), so the test's `import sys; sys.exit(1)` never reaches `sys.exit` and no SystemExit is raised. The sandbox is the correct behaviour and the test is stale against it, so the payload is now `raise SystemExit(1)` -- SystemExit is a builtin, needs no import, and tests what the case is named for: propagation rather than being caught and logged. Verified: 15 passed across both files on Python 3.11, ruff check and format clean, changed-test assertion gate passes, and all three files keep their existing line endings. --- .../cross-repo-python-integration.yml | 4 ---- .../ops/test_cross_repo_python_integration.py | 22 ++++++++----------- .../rotation_converter/test_scripting_env.py | 5 ++++- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/.github/workflows/cross-repo-python-integration.yml b/.github/workflows/cross-repo-python-integration.yml index 0b507b1801..838ebd1abe 100644 --- a/.github/workflows/cross-repo-python-integration.yml +++ b/.github/workflows/cross-repo-python-integration.yml @@ -92,11 +92,7 @@ jobs: test_command: xvfb-run --auto-servernum pytest tests/shared_contracts/ --timeout=60 --timeout-method=thread -v --tb=short env_name: REQUIRE_REAL_TOOLS_REPO sparse_checkout: | - src/chat - src/contracts.py - src/python/src/utils src/shared - src/sidekick tests/shared_contracts tests/support diff --git a/tests/ops/test_cross_repo_python_integration.py b/tests/ops/test_cross_repo_python_integration.py index cbd7b17175..684cb1ae4b 100644 --- a/tests/ops/test_cross_repo_python_integration.py +++ b/tests/ops/test_cross_repo_python_integration.py @@ -14,12 +14,10 @@ "tests/shared_contracts", }, "D-sorganization/UpstreamDrift": { - "chat", - "contracts.py", - "python/src/utils", - "shared", - "sidekick", - "src/shared/python", + # UpstreamDrift moved its consumed packages under src/shared/python, so + # this is the narrow root that carries them. Deliberately NOT bare `src` + # -- see the assertions in the test below. + "src/shared", "tests/shared_contracts", "tests/support", }, @@ -75,13 +73,11 @@ def test_upstream_scope_includes_every_release_build_package_root() -> None: ) scope = set(upstream["sparse_checkout"].splitlines()) - assert { - "chat", - "contracts.py", - "python/src/utils", - "shared", - "sidekick", - } <= scope + # `src/shared` is the package root that actually carries the code this repo + # provides to UpstreamDrift; `pip install -e .` there resolves through + # hatchling's `packages = ["src"]`, and cone-mode sparse checkout gives it a + # populated `src/shared` without pulling all of `src`. + assert {"src/shared"} <= scope def test_downstream_checkout_keeps_sparse_checkout_authoritative() -> None: diff --git a/tests/rotation_converter/test_scripting_env.py b/tests/rotation_converter/test_scripting_env.py index 65f06d49c0..58be4d8986 100644 --- a/tests/rotation_converter/test_scripting_env.py +++ b/tests/rotation_converter/test_scripting_env.py @@ -112,7 +112,10 @@ def test_refresh_user_functions_system_exit_propagates(self) -> None: self.env.set_user_library_path(user_lib_path) # Save code that raises SystemExit - self.env.save_user_code("import sys; sys.exit(1)") + # `import sys` is blocked by the scripting sandbox, so importing it to + # reach sys.exit never raises. SystemExit is a builtin, so raise it + # directly to test what this case is actually about: propagation. + self.env.save_user_code("raise SystemExit(1)") # Should propagate instead of being caught and logged with self.assertRaises(SystemExit):