Skip to content

Restructure CI: comparator battery at one pin, per-suite and per-pin jobs, parallel compiles - #71

Merged
tadamcz merged 12 commits into
mainfrom
ci-restructure
Sep 24, 2026
Merged

tadamcz merged 12 commits into
mainfrom
ci-restructure

Conversation

@tadamcz

@tadamcz tadamcz commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Follow-up to the timing run in #68, which put time-to-green at 85 to 116 minutes: every job rebuilt its Lean images from an empty cache, the comparator battery ran at all four pins in one serial job, and the five isolation suites ran back to back. This PR restructures which tests run where; it does not touch how images are built.

What runs where now

  • Comparator battery at one pin. test_lean_vuln_e2e.py and test_comparator_security.py run once, at the OEIS pin, via module constants PIN and IMP. Comparator's verdict logic and the checker's staging do not vary with the pin.
  • Three suites at every registered pin. test_proof_acceptance.py, test_agent_image.py and test_comparator_primitives.py run at each pin in apn.dataset.FC_PINS: the image builds, an honest proof and disproof are accepted, Lake resolves helper modules, Loogle's per-pin binary and index work, and the comparator primitives resolve. pin is the parametrized fixture; --fc-pin restricts it to one pin and rejects an unregistered one.
  • One CI job per suite. The isolation suites are five jobs; a pins job prints FC_PINS as JSON and per-pin fans out over it with fromJSON, so no pin is listed in the workflow. all-checks needs every other job and fails unless all succeeded; branch protection should require that one status.
  • Nothing can drop out silently. The tests job selects by --ignore only, so a module listed in no job runs there. A pins failure skips per-pin, which all-checks reports as failure.
  • Compile gate at up to 16 parallel jobs in the isolation suites, from xargs' default 4: 607 s to 199 s for the 492 OEIS specs in Scratch: time every CI suite on current main #68.
  • --durations=25 on every pytest job, so the next timing question is answered from the log at hand.

History also contains a removal of the OEIS isolation oracle and its revert; the oracle stays.

Measured

Run 36015119047 on this branch, before the per-pin fan-out, against #68 on the same runner class:

Job #68 This branch
time-to-green 85 min 42.5 min
comparator-tests 85 min 28 min
isolation, slowest of five 40 min, one job 20 min
gold-proofs 33 min 42 min, unchanged job, now the critical path

That run's VM was 25 to 30 percent slower than #68's on the unchanged jobs, so the improvement is understated. The serial per-pin job in that run took 36 min; the fan-out replaces it with four parallel jobs of roughly 12 min each.

Not in this PR

Sharding the gold sweep, which is now the critical path; any image-build cache; trimming duplicate cases in the battery.

Comparator's verdict logic and the checker's staging do not vary with the FC pin, so test_proof_acceptance, test_lean_vuln_e2e and test_comparator_security now run once, at the OEIS pin (conftest's pin fixture). What does vary per pin -- toolchain, Mathlib, util-module layout, the cache-get permissions that bit in #65, the exporter built at that toolchain -- is covered by the new tests/test_pin_smoke.py (honest proof and honest disproof accepted in each pin's production images) plus test_comparator_primitives, both parametrized over apn.dataset.FC_PINS from Python via the every_pin fixture, so a new pin is tested without a CI change. The comparator job drops from 148 tests to 34; the per-pin work moves to a pin-smoke job.
…ry job

The isolation job ran five datasets back to back, each building its own generate image; they are now one job each so the run's wall-clock is the slowest suite rather than the sum. The new all-checks job needs every other job and fails unless all of them succeeded (matrix suites included), so branch protection can require that one status. Suites are still selected by listing modules per job, with the tests job selecting by --ignore only: a module listed nowhere runs there, so forgetting to update this file cannot drop a suite from CI.
…ison

The oracle re-extracted the 38 published gold proofs to compare each target_theorem_0 type with our spec's target, and the extractor elaborates the full proofs to do it: 384 s and 610 s in the two isolation runs of the scratch PR, a quarter to a third of the OEIS fixture. test_gold_proofs runs every one of those proofs through Comparator against our spec, and Comparator compares the whole statement closure before accepting, so the oracle was a weaker form of a check that already runs.
The compile gate's xargs default of 4 left the 64-core runner idle: 607 s for the 492 OEIS specs against 199 s at 16 jobs in the scratch PR, and 107 s against 38 s for fc100. The tests now pass APN_COMPILE_JOBS = min(cpu count, 16) into the sandbox exec; 16 stayed well inside the generate container's 32 GiB limit in that run. The script's own default is unchanged for the vendor-time dev container.
Every pytest job's log now ends with pytest's setup/call/teardown table for its slowest phases, so the next CI-time question can be answered from the logs of the run at hand instead of a data-collection PR.
The two single-file acceptance cases stay in the suite as well as in test_pin_smoke.py; at the OEIS pin they run twice.
A fixture called pin that yields one hardcoded value reads as parametrized when it is not. The three comparator suites now define PIN = fc_commit(OEIS_DIR) and IMP at module level and use them directly; conftest keeps only the parametrized every_pin.
…ated from Python

The pin-smoke job built four pins' images back to back, 36 minutes in the last run. A pins job now prints apn.dataset.FC_PINS as JSON and pin-smoke fans out over it with fromJSON, one job per pin, so the pin list still lives only in Python. Each job runs the two per-pin modules with a new --fc-pin option (conftest), which rejects an unregistered pin. all-checks needs both new jobs, so a failure in the generator fails the run rather than skipping the pins.
…rop the smoke module

Instead of a hand-picked smoke module, the per-pin job runs three whole files at each registered pin: test_proof_acceptance.py (back to main's version, with the pin/imp fixtures; pin is now the parametrized fixture, filtered by --fc-pin), test_agent_image.py (Loogle's binary and index are the one agent chunk built per pin) and test_comparator_primitives.py. The standalone agent-image job is the OEIS pin's instance of that and goes. Per pin this is about 2.5 min of acceptance checks and 2 min of agent contract on top of the image build, in parallel jobs, so time-to-green is unchanged.
@tadamcz tadamcz changed the title Cut CI time: battery at one pin, per-suite jobs, oracle removal, parallel compiles Restructure CI: comparator battery at one pin, per-suite and per-pin jobs, parallel compiles Sep 24, 2026
…pin suite now

The comparator-tests entry still listed test_proof_acceptance.py after it became pin-parametrized, so that job built all four pins' images and ran the suite at each, 42 minutes instead of about 22. It now runs only the two battery suites.
@tadamcz
tadamcz merged commit c69b563 into main Sep 24, 2026
16 checks passed
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