Skip to content

fix: round-trip the metronome parentheses attribute#344

Merged
webern merged 1 commit into
mainfrom
claude/metronome-parentheses
Jul 12, 2026
Merged

fix: round-trip the metronome parentheses attribute#344
webern merged 1 commit into
mainfrom
claude/metronome-parentheses

Conversation

@webern

@webern webern commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Human Summary

Looks like a bug fix where we purported to support the metronome parenthesis attribute, but dropped it. Simple fix.

Summary

<metronome parentheses="yes"> lost its parentheses on an api round-trip. The api model
already had the field — TempoData::isParenthetical — but it dangled: MetronomeReader
never set it and DirectionWriter never emitted it. This wires both sides: the reader maps
core::Metronome::parentheses() into the Bool, and the writer emits the attribute when the
field is not unspecified. No api surface change.

Stacked on #342 to keep the roundtrip-baseline.txt additions conflict-free; the 2 files
this flips are pinned (220 -> 222).

Testing

  • New roundTripParentheses MetronomeApi test (fails before, passes after)
  • Full mxtest suite passes (4951 assertions in 421 test cases)
  • Discovery: 222 PASS, zero regressions; regression mode: 222/222

References


Generated by Claude Code

@github-actions

Copy link
Copy Markdown

Coverage report

Core-dev coverage src/private/mx/core/

Metric Coverage Covered / Total
Lines 77.8% 28514 / 36648
Functions 74.2% 6352 / 8556
Branches 50.7% 22680 / 44751

API coverage src/private/mx/{api,impl,utility}/

Metric Coverage Covered / Total
Lines 84.4% 7229 / 8564
Functions 74.9% 2512 / 3353
Branches 52.3% 6300 / 12046

Core HTML report | API HTML report

Commit 5f502273614b0122ba0751336b75774b3196b83f.

@github-actions

Copy link
Copy Markdown

gen-quality gen/

gen-quality: 84.5 / 100   (floor 84.5, +0.0)

  structure     86.5  x0.50   [fn 90.5 / file 82.6]
  cyclomatic    88.4  x0.25
  cognitive     76.6  x0.25

  409 functions across 31 files, 7702 lines (largest file 1044)
  max cc 56  max cognitive 44  max fn loc 152

Worst offenders (top 5 per axis; full lists in score.json):
  cyclomatic gen/xsd/analyze.py:311     report                             56
  cyclomatic gen/plates/build.py:956    _validate_config_against_ir        35
  cyclomatic gen/press/context.py:145   plate_context                      34
  cyclomatic gen/__main__.py:46         _ir                                23
  cyclomatic gen/tests/test_ir.py:102   _check_references                  20
  cognitive  gen/xsd/analyze.py:311     report                             44
  cognitive  gen/ir/resolve.py:119      flat_elements                      40
  cognitive  gen/tests/test_ir.py:102   _check_references                  38
  cognitive  gen/press/context.py:145   plate_context                      37
  cognitive  gen/xsd/analyze.py:207     _sccs                              37
  size       gen/xsd/analyze.py:311     report                             152
  size       gen/press/context.py:145   plate_context                      96
  size       gen/plates/build.py:533    _value_plate                       89
  size       gen/plates/build.py:956    _validate_config_against_ir        89
  size       gen/ir/resolve.py:119      flat_elements                      78

Commit 5f502273614b0122ba0751336b75774b3196b83f.

Base automatically changed from claude/caesura-value to main July 12, 2026 19:45
TempoData::isParenthetical existed but dangled: the reader never set it
and the writer never emitted it. Wire both sides.

Pins the 2 corpus files this flips to PASS (222 total).
@webern webern force-pushed the claude/metronome-parentheses branch from 4c44177 to 302bca3 Compare July 12, 2026 20:31
@github-actions

Copy link
Copy Markdown

Coverage report

Core-dev coverage src/private/mx/core/

Metric Coverage Covered / Total
Lines 77.8% 28514 / 36648
Functions 74.2% 6352 / 8556
Branches 50.7% 22680 / 44751

API coverage src/private/mx/{api,impl,utility}/

Metric Coverage Covered / Total
Lines 84.6% 7243 / 8566
Functions 74.9% 2512 / 3353
Branches 52.4% 6314 / 12050

Core HTML report | API HTML report

Commit 9961fb2812f3ff37c7a6d76bf25d90cd2351b5ac.

@github-actions

Copy link
Copy Markdown

gen-quality gen/

gen-quality: 84.5 / 100   (floor 84.5, +0.0)

  structure     86.5  x0.50   [fn 90.5 / file 82.6]
  cyclomatic    88.4  x0.25
  cognitive     76.6  x0.25

  409 functions across 31 files, 7702 lines (largest file 1044)
  max cc 56  max cognitive 44  max fn loc 152

Worst offenders (top 5 per axis; full lists in score.json):
  cyclomatic gen/xsd/analyze.py:311     report                             56
  cyclomatic gen/plates/build.py:956    _validate_config_against_ir        35
  cyclomatic gen/press/context.py:145   plate_context                      34
  cyclomatic gen/__main__.py:46         _ir                                23
  cyclomatic gen/tests/test_ir.py:102   _check_references                  20
  cognitive  gen/xsd/analyze.py:311     report                             44
  cognitive  gen/ir/resolve.py:119      flat_elements                      40
  cognitive  gen/tests/test_ir.py:102   _check_references                  38
  cognitive  gen/press/context.py:145   plate_context                      37
  cognitive  gen/xsd/analyze.py:207     _sccs                              37
  size       gen/xsd/analyze.py:311     report                             152
  size       gen/press/context.py:145   plate_context                      96
  size       gen/plates/build.py:533    _value_plate                       89
  size       gen/plates/build.py:956    _validate_config_against_ir        89
  size       gen/ir/resolve.py:119      flat_elements                      78

Commit 9961fb2812f3ff37c7a6d76bf25d90cd2351b5ac.

@webern webern merged commit 9a015a3 into main Jul 12, 2026
10 checks passed
@webern webern deleted the claude/metronome-parentheses branch July 12, 2026 21:56
webern added a commit that referenced this pull request Jul 12, 2026
…346)

## Human Summary

Bug fix related to grace notes not advancing the tick time position.

## Summary

Grace notes occupy no ticks (#318), so a grace-note chord shares its
`tickTimePosition` with
the chord it ornaments. `MeasureWriter`'s chord-boundary detection
compared tick positions
only, so the first note of the main chord was treated as a continuation
of the grace chord
and got a spurious `<chord/>` tag — musically corrupting the output by
merging the real
chord into the zero-duration grace chord.

The fix tracks whether the previous chord note was a grace note: a
grace/non-grace
transition at the same tick is also a chord boundary.

Stacked on #344 to keep the `roundtrip-baseline.txt` additions
conflict-free; the 2 files
this flips are pinned (222 -> 224).

## Testing

- [x] New `GraceChordThenChordAtSameTick` MeasureWriter test (fails
before, passes after)
- [x] Full mxtest suite passes
- [x] Discovery: 224 PASS, zero regressions; regression mode: 224/224

## References

- Closes #345
- Stacked on #344; related to #318; part of #208
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

api: metronome parentheses attribute is dropped despite TempoData::isParenthetical existing

1 participant