Skip to content

fix: carry a dotted note's dots into a guessed tuplet-normal - #458

Merged
webern merged 1 commit into
mainfrom
m/mxdev-tupdots
Sep 19, 2026
Merged

webern merged 1 commit into
mainfrom
m/mxdev-tupdots

Conversation

@webern

@webern webern commented Sep 19, 2026 •

Copy link
Copy Markdown
Owner

Human Summary

A bug with automatic tuplet note duration detection, both found and fixed by AI.

Summary

When a <tuplet> says nothing about its normal side, TupletReader::guessNormalFromNote
reconstructs that side from the note's <time-modification>. If the <time-modification> names a
normal-type, the duration and dots come from the normal-type/normal-dot group. When it does
not, the reader already took the duration from the note's own <type> but left normalDots
unspecified.

Per the schema, an absent normal-type means the normal notes are the note's own written figure,
dots included, so a dotted note in such a tuplet read as an undotted normal figure and was written
back as a <tuplet-normal> with no <tuplet-dot/>.

The fallback now takes the dot count from the note's own <dot> elements, the way the actual side
already does (the same fix as #449, on the other side of the ratio). A note with no dots now guesses
zero dots rather than the unspecified sentinel, so a second round trip reads the same value. An
explicit normal-type group still wins. Nothing about the api's shape or vocabulary changes; only
what the reader records, so this is non-breaking.

Testing

  • New reader tests fail before the change, pass after: with the fix reverted, 4 of the 5 new
    cases fail with normalDots reported as -1
  • make fmt and make fmt-check pass
  • make api-test: all tests pass (5898 assertions in 662 test cases)
  • make api-roundtrip: 414 passed, 0 failed (of 414 pinned)
  • make api-roundtrip-discover: 414 PASS, 426 FAIL; no file unlocked by this change, so
    nothing was added to the baseline
  • make test-all: core round trip passes (841 test cases), core unit passes (603 assertions in
    69 test cases), plus the api suites above

The tests added are a single-dot case, a double-dotted case proving the count rather than the
presence of one dot, a guard that an explicit normal-type/normal-dot group is not overwritten, a
zero-dot case, and an end-to-end test that reads a dotted note in a normal-type-less tuplet,
writes it, and checks the written <tuplet-normal> carries a <tuplet-dot/>.

References

@webern webern added bug software defect non-breaking fixes or implementation that do not require breaking changes impl Affects the mx::impl layer ai Issues opened by, or through, a coding agent. labels Sep 19, 2026
@webern
webern merged commit 7a9d253 into main Sep 19, 2026
8 checks passed
@webern
webern deleted the m/mxdev-tupdots branch September 19, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai Issues opened by, or through, a coding agent. bug software defect impl Affects the mx::impl layer non-breaking fixes or implementation that do not require breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

guessed tuplet-normal drops the note's dots

1 participant