Skip to content

ChromaticChords reports a minor key's own dominant (E / E7 in A minor) as "borrowed from parallel major" #337

Description

@matt-edmondson

What's wrong

In a minor (aeolian) key, V and V7 use the raised leading tone (G# in A minor), so they fail the diatonic check. ClassifyChromatic in Semantics.Music/Progression.Chromatic.cs then goes through these branches:

  • The secondary-dominant branch (:48-58) skips the chord because its target is Degree == 1.
  • The Neapolitan check doesn't match.
  • The borrowed-chord fallback (:68-73) finds every tone in A major, so the chord is labelled BorrowedChord "from parallel major".

Reproduced against HEAD 9c64b67:

var key = Key.Parse("A aeolian");
Progression.Parse("4/4  Am | Dm | E7 | Am").ChromaticChords(key);
// => [ (index 2, BorrowedChord, "from parallel major") ]
Progression.Parse("4/4  Am | E | Am").ChromaticChords(key);
// => same

On the same progression the other analyses agree with each other and disagree with this one:

  • RomanNumerals gives i iv V7 i.
  • Functions gives Dominant for the E7.
  • Cadences reports an authentic cadence.

Why it matters

V/V7 is the most common "chromatic" chord in minor-key harmony, and it is treated as part of the key everywhere else in the library. InferKey only returns major or aeolian keys, so every inferred minor key mislabels its dominant. Consumers that highlight borrowed chords will flag almost every minor-key cadence.

Suggested fix

For a minor-family key, treat a major triad or dominant seventh on scale degree 5 as the harmonic-minor V. Either accept it in IsDiatonic, or return early (not chromatic) before the borrowed-chord fallback. This is related to, but separate from, #304 (the leading-tone chord numeral) and #301 (secondary-dominant numerals in non-major modes).

Acceptance criteria

  • ChromaticChords(A aeolian) returns nothing for Am | Dm | E7 | Am or Am | E | Am.
  • Fm in C major is still reported as "borrowed from parallel minor".
  • D7 in C major is still reported as V/V.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions