Commit 0c2d9ba
fix: Julia 1.12 CI floor ([sources] needs Pkg 1.11+); idempotent canonicalize_presentation (#76)
## 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-tests` job added in #72 installed Julia **1.10**, but
`server/Project.toml` resolves 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.instantiate` therefore fell back to a registry lookup and died with
`expected 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_presentation` was not idempotent
The 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:
| Suite | Result |
|---|---|
| presentation well-formedness | 6752/6752 pass |
| descriptor determinism | 800/800 pass |
| crossing-order invariance | 600 pass + 1 expected Broken (11/200
`quandle_key` residual → upstream KnotTheory.jl#42) |
| canonical-blob round-trip (incl. idempotency) | 600/600 pass — was
95/200 failing before the fix |
## 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_broken` R2 marker in
`test_quandle_axioms.jl` flips to "unexpected pass" by design; a
marker-removal PR follows then.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 75480e8 commit 0c2d9ba
3 files changed
Lines changed: 53 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
42 | 45 | | |
43 | 46 | | |
44 | 47 | | |
45 | | - | |
| 48 | + | |
46 | 49 | | |
47 | 50 | | |
48 | 51 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
142 | 142 | | |
143 | 143 | | |
144 | 144 | | |
145 | | - | |
| 145 | + | |
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
| |||
172 | 172 | | |
173 | 173 | | |
174 | 174 | | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
175 | 220 | | |
176 | 221 | | |
177 | 222 | | |
| |||
184 | 229 | | |
185 | 230 | | |
186 | 231 | | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
| 232 | + | |
194 | 233 | | |
195 | 234 | | |
196 | 235 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
209 | 209 | | |
210 | 210 | | |
211 | 211 | | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
| 212 | + | |
218 | 213 | | |
219 | 214 | | |
220 | 215 | | |
| |||
0 commit comments