From bb7dff468811c4c48c42b8b3d0decfd6b49bb2f8 Mon Sep 17 00:00:00 2001 From: aurascoper Date: Mon, 27 Jul 2026 11:23:06 -0500 Subject: [PATCH 1/2] ci: run the Python contract suites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Neither NeuralComposeEEG nor Tests/eval has ever run in CI — build-and-test is Swift-only. That is how a test importing an uncommitted module reached a pull request unnoticed, and it left 62 Python tests ungated. Adds a `python-contracts` job on ubuntu-latest (nothing here is platform-specific, and the runner is cheaper than macOS). pytest is a correctness requirement, not a preference. Tests/eval mixes four harness styles, and most modules are bare `def test_*` functions with no TestCase and no __main__ runner. `python -m unittest Tests.eval.` collects ZERO tests from those and prints OK — 8 of 62 tests would have run behind a green check. pytest collects all 62. Excluded, each for a stated reason rather than to force green: test_joint_embedding.py imports mlx.core; Apple Silicon only 3 deselected cases pre-existing failures on this base, reproducing on both NumPy 1.26.4 and 2.4.6; tracked separately. The rest of their files still run. Requires the lazy trapezoid resolution in the parent commit: test_session_consume imports eeg_spectral, which could not import on numpy>=2 before it. Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 58 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9cfd75..adc4b8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,3 +64,61 @@ jobs: # collision/flake risk on a headless runner. The OSC *decode* logic is # covered socket-free by MuseOSCDecoderTests / MindMonitorDecoderTests, # which still run. Run the socket integration test locally. + + # The Python contract suites had no CI at all until now, which is how a test + # importing an uncommitted module (neuralcompose_eeg.structured_state) reached + # a pull request unnoticed: build-and-test above is Swift-only. + # + # Linux, not macOS: nothing here is platform-specific, and the runner is both + # cheaper and faster. The one Apple-only suite is excluded by name below. + python-contracts: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + cache: pip + cache-dependency-path: NeuralComposeEEG/requirements.txt + + - name: Install Python dependencies + run: | + # CPU wheel explicitly: the default Linux torch pulls a ~800MB CUDA + # build for a runner with no GPU. Installed first so the pinned + # requirements below see torch>=2.0 as already satisfied. + pip install --index-url https://download.pytorch.org/whl/cpu torch + pip install -r NeuralComposeEEG/requirements.txt + # pandas is a Tests/eval harness dependency only (session capture + # frames); deliberately not a NeuralComposeEEG requirement. + # pytest is required, not stylistic: most Tests/eval modules are bare + # `def test_*` functions with no unittest.TestCase and no __main__ + # runner, so `python -m unittest` collects ZERO of them and exits 0. + pip install pandas pytest + + # Offline scientific package: canonical dataset contracts, capture + # manifests, and the structured-state shadow bridge. Discovered rather + # than enumerated so new contract suites are picked up automatically. + - name: Test (NeuralComposeEEG contracts) + run: | + PYTHONPATH=NeuralComposeEEG/src \ + python -m unittest discover -s NeuralComposeEEG/tests -t . --verbose + + # pytest, because Tests/eval mixes four harness styles: unittest.TestCase, + # bare `def test_*` with a __main__ runner, and bare `def test_*` with no + # runner at all. pytest collects all of them; unittest collects 8 of 62 + # and reports OK for the rest. + # + # test_joint_embedding.py imports mlx.core (Apple Silicon only) and would + # fail collection here — run it locally. + # + # The three deselected cases fail on this base and are tracked separately; + # they are pre-existing, reproduce on both NumPy 1.26 and 2.4, and are not + # caused by this workflow. The rest of their files still run. + - name: Test (eval contract suites) + run: | + pytest Tests/eval -v \ + --ignore=Tests/eval/test_joint_embedding.py \ + --deselect Tests/eval/test_eval_stats.py::test_cohens_d_large_effect \ + --deselect Tests/eval/test_eval_stats.py::test_mann_whitney_u_disjoint \ + --deselect Tests/eval/test_embedding_space.py::test_cka_independent From 09ac18ab235573e76a5570121a04de1adfb64579 Mon Sep 17 00:00:00 2001 From: aurascoper Date: Mon, 27 Jul 2026 11:24:11 -0500 Subject: [PATCH 2/2] ci: reference issue #38 for the deselected eval cases Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index adc4b8b..d21a343 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,8 +113,8 @@ jobs: # fail collection here — run it locally. # # The three deselected cases fail on this base and are tracked separately; - # they are pre-existing, reproduce on both NumPy 1.26 and 2.4, and are not - # caused by this workflow. The rest of their files still run. + # they are pre-existing (issue #38), reproduce on both NumPy 1.26 and 2.4, and + # are not caused by this workflow. The rest of their files still run. - name: Test (eval contract suites) run: | pytest Tests/eval -v \