epiphany/crates/epiphany-layout-ir/src
Levi Neuwirth 51f7ac9f61 Push 4b tranche 3b-ii: one SmuflVersion, and a live ordering bug dies with the homonym
Closes P13-S12. epiphany-layout-ir defined its own SmuflVersion storing the
minor LITERALLY ({1,4} for SMuFL 1.4), so derived Ord sorted 1.3 and 1.4
BEFORE 1.12 — backwards versus SMuFL's real release order — on a direct field
of GlyphCatalogIdentity, which is layout-conformance identity. That bug was
live. The crate graph fixes the direction: layout-ir depends on core, so
core's fraction-normalized minor_centi type is necessarily the survivor.
layout-ir deletes its own and re-exports core's, keeping
epiphany_layout_ir::SmuflVersion resolving for downstream at zero churn.

No wire change: no schema major, no Codec, no decode vector. LayoutCache is a
regenerable major-0 role. The one line that moves bytes is encode_catalog's
.minor -> .minor_centi (04 00 -> 28 00 at offset 2, verified by encoding a
default identity: 60 bytes, unchanged elsewhere).

The tranche also closes S12's OTHER half, which had gone unnoticed: the
ratified shape reached Rust and the binary companion but core_spec.tex never
defined SmuflVersion at all — the exact "undefined leaf" S12 was filed about.
It is now declared once, with the hundredths rule as normative prose and the
release table as a rationale note, cross-referenced from both Chapter 9 sites
so the glyph catalog's version and the tuning context's are visibly one type.
No new req: label; counts stay 212/282/282.

Two ledger claims corrected, both verified false before dispatch rather than
after: PASS13_CANDIDATES.md's S12 entry and epiphany-core/DECISIONS.md's S12
bullet both promised this move would land "with golden regen". Nothing is
pinned to the catalog identity — every ResolvedLayoutIR::canonical_bytes()
assertion is RELATIVE (stability, determinism, and a sensitivity check that
mutates metrics_hash, never smufl_version), and the committed SVG/PNG goldens
embed no identity, only a fixed comment string. There was nothing to
regenerate, and conformance gate [9] never moved.

The fix is locked by a test that names the bug: layout-ir asserts the real
release order through GlyphCatalogIdentity.smufl_version. Mutation-verified
independently by making from_decimal store one-digit minors literally — it
fails with "minor_centi: 20 did not sort before minor_centi: 3", which is
precisely the deleted type's behaviour.

Gate: fmt clean, clippy 0, 1283 passed / 0 failed (+1, the new test), doc 0,
conformance 8/8, requirement labels 6/6 at 212/282/282. No golden, vector,
baseline, or editor-track file changed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 19:30:52 -04:00
..
barrier.rs One tag vocabulary the compiler owns, and ratify the corpus in the companion 2026-07-09 20:32:35 -04:00
cache.rs Land epiphany-layout-ir (Agent E): layout IR + solver interface 2026-06-19 19:58:01 -04:00
constrained.rs P13-I2: Staff::default_clef is the fallback, not decoration 2026-07-09 14:47:42 -04:00
engrave_theory.rs layout-ir: staff_step_pitch, the clef-relative position inverse 2026-06-29 17:28:23 -04:00
engraving.rs Pushes 1+3: fix the MUST-level violations, wire the types-only machinery 2026-07-02 17:10:50 -04:00
glyph.rs Push 4b tranche 3b-ii: one SmuflVersion, and a live ordering bug dies with the homonym 2026-07-23 19:30:52 -04:00
hittest.rs Let the band model carry staff attribution instead of inferring it 2026-07-09 10:37:27 -04:00
lib.rs P13-I2: Staff::default_clef is the fallback, not decoration 2026-07-09 14:47:42 -04:00
logical.rs P13-I2: Staff::default_clef is the fallback, not decoration 2026-07-09 14:47:42 -04:00
provenance.rs Phase 3 tranche 1: casting-off, K1 schema-fill, value-restoring undo 2026-07-02 21:55:26 -04:00
quality.rs Straighten the QMC version story in the docs that assert it 2026-07-09 11:54:25 -04:00
render.rs Schema major 2 Phase E2: slur curves + cubic-bézier primitive 2026-07-08 15:33:00 -04:00
resolved.rs Push 4b tranche 3b-ii: one SmuflVersion, and a live ordering bug dies with the homonym 2026-07-23 19:30:52 -04:00
roundtrip.rs Schema major 2 Phase E2: slur curves + cubic-bézier primitive 2026-07-08 15:33:00 -04:00
solver.rs Push 4b tranche 3b-ii: one SmuflVersion, and a live ordering bug dies with the homonym 2026-07-23 19:30:52 -04:00
spatial.rs Land epiphany-layout-ir (Agent E): layout IR + solver interface 2026-06-19 19:58:01 -04:00
time_axis.rs Agent I Phase 2-3: engrave recognizable notation from Score to SVG 2026-06-26 20:46:33 -04:00
vertical_band.rs Two-sided inter-staff renegotiation, and the cascade defect it uncovered 2026-07-09 13:32:37 -04:00