You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Key.RomanNumeralOf labels the minor-key leading-tone chord as a flattened tonic: G#dim in A minor is "bi°", not "#vii°" #304
Scale.DegreeOf (Semantics.Music/Scale.cs:94-103) spells a pitch class that isn't in the scale against its nearest scale neighbours, preferring the flat spelling on a tie. When the pitch is above the scale's last offset there is no upper neighbour, so the flat candidate wraps around the octave to degree 1:
Every mode with a flat seventh has this problem: aeolian, dorian, phrygian, mixolydian, locrian, and the blues and pentatonic scales. Semitone 11 is one semitone from both neighbours, so it comes out as degree 1 with alteration −1, a flattened tonic.
Harmonic analysis never reads that pitch as a flattened tonic. It is the raised seventh, the leading tone, and the most common chromatic note in minor-key harmony.
So the minor progression i – iv – vii°7 – i is labelled i, iv, bi°, i. ChordFromRomanNumeral accepts #vii°, which means the output of RomanNumeralOf and the input ChordFromRomanNumeral expects disagree.
Suggested fix
In DegreeOf, when the flat candidate reaches degree 1 only by wrapping (upperIndex < 0), use the sharp spelling of the last degree instead. The flat-preferring tie-break stays as it is everywhere else, so major-key bII, bIII, bVI and bVII are unchanged.
Priority: Medium. Every flat-seventh mode mislabels the most common chromatic chord in minor-key harmony, and RomanNumeralOf output doesn't round-trip through ChordFromRomanNumeral. The results are wrong, but nothing crashes.
Area / suggested assignee:Semantics.Music (Scale.DegreeOf). @matt-edmondson.
Notes: The fix is small: take the sharp spelling of the last degree only when the flat candidate wraps to degree 1. The existing tie-break test guards the major-key cases.
Activity
matt-edmondson commentedon Sep 28, 2026
Triage
RomanNumeralOfoutput doesn't round-trip throughChordFromRomanNumeral. The results are wrong, but nothing crashes.Semantics.Music(Scale.DegreeOf). @matt-edmondson.Generated by Claude Code
[patch] Spell the raised seventh above a flat seventh as ktsu-dev#7, …