Skip to content

fix(ci): reconcile the cross-repo sparse-scope mirror and the sandboxed exit test - #4480

Merged
dieterolson merged 1 commit into
mainfrom
fix/main-crossrepo-scope-and-sandbox-exit
Aug 15, 2026
Merged

fix(ci): reconcile the cross-repo sparse-scope mirror and the sandboxed exit test#4480
dieterolson merged 1 commit into
mainfrom
fix/main-crossrepo-scope-and-sandbox-exit

Conversation

@dieterolson

@dieterolson dieterolson commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Three tests fail on main at edfeae684 today, before this PR. They are invisible because neither file lands in main's changed-file set, so delta CI never runs them. The practical effect is that the first branch to touch either file inherits the failures and appears to have caused them — which is what happened to #4447.

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

Reproduce on a clean checkout of main:

git worktree add --detach /tmp/probe origin/main
cd /tmp/probe && pytest tests/ops/test_cross_repo_python_integration.py \
  tests/rotation_converter/test_scripting_env.py
# 3 failed

1-2. The cross-repo sparse scope 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.

I checked every candidate against UpstreamDrift's default branch via the API, not 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

Four declared paths match nothing at all. Removed rather than replaced with a guess — a sparse entry that resolves to nothing is the same vacuous-gate family as #4477.

Which side should move was the real question, and 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 to me, even though UpstreamDrift's hatchling config says packages = ["src"] and that would have been the simplest way to make the mirror agree. 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 the closer side, so the test's expectation is what moved.

Resulting scope:

D-sorganization/Gasification_Model -> src, tests/shared_contracts
D-sorganization/UpstreamDrift      -> src/shared, tests/shared_contracts, tests/support

Left out deliberately, so this stays reviewable and does not collide with work in flight:

Context a reviewer should have: the Cross-Repo Python Integration workflow's last completed run on main was a failure (2026-08-06). So the previously declared path set cannot be assumed to have been the working configuration either. This PR makes the declaration honest about what exists; it does not claim the cross-repo job is green end to end.

3. The sandboxed SystemExit test

The scripting sandbox now blocks import sysError loading user library: 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 correct behaviour; the test is stale against a good security change. The payload is now raise SystemExit(1): SystemExit is a builtin, needs no import, and the test goes back to checking what its name says — that it propagates rather than being caught and logged.

Why this is a separate PR

These are main's defects, not any one branch's. Fixing them here unblocks #4447, #4446 and every future branch that touches these files, instead of one; and it keeps a 34-PR consolidation from absorbing unrelated repairs.

Verification

  • 15 passed across both test files on Python 3.11 (was 3 failed).
  • ruff check and ruff format --check clean on both changed test files.
  • Changed-test assertion gate passes.
  • Workflow still parses as valid YAML; both jobs intact.
  • All three files keep their existing line endings (the workflow is CRLF on main and stays CRLF, so the diff is content only).

Part of #4460
Part of #4481

🤖 Generated with Claude Code

…ed exit test

Three tests fail on `main` at edfeae6 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.
@dieterolson
dieterolson enabled auto-merge (squash) August 15, 2026 01:19
@dieterolson
dieterolson merged commit 9495519 into main Aug 15, 2026
24 of 25 checks passed
dieterolson pushed a commit that referenced this pull request Aug 15, 2026
#4480 landed the three fixes for tests that failed on `main` but were never
selected by its delta CI. Re-syncing clears the last known cause of this
branch's `tests (3.11)` failure.

One conflict, in the release-build-package-root assertion, resolved as the
union: #4480's corrected `{"src/shared"}` plus this branch's
`vendor/ud-tools`, which is the pinned Tools gitlink UpstreamDrift's own
test_tools_vendoring.py resolves against.

I checked the auto-merged regions on content rather than trusting them, since
this is the exact file pair I mis-resolved two merges ago. Both are correct:
the workflow's UpstreamDrift scope is #4480's cleaned list plus
`vendor/ud-tools` with the submodule-init step intact, and
REQUIRED_SPARSE_PATHS carries the same four entries -- so the mirror and the
workflow agree, which is the property the test exists to enforce.

Verified: the three formerly-failing tests now pass (16 passed on 3.11), mypy
clean over CI's 374 files, ruff check and format clean over 584, changed-test
assertion and module-size gates pass, no conflict markers, no gitlinks.
dieterolson pushed a commit that referenced this pull request Aug 15, 2026
…visible tests

