Skip to content

fix: do not absorb the main chord into a preceding grace-note chord#346

Merged
webern merged 1 commit into
mainfrom
claude/grace-chord-boundary
Jul 12, 2026
Merged

fix: do not absorb the main chord into a preceding grace-note chord#346
webern merged 1 commit into
mainfrom
claude/grace-chord-boundary

Conversation

@webern

@webern webern commented Jul 12, 2026

Copy link
Copy Markdown
Owner

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

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

References

@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% 7233 / 8568
Functions 74.9% 2512 / 3353
Branches 52.3% 6302 / 12048

Core HTML report | API HTML report

Commit f63f4ffc43348a795ab4cee065066d00f9cc6d20.

@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 f63f4ffc43348a795ab4cee065066d00f9cc6d20.

@webern webern force-pushed the claude/metronome-parentheses branch from 4c44177 to 302bca3 Compare July 12, 2026 20:31
@webern webern force-pushed the claude/grace-chord-boundary branch from 2989c24 to de0d806 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% 7247 / 8570
Functions 74.9% 2512 / 3353
Branches 52.4% 6316 / 12052

Core HTML report | API HTML report

Commit 2a3d559e0cf3ddf2d6cb9feb8656ed06a93927c0.

@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 2a3d559e0cf3ddf2d6cb9feb8656ed06a93927c0.

Base automatically changed from claude/metronome-parentheses to main July 12, 2026 21:56
Grace notes occupy no ticks, so a grace-note chord shares its tick
position with the chord it ornaments; the writer's tick-only chord
boundary detection stamped a spurious <chord/> on the main chord's
first note. A grace/non-grace transition is now also a chord boundary.

Pins the 2 corpus files this flips to PASS (224 total).
@webern webern force-pushed the claude/grace-chord-boundary branch from de0d806 to 541a835 Compare July 12, 2026 22:23
@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% 7247 / 8570
Functions 74.9% 2512 / 3353
Branches 52.4% 6316 / 12052

Core HTML report | API HTML report

Commit 3725731bd7af63c9ca08ff2520d905641f08fa8e.

@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 3725731bd7af63c9ca08ff2520d905641f08fa8e.

@webern webern merged commit 5b595df into main Jul 12, 2026
10 checks passed
@webern webern deleted the claude/grace-chord-boundary branch July 12, 2026 22:38
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: writer absorbs the main chord into a preceding grace-note chord at the same tick

1 participant