From 5b4872e8ddbb266b03c0abf94c014a416c9234ab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:30:24 +0000 Subject: [PATCH 1/4] Initial plan From 2690c10fe85d890b9c7b491e4537f3e7c09540e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:41:09 +0000 Subject: [PATCH 2/4] Add DominantFlat9Sharp5 chord type with scale suggestions Co-authored-by: twitchax <549523+twitchax@users.noreply.github.com> --- kord/src/core/chord.rs | 7 ++++- kord/src/core/known_chord.rs | 56 ++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/kord/src/core/chord.rs b/kord/src/core/chord.rs index 3cb46cc..0939ab1 100644 --- a/kord/src/core/chord.rs +++ b/kord/src/core/chord.rs @@ -520,7 +520,7 @@ impl HasName for Chord { name.push_str("(♭5)"); } - if self.modifiers.contains(&Modifier::Augmented5) && !known_name.contains('+') { + if self.modifiers.contains(&Modifier::Augmented5) && !known_name.contains('+') && !known_name.contains("(♯5)") { name.push_str("(♯5)"); } @@ -948,6 +948,10 @@ impl HasKnownChord for Chord { } if contains_dominant { + if modifiers.contains(&Modifier::Flat9) { + return KnownChord::DominantFlat9Sharp5(degree); + } + return KnownChord::AugmentedDominant(degree); } @@ -1490,6 +1494,7 @@ mod tests { assert_eq!(Chord::new(C).seven().sharp11().known_chord(), KnownChord::DominantSharp11(Degree::Seven)); assert_eq!(Chord::new(C).seven().flat9().known_chord(), KnownChord::DominantFlat9(Degree::Seven)); assert_eq!(Chord::new(C).seven().sharp9().known_chord(), KnownChord::DominantSharp9(Degree::Seven)); + assert_eq!(Chord::new(C).seven().flat9().augmented().known_chord(), KnownChord::DominantFlat9Sharp5(Degree::Seven)); assert_eq!(Chord::new(C).sus2().known_chord(), KnownChord::Major); assert_eq!(Chord::new(C).sus4().known_chord(), KnownChord::Major); diff --git a/kord/src/core/known_chord.rs b/kord/src/core/known_chord.rs index 87ebc3b..96d776f 100644 --- a/kord/src/core/known_chord.rs +++ b/kord/src/core/known_chord.rs @@ -187,6 +187,8 @@ pub enum KnownChord { DominantFlat9(Degree), /// A dominant sharp 9 chord. DominantSharp9(Degree), + /// A dominant flat 9 sharp 5 chord. + DominantFlat9Sharp5(Degree), /// A minor dominant flat 13 chord. MinorDominantFlat13(Degree), /// A minor dominant flat 9 flat 13 chord. @@ -215,6 +217,7 @@ impl HasDescription for KnownChord { KnownChord::Diminished => "diminished", KnownChord::DominantFlat9(_) => "dominant flat 9", KnownChord::DominantSharp9(_) => "dominant sharp 9", + KnownChord::DominantFlat9Sharp5(_) => "dominant flat 9 sharp 5", KnownChord::MinorDominantFlat13(_) => "minor dominant flat 13", KnownChord::MinorDominantFlat9Flat13(_) => "minor dominant flat 9 flat 13", KnownChord::Sharp11 => "sharp 11", @@ -353,6 +356,15 @@ impl HasRelativeScale for KnownChord { Interval::MinorSixth, Interval::MinorSeventh, ], + KnownChord::DominantFlat9Sharp5(_) => vec![ + Interval::PerfectUnison, + Interval::MinorSecond, + Interval::MinorThird, + Interval::MajorThird, + Interval::AugmentedFourth, + Interval::MinorSixth, + Interval::MinorSeventh, + ], KnownChord::MinorDominantFlat13(_) => vec![ Interval::PerfectUnison, Interval::MajorSecond, @@ -408,6 +420,7 @@ impl HasRelativeChord for KnownChord { KnownChord::Diminished => vec![Interval::PerfectUnison, Interval::MinorThird, Interval::DiminishedFifth, Interval::DiminishedSeventh], KnownChord::DominantFlat9(_) => vec![Interval::PerfectUnison, Interval::MajorThird, Interval::PerfectFifth, Interval::MinorSeventh, Interval::MinorNinth], KnownChord::DominantSharp9(_) => vec![Interval::PerfectUnison, Interval::MajorThird, Interval::PerfectFifth, Interval::MinorSeventh, Interval::AugmentedNinth], + KnownChord::DominantFlat9Sharp5(_) => vec![Interval::PerfectUnison, Interval::MajorThird, Interval::AugmentedFifth, Interval::MinorSeventh, Interval::MinorNinth], KnownChord::MinorDominantFlat13(_) => vec![Interval::PerfectUnison, Interval::MinorThird, Interval::PerfectFifth, Interval::MinorSeventh, Interval::MinorThirteenth], KnownChord::MinorDominantFlat9Flat13(_) => vec![ Interval::PerfectUnison, @@ -446,6 +459,7 @@ impl HasName for KnownChord { KnownChord::Diminished => "dim".to_owned(), KnownChord::DominantFlat9(d) => format!("{}(♭9)", d.static_name()), KnownChord::DominantSharp9(d) => format!("{}(♯9)", d.static_name()), + KnownChord::DominantFlat9Sharp5(d) => format!("{}(♭9)(♯5)", d.static_name()), KnownChord::MinorDominantFlat13(d) => format!("m{}(♭13)", d.static_name()), KnownChord::MinorDominantFlat9Flat13(d) => format!("{}(♭9)(♭13)", d.static_name()), KnownChord::Sharp11 => "(♯11)".to_owned(), @@ -472,6 +486,7 @@ impl KnownChord { KnownChord::Diminished => DIMINISHED_CANDIDATES, KnownChord::DominantFlat9(_) => DOMINANT_FLAT9_CANDIDATES, KnownChord::DominantSharp9(_) => DOMINANT_SHARP9_CANDIDATES, + KnownChord::DominantFlat9Sharp5(_) => DOMINANT_FLAT9_SHARP5_CANDIDATES, KnownChord::MinorDominantFlat13(_) => MINOR_DOMINANT_FLAT13_CANDIDATES, KnownChord::MinorDominantFlat9Flat13(_) => MINOR_DOMINANT_FLAT9_FLAT13_CANDIDATES, KnownChord::Sharp11 => SHARP11_CANDIDATES, @@ -772,6 +787,24 @@ static DOMINANT_SHARP9_CANDIDATES: &[IntervalCandidate] = &[ }, ]; +static DOMINANT_FLAT9_SHARP5_CANDIDATES: &[IntervalCandidate] = &[ + IntervalCandidate { + kind: IntervalCollectionKind::Mode(ModeKind::Altered), + rank: 1, + reason: "Primary scale for V7(♭9)(♯5) chords; the altered dominant scale (7th mode of melodic minor) provides all necessary alterations including ♭9, ♯5/♭13, and ♭5; maximum tension with both flat 9 and sharp 5 present; creates the strongest resolution pull in modern jazz and chromatic harmony", + }, + IntervalCandidate { + kind: IntervalCollectionKind::Scale(ScaleKind::DiminishedHalfWhole), + rank: 2, + reason: "Symmetrical half-whole diminished (dominant diminished) that supports V7(♭9)(♯5); provides ♭9, ♯9, ♯11, and 13 simultaneously; rich dominant tension palette; works well when you need the ♭9 with option to imply or approach the ♯5", + }, + IntervalCandidate { + kind: IntervalCollectionKind::Mode(ModeKind::PhrygianDominant), + rank: 3, + reason: "Spanish or Phrygian dominant sound (5th mode of harmonic minor) emphasizing the characteristic ♭9; exotic, Middle Eastern, or Flamenco flavor; while it has natural 5th, it can approach or bend toward ♯5 in phrasing; strong V in minor keys", + }, +]; + static MINOR_DOMINANT_FLAT13_CANDIDATES: &[IntervalCandidate] = &[ IntervalCandidate { kind: IntervalCollectionKind::Mode(ModeKind::Aeolian), @@ -899,6 +932,28 @@ mod tests { } } + #[test] + fn test_dominant_flat9_sharp5_candidates() { + let candidates = KnownChord::DominantFlat9Sharp5(Degree::Seven).scale_candidates(); + assert!(!candidates.is_empty(), "G7(b9)(#5) should have scale candidates"); + + match &candidates[0] { + ScaleCandidate::Mode { kind, rank, .. } => { + assert_eq!(*kind, ModeKind::Altered); + assert_eq!(*rank, 1); + } + _ => panic!("First candidate for G7(b9)(#5) should be a Mode"), + } + + match &candidates[1] { + ScaleCandidate::Scale { kind, rank, .. } => { + assert_eq!(*kind, ScaleKind::DiminishedHalfWhole); + assert_eq!(*rank, 2); + } + _ => panic!("Second candidate for G7(b9)(#5) should be a Scale"), + } + } + #[test] fn test_half_diminished_candidates() { let candidates = KnownChord::HalfDiminished(Degree::Seven).scale_candidates(); @@ -1036,6 +1091,7 @@ mod tests { KnownChord::Diminished, KnownChord::DominantFlat9(Degree::Seven), KnownChord::DominantSharp9(Degree::Seven), + KnownChord::DominantFlat9Sharp5(Degree::Seven), KnownChord::MinorDominantFlat13(Degree::Seven), KnownChord::MinorDominantFlat9Flat13(Degree::Seven), KnownChord::Sharp11, From c5c604f0f686254c0d41ff591ab00d960fe9c22d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:47:52 +0000 Subject: [PATCH 3/4] Fix relative_scale for DominantFlat9Sharp5 to include AugmentedFifth Co-authored-by: twitchax <549523+twitchax@users.noreply.github.com> --- kord/src/core/known_chord.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kord/src/core/known_chord.rs b/kord/src/core/known_chord.rs index 96d776f..5fc2f17 100644 --- a/kord/src/core/known_chord.rs +++ b/kord/src/core/known_chord.rs @@ -362,7 +362,7 @@ impl HasRelativeScale for KnownChord { Interval::MinorThird, Interval::MajorThird, Interval::AugmentedFourth, - Interval::MinorSixth, + Interval::AugmentedFifth, Interval::MinorSeventh, ], KnownChord::MinorDominantFlat13(_) => vec![ From 5851a07fb45e6b4e0e0bf4f29540b30f2fd34998 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:57:34 +0000 Subject: [PATCH 4/4] Rename DominantFlat9Sharp5 to AugmentedDominantFlat9 for consistency Co-authored-by: twitchax <549523+twitchax@users.noreply.github.com> --- kord/src/core/chord.rs | 4 ++-- kord/src/core/known_chord.rs | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/kord/src/core/chord.rs b/kord/src/core/chord.rs index 0939ab1..79ec6de 100644 --- a/kord/src/core/chord.rs +++ b/kord/src/core/chord.rs @@ -949,7 +949,7 @@ impl HasKnownChord for Chord { if contains_dominant { if modifiers.contains(&Modifier::Flat9) { - return KnownChord::DominantFlat9Sharp5(degree); + return KnownChord::AugmentedDominantFlat9(degree); } return KnownChord::AugmentedDominant(degree); @@ -1494,7 +1494,7 @@ mod tests { assert_eq!(Chord::new(C).seven().sharp11().known_chord(), KnownChord::DominantSharp11(Degree::Seven)); assert_eq!(Chord::new(C).seven().flat9().known_chord(), KnownChord::DominantFlat9(Degree::Seven)); assert_eq!(Chord::new(C).seven().sharp9().known_chord(), KnownChord::DominantSharp9(Degree::Seven)); - assert_eq!(Chord::new(C).seven().flat9().augmented().known_chord(), KnownChord::DominantFlat9Sharp5(Degree::Seven)); + assert_eq!(Chord::new(C).seven().flat9().augmented().known_chord(), KnownChord::AugmentedDominantFlat9(Degree::Seven)); assert_eq!(Chord::new(C).sus2().known_chord(), KnownChord::Major); assert_eq!(Chord::new(C).sus4().known_chord(), KnownChord::Major); diff --git a/kord/src/core/known_chord.rs b/kord/src/core/known_chord.rs index 5fc2f17..fba2fa6 100644 --- a/kord/src/core/known_chord.rs +++ b/kord/src/core/known_chord.rs @@ -187,8 +187,8 @@ pub enum KnownChord { DominantFlat9(Degree), /// A dominant sharp 9 chord. DominantSharp9(Degree), - /// A dominant flat 9 sharp 5 chord. - DominantFlat9Sharp5(Degree), + /// An augmented dominant flat 9 chord. + AugmentedDominantFlat9(Degree), /// A minor dominant flat 13 chord. MinorDominantFlat13(Degree), /// A minor dominant flat 9 flat 13 chord. @@ -217,7 +217,7 @@ impl HasDescription for KnownChord { KnownChord::Diminished => "diminished", KnownChord::DominantFlat9(_) => "dominant flat 9", KnownChord::DominantSharp9(_) => "dominant sharp 9", - KnownChord::DominantFlat9Sharp5(_) => "dominant flat 9 sharp 5", + KnownChord::AugmentedDominantFlat9(_) => "augmented dominant flat 9", KnownChord::MinorDominantFlat13(_) => "minor dominant flat 13", KnownChord::MinorDominantFlat9Flat13(_) => "minor dominant flat 9 flat 13", KnownChord::Sharp11 => "sharp 11", @@ -356,7 +356,7 @@ impl HasRelativeScale for KnownChord { Interval::MinorSixth, Interval::MinorSeventh, ], - KnownChord::DominantFlat9Sharp5(_) => vec![ + KnownChord::AugmentedDominantFlat9(_) => vec![ Interval::PerfectUnison, Interval::MinorSecond, Interval::MinorThird, @@ -420,7 +420,7 @@ impl HasRelativeChord for KnownChord { KnownChord::Diminished => vec![Interval::PerfectUnison, Interval::MinorThird, Interval::DiminishedFifth, Interval::DiminishedSeventh], KnownChord::DominantFlat9(_) => vec![Interval::PerfectUnison, Interval::MajorThird, Interval::PerfectFifth, Interval::MinorSeventh, Interval::MinorNinth], KnownChord::DominantSharp9(_) => vec![Interval::PerfectUnison, Interval::MajorThird, Interval::PerfectFifth, Interval::MinorSeventh, Interval::AugmentedNinth], - KnownChord::DominantFlat9Sharp5(_) => vec![Interval::PerfectUnison, Interval::MajorThird, Interval::AugmentedFifth, Interval::MinorSeventh, Interval::MinorNinth], + KnownChord::AugmentedDominantFlat9(_) => vec![Interval::PerfectUnison, Interval::MajorThird, Interval::AugmentedFifth, Interval::MinorSeventh, Interval::MinorNinth], KnownChord::MinorDominantFlat13(_) => vec![Interval::PerfectUnison, Interval::MinorThird, Interval::PerfectFifth, Interval::MinorSeventh, Interval::MinorThirteenth], KnownChord::MinorDominantFlat9Flat13(_) => vec![ Interval::PerfectUnison, @@ -459,7 +459,7 @@ impl HasName for KnownChord { KnownChord::Diminished => "dim".to_owned(), KnownChord::DominantFlat9(d) => format!("{}(♭9)", d.static_name()), KnownChord::DominantSharp9(d) => format!("{}(♯9)", d.static_name()), - KnownChord::DominantFlat9Sharp5(d) => format!("{}(♭9)(♯5)", d.static_name()), + KnownChord::AugmentedDominantFlat9(d) => format!("+{}(♭9)", d.static_name()), KnownChord::MinorDominantFlat13(d) => format!("m{}(♭13)", d.static_name()), KnownChord::MinorDominantFlat9Flat13(d) => format!("{}(♭9)(♭13)", d.static_name()), KnownChord::Sharp11 => "(♯11)".to_owned(), @@ -486,7 +486,7 @@ impl KnownChord { KnownChord::Diminished => DIMINISHED_CANDIDATES, KnownChord::DominantFlat9(_) => DOMINANT_FLAT9_CANDIDATES, KnownChord::DominantSharp9(_) => DOMINANT_SHARP9_CANDIDATES, - KnownChord::DominantFlat9Sharp5(_) => DOMINANT_FLAT9_SHARP5_CANDIDATES, + KnownChord::AugmentedDominantFlat9(_) => AUGMENTED_DOMINANT_FLAT9_CANDIDATES, KnownChord::MinorDominantFlat13(_) => MINOR_DOMINANT_FLAT13_CANDIDATES, KnownChord::MinorDominantFlat9Flat13(_) => MINOR_DOMINANT_FLAT9_FLAT13_CANDIDATES, KnownChord::Sharp11 => SHARP11_CANDIDATES, @@ -787,7 +787,7 @@ static DOMINANT_SHARP9_CANDIDATES: &[IntervalCandidate] = &[ }, ]; -static DOMINANT_FLAT9_SHARP5_CANDIDATES: &[IntervalCandidate] = &[ +static AUGMENTED_DOMINANT_FLAT9_CANDIDATES: &[IntervalCandidate] = &[ IntervalCandidate { kind: IntervalCollectionKind::Mode(ModeKind::Altered), rank: 1, @@ -933,8 +933,8 @@ mod tests { } #[test] - fn test_dominant_flat9_sharp5_candidates() { - let candidates = KnownChord::DominantFlat9Sharp5(Degree::Seven).scale_candidates(); + fn test_augmented_dominant_flat9_candidates() { + let candidates = KnownChord::AugmentedDominantFlat9(Degree::Seven).scale_candidates(); assert!(!candidates.is_empty(), "G7(b9)(#5) should have scale candidates"); match &candidates[0] { @@ -1091,7 +1091,7 @@ mod tests { KnownChord::Diminished, KnownChord::DominantFlat9(Degree::Seven), KnownChord::DominantSharp9(Degree::Seven), - KnownChord::DominantFlat9Sharp5(Degree::Seven), + KnownChord::AugmentedDominantFlat9(Degree::Seven), KnownChord::MinorDominantFlat13(Degree::Seven), KnownChord::MinorDominantFlat9Flat13(Degree::Seven), KnownChord::Sharp11,