#4480 fixed the three tests that failed on `main` itself while `main` stayed green,
because delta CI never selected their files. Two of those live in
`tests/ops/test_cross_repo_python_integration.py`, which this branch also
modified, so it was the single conflict.

Resolved as a union rather than by taking a side:

* `REQUIRED_SPARSE_PATHS["D-sorganization/UpstreamDrift"]` keeps #4480's narrowed
  `src/shared` root and its explanatory comment, plus this branch's
  `vendor/ud-tools` entry.
* `test_upstream_scope_includes_every_release_build_package_root` keeps #4480's
  rewritten assertion and rationale, widened to
  `{"src/shared", "vendor/ud-tools"} <= scope`.
* This branch's `test_upstream_initializes_the_pinned_tools_submodule_before_install`
  is retained in full.

`.github/workflows/cross-repo-python-integration.yml` merged without conflict:
#4480 removed the four `src/chat`, `src/contracts.py`, `src/python/src/utils` and
`src/sidekick` entries that #4475 had introduced, and this branch had not touched
them, so the UpstreamDrift scope lands as exactly `src/shared`,
`tests/shared_contracts`, `tests/support`, `vendor/ud-tools` -- consistent with the
reconciled test. `tests/rotation_converter/test_scripting_env.py` took #4480's fix
cleanly.

Verified by running both affected files: **16 passed**, including all three tests
that were red on `main`.

`rerere` proposed the test-file resolution and it was inspected and test-verified
rather than trusted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
dieterolson pushed a commit that referenced this pull request Aug 15, 2026
… contract test

Merge conflicts:

* .github/workflows/cross-repo-python-integration.yml and its contract test —
  resolved to main's versions, deliberately NOT unioned. #4480 narrowed the
  UpstreamDrift sparse scope to `src/shared` and deleted the pinned-submodule
  step, with a comment explaining that UpstreamDrift moved its consumed packages
  under src/shared/python and that `pip install -e .` resolves through
  hatchling's `packages = ["src"]`. Its test asserts set *equality*
  (`actual == REQUIRED_SPARSE_PATHS`), so re-adding this branch's wider scope or
  the submodule-init step would fail the very test #4480 fixed. The wide scope is
  the superseded side, not content worth preserving; nothing else references the
  removed step. The workflow is now byte-identical to main, keeping #4475's
  CI_RUNNER_MODE fallback and public-repo hosted routing.
* AGENT_HANDOFF.md — kept this branch's policy-compliant rewrite and folded in
  main's new fact (#4406 drift-transfer diagnostics under UpstreamDrift epic
  #8551), 89 lines.
* SPEC.md — unioned, newest first.

canonical numeric JSON: the guard and the test contradicted each other and both
arrived from this branch's own fold. Resolved in favour of the guard, and the
test rewritten to assert the narrowed contract.

Evidence that the strict default is the intended contract, not an accident:

* The guard appears in three coordinated places — the float path, the integer
  path, and a named opt-out (`canonical_numeric_json_extended_floats`) whose
  docstring says "beyond the safe range while retaining safe integers".
* A dedicated facade, src/rate_of_closure/variation/canonical_numeric_json.py,
  re-exports the extended encoder under the plain name for the one caller that
  needs it (capability-observation payloads carrying declared 1e20/1e21
  magnitudes). That is how a contract gets narrowed while an established caller
  keeps working.
* The strict encoder's only production consumer is
  regional_ground_authority_status.py — the browser-facing authority job-status
  wire, where a value above 2**53-1 would reach the browser as a different
  number.
* The old test's own second case already asserted the +/-(2**53-1) boundary,
  i.e. the file half-agreed with the guard. The failing case was a pre-guard
  regression guard ("preserves established... domain") that the narrowing
  superseded.

The default guard is untouched: loosening it would make every cross-runtime
payload silently accept values JavaScript cannot represent, which is a contract
that cannot fail. The test now asserts (a) the default path fails closed for
out-of-range floats, (b) the opt-in path still serializes that domain exactly
with no exponent notation, and (c) the opt-in path still refuses unsafe
integers. canonical_numeric_float stays strict: its production consumers
(ground contract_types, ground_playback_comparison) carry physical magnitudes
far below the limit, so an unused opt-out would be speculative.

Not fixed here: test_wind.py's abs=1e-12 cross-client tolerance is #4482's
(~1600 ULP of accumulation under a different libm, not one rounding).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant