fix: narrow an oversized octave shift to the closest ottava line - #423
Open
webern wants to merge 2 commits into
Conversation
MusicXML lets octave-shift/@SiZe be any positive integer, and three corpus files use that room for a number that names no line a performer could read: 27, 11 and 1. mx::api narrows each to the nearest ottava it can draw, so the round-trip saw a 27 go in and a 15 come out. The narrowing is the behavior we want. mx::api models the six ottava lines music notation has, and everything downstream is allowed to assume an ottava is one of them. So the harness brings the expected document to the size mx::api writes, the way it already adds mx's attribution stamp to the expected side rather than stripping it from the output. Only the expected side is narrowed, so a write that produced a size other than 8, 15 or 22 still fails. Two api tests state the narrowing on its own, away from the corpus. Pins the three files in the api round-trip baseline.
webern
force-pushed
the
claude/mx-api-roundtrip-corpus-9pkrg6-06-octave-shift-size
branch
from
August 23, 2026 19:29
c04b36d to
d3d8b60
Compare
The size narrowing matched 22 exactly, so a source asking for 27 fell through to the 15th line even though the 22nd was both available and closer to what it asked for. Match 22 and up instead. lysuite/ly33e_Spanners_OctaveShifts_InvalidSize.xml states size 27, and now round-trips as 22 rather than 15. The round-trip harness narrows the expected document by the same rule.
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.
Human Summary
Some corpus files existed with bad octave-shift size values.
lysuite/ly33e_Spanners_OctaveShifts_InvalidSize.xmlwas apparently created for this purpose.synthetic/octave-shift.3.0.xmlandsynthetic/octave-shift.3.1.xmlwere created by an LLM that might not have known better (just going off of the schema).Either way, the right thing to do is to test the expected behavior of
mxwhich is to coerce these to the next lower, valid, values of 22, 15 or 8.Summary
MusicXML lets
octave-shift/@sizebe any positive integer, and three corpus files use that room for a number that names no line a performer could read: 27, 11 and 1 (lysuite/ly33e_Spanners_OctaveShifts_InvalidSize.xmlis named for it).mx::apinarrows each of those to an ottava it can draw, so the round-trip saw a 27 go in and a different number come out.Narrowing is the behavior we want —
mx::apimodels the six ottava lines music notation has, and everything downstream is allowed to assume an ottava is one of them. Two changes, one to the rule and one to the round-trip.The rule now picks the closest line.
DirectionReader::parseOctaveShiftmatched 22 exactly, so a source asking for 27 fell through to the 15th line even though the 22nd was both available and closer to what it asked for. It matches 22 and up instead. Sizes of exactly 8, 15 and 22 are unaffected, so this only moves sources that were already asking for something notation has no name for.The round-trip expects the narrowed size.
narrowOctaveShiftSizes()inCorpusRoundtripMain.cpprewritesoctave-shift/@sizeon the expected document by that same rule, rather than the api learning to echo the original number back out. That is the move the harness already makes for mx's attribution stamp: add it to the expected side instead of stripping it from the output.OttavaStopSizeContradictionIsNormalizedToTheStartcovers from the api side.OttavaStart::writeDefaultSizeandOttavaStop::writeSizefrom feat: derive octave-shift stop size from its start #415 — so only the value ever differed. No public api change.Round-trip corpus
Adds 3 files to
roundtrip-baseline.txt(407 -> 410).value:octave-shift@sizewas the sixth entry on the classifier worklist.Testing
Three new
OttavaSizeApiTestcases state the narrowing away from the corpus: a size between the lines taking the 15th, a size past the 22nd taking the 22nd, and a size below 8 becoming a plain octave line.The gates below were run against the first commit. The second commit (the
>= 22rule) landed after, at the author's direction, and is covered by CI on this PR.make api-test(6348 assertions in 588 test cases)make api-roundtrip(410 passed, 0 failed of 410 pinned)make api-roundtrip-discover: the PASS set is exactly the 410 pinned files — the 3 new passes and no regressionsmake core-roundtrip-test(839 test cases) andmake core-unit(221 assertions in 44 test cases)make fmtandmake fmt-checkReferences