Skip to content

feat: expose the identification source in mx::api - #419

Merged
webern merged 3 commits into
mainfrom
claude/mx-api-roundtrip-corpus-9pkrg6-02-identification-source
Aug 23, 2026
Merged

feat: expose the identification source in mx::api#419
webern merged 3 commits into
mainfrom
claude/mx-api-roundtrip-corpus-9pkrg6-02-identification-source

Conversation

@webern

@webern webern commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Human Summary

Add support to mx::api for the <source> element. Seen in some corpus files.

Summary

<identification>/<source> names the edition, manuscript, or other publication a score was made from. mx::api had nowhere to keep it, so the reader discarded it and every write dropped the element.

ScoreData gains std::optional<std::string> source, read from and written to <identification>.

Optional rather than a plain string like its copyright neighbor: <source></source> is legal MusicXML and says the score named a source and left it blank, which is a different fact from saying nothing at all. A plain string would collapse the two.

Non-breaking: one new optional field.

Round-trip corpus

Adds 5 files to roundtrip-baseline.txt (394 -> 399). drop:source was the second entry on the classifier worklist, blocking these five on its own.

Testing

  • New IdentificationSourceApiTest covers the round trip, the written element, the empty default, and the blank-but-present case (*IdentificationSource*: 7 assertions in 4 test cases)
  • make api-test (6297 assertions in 577 test cases)
  • make api-roundtrip (399 passed, 0 failed of 399 pinned)
  • make api-roundtrip-discover reports exactly the 5 new passes and no regressions
  • make fmt

References

webern added 2 commits August 23, 2026 16:09
MusicXML lets a <note> carry its own playback velocity in the dynamics and
end-dynamics attributes, the MIDI Note On and Note Off velocities expressed as
percentages of the default forte level. The api had no home for either, so the
reader dropped them and an author could not state them.

NoteData gains velocityStart and velocityStop. Both are optional doubles that
default to empty, so a note that says nothing about playback still writes no
attribute. The names avoid "dynamics", which in the api already means the
printed marking (a MarkData in noteAttachmentData) rather than how hard the
note is played.

Pins the thirteen foundsuite Inventions in the api round-trip baseline. Each
one carried a per-note velocity that was the only thing it lost on write.
MusicXML's <identification>/<source> names the edition, manuscript, or other
publication a score was made from. The api had nowhere to keep it, so the
reader discarded it and every write dropped the element.

ScoreData gains an optional source string. Optional rather than a plain string
because <source></source> is legal and means something different from saying
nothing at all.

Pins five more files in the api round-trip baseline whose only divergence was
the dropped element.
@webern webern added feature new feature request non-breaking fixes or implementation that do not require breaking changes api Affects the mx::api layer impl Affects the mx::impl layer ai Issues opened by, or through, a coding agent. labels Aug 23, 2026 — with Claude
Base automatically changed from claude/mx-api-roundtrip-corpus-9pkrg6-01-note-velocity to main August 23, 2026 18:49
…ntification-source

Signed-off-by: Matthew James Briggs <matthew.james.briggs@gmail.com>
@webern
webern merged commit ac6913e into main Aug 23, 2026
3 of 8 checks passed
@webern
webern deleted the claude/mx-api-roundtrip-corpus-9pkrg6-02-identification-source branch August 23, 2026 18:51
webern added a commit that referenced this pull request Aug 23, 2026
## Human Summary

Adds support for `directive`.

## Summary

`<direction directive="yes">` aligns a direction with the measure's time
signature rather than with the note it is anchored to. That is how a
tempo or style marking at the head of a movement is usually placed. The
api had no field for it, so the reader discarded it and the attribute
was dropped on write.

`DirectionData` gains `Bool directive`, following the api's tri-state
convention: `unspecified` does not write an attribute, `yes` and `no`
are written verbatim.

`<harmony>` does not carry `directive` even though it shares `placement`
and `system` with `<direction>`, so the reader only looks for it on
`<direction>`.

Non-breaking: one new field defaulting to `unspecified`.

## Round-trip corpus

Adds 3 files to `roundtrip-baseline.txt` (399 -> 402).
`attr:direction@directive` was the third entry on the classifier
worklist.

## Testing

- [x] Two new `DirectionWriter` impl tests: the api -> core -> api round
trip of `yes`, and that `unspecified` leaves the attribute off entirely
(`*directive*`: 9 assertions in 2 test cases)
- [x] `make api-test` (6306 assertions in 579 test cases)
- [x] `make api-roundtrip` (402 passed, 0 failed of 402 pinned)
- [x] `make api-roundtrip-discover` reports exactly the 3 new passes and
no regressions
- [x] `make fmt`

## References

- Progresses the round-trip corpus work tracked in #208
- Stacked on #419, which is stacked on #417. The base branch is #419's
branch, so this diff shows only the directive change.

---------

Signed-off-by: Matthew James Briggs <matthew.james.briggs@gmail.com>
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. api Affects the mx::api layer feature new feature request 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.

1 participant