fix: Julia 1.12 CI floor ([sources] needs Pkg 1.11+); idempotent canonicalize_presentation#76
Merged
Merged
Conversation
The krl-tests job installed Julia 1.10, but server/Project.toml resolves its unregistered siblings (KnotTheory/Skein/AcceleratorGate) through a [sources] table — a Pkg 1.11+ feature that 1.10 silently ignores, so Pkg.instantiate fell back to a registry lookup and failed with 'expected package KnotTheory [215268c9] to be registered' (observed on this PR's first CI run). Local verification ran on 1.12.6; pin CI to the 1.12 channel to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cle minimum The old single relabelling pass was not idempotent: BFS relabelling from the canonical-pass ordering can itself change the ordering, so blob(canonicalize(p)) != blob(canonicalize(canonicalize(p))) — measured at 95/200 seeded BR-5 trials once the upstream KnotTheory.jl PD-integrity bugs (braid strand-swap, r2_simplify re-splice) were fixed and the harness could see it. Fix: iterate the pass, detecting the inevitable cycle of serialised states, and return the lexicographically minimal state on the cycle. That choice is a fixed point (canonicalising it lands back on it) and is reached from every presentation in the same orbit. Where the old pass was already stable — every presentation in the shipped test corpus — the result is unchanged, so stored fingerprints remain valid. Also factors _presentation_serial out of canonical_presentation_blob so the cycle detector and the blob share one serialisation. Validated: BR-5 fuzz, 200 trials against fixed KnotTheory.jl — 8752 assertions pass, 0 hard failures, 1 expected Broken (11/200 quandle_key residual, upstream KnotTheory.jl#42). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
hyperpolymath
marked this pull request as ready for review
July 21, 2026 13:06
## Summary Removes the `@test_broken` marker on the R2-invariance 5-colouring assertion in `server/test_quandle_axioms.jl`, restoring the plain hard `@test`. The marker tracked an upstream defect: `r2_simplify` in KnotTheory.jl removed a bigon without re-splicing the severed arcs, so the trefoil's extracted presentation gained 2 phantom generators and its 5-colouring count came out 25 instead of 5. That is fixed in **hyperpolymath/KnotTheory.jl#43** (union-find arc re-splice + the braid strand-swap fix underneath it). ## Merge order — do not merge early 1. quandledb #76 (CI Julia 1.12 floor + idempotent canonicalisation) 2. **KnotTheory.jl#43** ← this PR's CI checks out that repo's *default branch*, so until #43 merges the restored hard assertion fails here (red is expected and correct) 3. this PR The `@test_broken` mechanism makes step 3 mandatory rather than optional: once #43 merges, the marker reports "unexpected pass" — a hard error — in #76's follow-up CI runs, and this PR is the remedy. ## Verification With the #43 fix applied locally (Julia 1.12.6, 200-trial BR-5 corpus): the axioms suite passes fully with the hard assertion restored; the only remaining Broken mark in the repo is the BR-5 `quandle_key` order-sensitivity counter (11/200 residual, upstream KnotTheory.jl#42 — polynomial unit normalisation, deliberately kept). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two follow-ups to #72 (squash-merged as 28505a5 with its first CI run still red):
1. CI: the new Julia job needs Julia ≥ 1.11
The
krl-testsjob added in #72 installed Julia 1.10, butserver/Project.tomlresolves its unregistered sibling deps (KnotTheory.jl/Skein.jl/AcceleratorGate.jl) through a[sources]table — a Pkg 1.11+ feature that 1.10 silently ignores.Pkg.instantiatetherefore fell back to a registry lookup and died withexpected package KnotTheory [215268c9] to be registered(observed on #72's CI run). Local verification had run on 1.12.6, which is why it passed there. CI now pins the 1.12 juliaup channel, with a comment explaining the floor.2.
canonicalize_presentationwas not idempotentThe single BFS-relabelling pass can change the very ordering it derived labels from, so
blob(canonicalize(p)) ≠ blob(canonicalize(canonicalize(p)))— measured at 95/200 seeded BR-5 trials once the upstream KnotTheory.jl PD-integrity bugs (hyperpolymath/KnotTheory.jl#43) were fixed and the harness could see real diagrams. A fingerprint that changes when you canonicalise twice cannot serve as a semantic identity.Fix: iterate the pass, detect the inevitable cycle of serialised states, and return the lexicographically minimal state on the cycle — a fixed point reached from every presentation in its orbit. Where the old pass was already stable (the entire shipped test corpus), output is unchanged, so stored fingerprints remain valid.
Verification
BR-5 fuzz, 200 trials, against KnotTheory.jl with the #43 fixes applied:
quandle_keyresidual → upstream KnotTheory.jl#42)Merge order
This PR is independent of KnotTheory.jl#43 (it validates against both old and fixed KnotTheory — the idempotency fix only touches quandledb's own layer). Once #43 merges upstream, the
@test_brokenR2 marker intest_quandle_axioms.jlflips to "unexpected pass" by design; a marker-removal PR follows then.🤖 Generated with Claude Code