Skip to content

A breaking change with a documented consumer migration has no fleet check: three sibling repos were unrunnable on v0.43.0 for a release cycle #1123

Description

@InauguralPhysicist

Summary

v0.43.0 shipped #1056, which made file resolution independent of the process working directory. Its changelog entry names the migration exactly: "consumers using root-relative paths from subdirectory files need an eigs.json at their project root."

Nobody ran that migration on the fleet. Three sibling repos have had unrunnable test suites since v0.43.0, and nothing anywhere reported it.

Measured, 2026-09-08, with the v0.43.0 release binary

repo manifest affected files what broke
EigenMiniSat none 6 tests/test_solver.eigs, tests/test_tseitin_invariant.eigs, lib/bench.eigs, all three benchmarks
Tidepool none 5 every entry point, because game.eigs is loaded by all of them
eddy none 3 src/dst.eigs, src/rw_dst.eigs, test/test_explorer_ui.eigs
$ cd EigenMiniSat && eigenscript tests/test_solver.eigs
Error line 6: load_file: cannot read 'lib/dimacs.eigs' (not found or unreadable);
tried containing directory '/home/user/EigenMiniSat/tests', eigs_modules walk,
no eigs.json above /home/user/EigenMiniSat/tests; ...

The diagnostic is excellent. It names every root it tried and the fix is one file. That is not the problem.

Fixed in each repo by adding eigs.json, which is the documented migration and what ouroboros did at its own pin bump. Verified after: EigenMiniSat reports "All EigenMiniSat solver tests passed", Tidepool "All regressions passed", eddy's script runs to completion.

Why nobody noticed, and why that is the actual finding

EigenMiniSat's root-level minisat.eigs was unaffected. A smoke test of the solver itself passed the whole time. What broke was the correctness suite and the entire benchmark surface — the parts that only run when someone is measuring something.

The consumer repos are pinned to older releases, which is deliberate and correct: they are post-release coverage, not a pre-merge gate, and a pin is what keeps them stable. But a pinned repo does not exercise the new release, so the breakage is invisible until someone bumps the pin, and the bump is exactly when a green suite is assumed rather than checked.

So the forcing-function model has a hole where its own design puts one. Consumers find gaps by real use, and a consumer that cannot start is not using anything. The property that makes them useful is the property that hid this.

I found it by accident, while setting up an unrelated benchmark. Time-to-discovery for that path is unbounded; this instance ran a full release cycle.

Direction

The cheap version is not a suite. It is a start-check: for each sibling repo present on the box, run its declared entry point against a candidate binary and assert it gets past module resolution. Seconds per repo, and it would have caught all three.

Where it has to live is the part worth deciding carefully:

  • It cannot be an EigenScript CI gate. CI has no sibling repos, and vendoring them is the wrong trade.
  • It fits the release path, which already has a doc-drift gate and a tag/dispatch checklist. A pin bump or a release cut is the moment the question "does the fleet still start" is both answerable and load-bearing.
  • It must fail loudly when it can measure nothing. A check that finds no sibling repos and reports success is worse than no check, and this repo has been bitten by exactly that shape before (the empty git tag case in the drift gate, the vacuous enrollment in the werror gate).

Each repo needs one declared entry point. Most already have one in their README or Makefile; recording it in the repo rather than in the checker keeps the checker from rotting when a consumer reorganises.

Not proposed

Making consumers track the tip. The pins are right, and this is not an argument against them — it is an argument that the pin bump needs a gate it currently does not have.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions