Lesson 10: Substitutions and modal mixture
Sections
Reading settings
No voice for this language in this browser.
More voices
Code and English terms
Off: the page’s voice reads everything, with no pause between two voices.
No voice for this language in this browser.
More voices
More voices: Microsoft Edge has natural online voices, and Windows (Settings › Time & language › Speech), macOS and Android install others.
Lesson 9 measured how far one chord is from the next. This lesson asks which chord can take another’s place, and which chords a key can borrow from its parallel modes. Guitar Alchemist (GA) answers in five places: a chatbot skill, a tool of its MCP server, a second tool with the same name on its web API, a service of that API, and a YAML file. The course program checks each one, and runs GA’s own code wherever it can.
All GA links point to commit a826864. The outputs come from the command below; the entry point is l12.
dotnet run --project code/music-theory-ga/GaTheory -c Release -- l12Diatonic substitution
Section titled “Diatonic substitution”The idea
Section titled “The idea”A substitution swaps one chord for another that does the same job. Wikipedia quotes Alfred Blatter: “A chord substitution occurs when a chord is replaced by another that is made to function like the original. Usually substituted chords possess two pitches in common with the triad that they are replacing.” (Chord substitution, citing Blatter 2007, p. 186). Lesson 9 showed which triads share two notes: those whose roots are a third apart. In C major, A minor and E minor can stand in for C, and D minor and A minor for F. Wikipedia calls the first case the relative major/minor substitution, which “shares two common tones” (same article).
The course takes the key’s triads on the other degrees and ranks them by the notes they share with the chord (Lesson12.CourseSubstitutes). A seventh chord has four notes, so a triad can share three with it: B diminished is G7 without its root, and E minor is Cmaj7 without its own.
== Diatonic substitutes in C major, by the notes they share (GA: ga_chord_substitutions, the closure rewritten)chord course GA checkAm C 2, F 2, Dm 1, Em 1 C 2, F 2, Dm 1, Em 1 okEm C 2, G 2, Am 1, Bdim 1 C 2, G 2, Am 1, Bdim 1 okF Dm 2, Am 2, C 1, Bdim 1 Dm 2, Am 2, C 1, Bdim 1 okC Em 2, Am 2, F 1, G 1 Em 2, Am 2, F 1, G 1 okG7 Bdim 3, Dm 2, Em 2, C 1, F 1 Bdim 3, Dm 2, Em 2, C 1, F 1 okCmaj7 Em 3, G 2, Am 2, F 1, Bdim 1 Em 3, G 2, Am 2, F 1, Bdim 1 okBm7b5 Dm 3, F 2, G 2, Em 1, Am 1 Dm 2, G 2, Bdim 2, Em 1, F 1, Am 1 DIFF the course's Bm7b5: B D F A; the closure's: B D F# ATies keep the order of the scale. The last row is a half-diminished seventh, B D F A, and D minor, D F A, shares three of its notes.
In GA: the MCP server’s ga_chord_substitutions
Section titled “In GA: the MCP server’s ga_chord_substitutions”GA’s MCP server answers with ga_chord_substitutions (GaDslTool.cs#L208-L222), which runs an F# closure, domain.chordSubstitutions (DomainClosures.fs#L535-L621). It does the same thing: the key’s triads that share at least one note with the chord, sorted by how many with F#’s stable List.sortByDescending (#L602), the chord itself skipped when both its root and its quality match (#L587). The closure is F# and the course program is C#, so the program rewrites it, with the parser it calls (Lesson12.ParseChord, Lesson12.GaSubstitutions). For this tool, the course tests its reading of GA’s code, not the running server.
The two agree on six chords. The seventh is lesson 9’s defect again: the parser keeps the ♭5 of Bm7♭5 as an alteration (ChordParser.fs#L69-L84), and the closure builds the chord from its quality and its extensions only (DomainClosures.fs#L85-L98, #L349-L355). B D F♯ A shares only two notes with D minor, and B diminished slips in with two. On GA’s main, the closure takes its notes from chordTones, which GA #681 introduced (#L446-L450 and #L663 at 5c3a52a); read, not run.
Here is the closure’s own answer for A minor, rewritten line for line, next to the example in the tool’s description (GaDslTool.cs#L212):
== The closure's answer for Am in C major, and the example in the tool's description (GaDslTool.cs line 212) Substitutions for Am in key of C major: ★★ C — 2 shared: C(m3/P1) E(P5/M3) ★★ F — 2 shared: A(P1/M3) C(m3/P5) ★ Dm — 1 shared: A(P1/P5) ★ Em — 1 shared: E(P5/P1) description: Am in key of C major → C (★★★, relative major), Em (★★, shared E/B), F (★, shared A)The description is wrong about all three chords. C shares two notes with A minor, not three. E minor shares only E, since A minor has no B. F shares A and C, and ranks with C.
The key is optional. Without it, the closure takes the chord’s root letter, drops the accidental, and assumes a major key (#L558-L559); the tool’s parameter only says “Defaults to chord root if omitted” (GaDslTool.cs#L215).
== Without a key, the closure uses the chord's root letter as a major key (line 558)chord GA's key GA's rankingAm A major A 2, C#m 1, D 1, E 1, F#m 1Bb7 B major C#m 1, D#m 1, E 1, F# 1, G#m 1, A#dim 1; tritone E7F#m F major F 1, Am 1, Dm 1Eb E major G#m 1, B 1, D#dim 1A minor’s first substitute is A major: the key of A major contains it, and the closure skips a chord only when the root and the quality match. F♯ minor is compared with the chords of F major, none of which contains F♯ or C♯; E♭ with those of E major.
Tritone substitution
Section titled “Tritone substitution”The idea
Section titled “The idea”Open Music Theory: “Tritone substitutions replace a dominant chord with another dominant chord a tritone away. The name refers both to the interval between the original and substituted chords and to the fact that the two chords share the same tritone.” (Open Music Theory, “Substitutions”). G7 is G B D F; D♭7 is D♭ F A♭ C♭, and C♭ sounds as B. The tritone B–F is in both chords with the roles swapped: B is the third of G7 and the seventh of D♭7. Both resolve to C, and the substitute does it by a half step in the bass: “the most reliable way to recognize a tritone substitution in a song is by its chromatic resolution downward by a minor second” (same chapter). The Streeling module MUS-005 · Jazz Harmony for Guitar works through it in section 5, “Substitution Techniques”.
The course calls a chord dominant when it has a major third and a minor seventh above its root, with or without extensions, and names the substitute a diminished fifth above the root: D♭ for G.
The closure adds a tritone line under the same test, a major third and a minor seventh among its intervals (#L603-L609), and spells the root with flats:
== The tritone substitute: the course's dominant chords, and the closure's test for M3 and m7 (lines 603-609)chord course GA checkG7 Db7 Db7 okD7 Ab7 Ab7 okE7 Bb7 Bb7 okC7 Gb7 Gb7 okG9 Db7 (none) DIFFG13 Db7 (none) DIFFGm7 (none) (none) okCmaj7 (none) (none) okG9 and G13 get no substitute. At a826864, “9” and “13” add only their own degree (#L94-L98), so the closure never sees the minor seventh both chords contain. chordTones, on main, implies it (lesson 9).
Secondary and backdoor dominants
Section titled “Secondary and backdoor dominants”The idea
Section titled “The idea”A secondary dominant is the dominant of a chord other than the tonic. Open Music Theory calls these “secondary dominant chords (V(7))” and gives the commonest: “ii becomes II♯, which is V/V” (Open Music Theory, “Tonicization”). In C major, that is D7 going to G. The target must be a major or minor triad: “Diminished and augmented triads can’t be tonicized, since there are no diminished or augmented keys” (same chapter). MUS-003 · How Harmony Works covers them in section 5; one row of its G major table is wrong (see the journal).
The backdoor dominant reaches the tonic from a whole step below: ♭VII⁷ → I, B♭7 → C in C major. Wikipedia quotes Jerry Coker: “The I chord, in a given progression, is often preceded by IV–7 to ♭VII7, instead of the usual V7 chord” (Chord substitution, citing Coker 1997, p. 82). MUS-005 has it as “Backdoor Dominant (bVII7 → I)”.
The course reads a pair of chords with the five names GA’s skill uses (Lesson12.CourseRelations): two dominant sevenths a tritone apart; a major triad or dominant seventh a fifth above a major or minor chord; a dominant seventh a whole step below its resolution; the same prime form, lesson 4’s set class; and interval-class vectors at most 2 apart.
In GA: the chatbot’s ChordSubstitutionSkill
Section titled “In GA: the chatbot’s ChordSubstitutionSkill”The chatbot answers these questions with ChordSubstitutionSkill, without a language model. Like lesson 9’s skill, it is picked by meaning (ProductionOrchestrator.cs#L200-L206); then it reads chord symbols with its own regular expression (ChordSubstitutionSkill.cs#L69-L71). Two symbols make a comparison, one a list (#L144-L174). The program copies the pattern, the tables and the selection, without the logger and the reply text, and calls GA’s GrothendieckService and GrothendieckDelta, compiled as they are (Lesson12.cs#L281-L416). The skill’s twelve example prompts (#L35-L55) go through the pattern first:
== GA's chatbot skill: what its own twelve example prompts parse to (ChordSubstitutionSkill.cs lines 146-160) Tritone substitution for G7 lists substitutes for G7 What can I substitute for Cmaj7 in a ii-V-I? lists substitutes for Cmaj7 Reharmonize Dm7 in a jazz context lists substitutes for Dm7 Alternative chord for F major in C compares F with C What's the secondary dominant of Am? lists substitutes for Am Show me a backdoor dominant for C major lists substitutes for C Alternative chord for Cmaj7 lists substitutes for Cmaj7 What can replace Dm7? lists substitutes for Dm7 Swap chord for G7 lists substitutes for G7 Modal interchange substitutes for C major lists substitutes for C Borrow a chord from parallel minor no chord: "Could not identify a chord symbol in your message." Modal interchange options in F major lists substitutes for FThe pattern is case-sensitive and wants a capital A to G with no letter after it, so “Alternative” and “Borrow” are not chords. “Alternative chord for F major in C” finds two chords, F and C, and compares them instead of listing alternatives to F. “Borrow a chord from parallel minor” has no chord symbol at all. The comparisons:
== Two chords: the course's reading and the skill's labels (ClassifySubstitution, lines 246-298)G7 Db7 DIFF course: Tritone Substitution, Set-Class Equivalent, ICV Neighbor (L1 = 0) GA: Tritone Substitution, Set-Class Equivalent, ICV Neighbor (L1 = 1)G7 C ok course and GA: Secondary DominantD7 G ok course and GA: Secondary DominantDm G DIFF course: Set-Class Equivalent, ICV Neighbor (L1 = 0) GA: Secondary Dominant, Set-Class Equivalent, ICV Neighbor (L1 = 1)F# Bdim DIFF course: Harmonic Distance GA: Secondary DominantC C DIFF course: Set-Class Equivalent, ICV Neighbor (L1 = 0) GA: Set-Class Equivalent, ICV Neighbor (L1 = 1)C Am DIFF course: Set-Class Equivalent, ICV Neighbor (L1 = 0) GA: Set-Class Equivalent, ICV Neighbor (L1 = 1)Bb7 C ok course and GA: Backdoor DominantTwo tests disagree with the textbook. Secondary Dominant looks only at the roots (#L262): D minor gets it before G, and F♯ before B diminished, though a minor chord is not a dominant and a diminished triad cannot be tonicized. ICV Neighbor reports distance 1 for two chords with the same interval-class vector, where the distance is 0: GrothendieckDelta.FromIcVs turns a zero difference into a one, “to preserve musical differentiation expected by callers/tests” (GrothendieckDelta.cs#L125-L131). So C is one step away from itself.
Ranking candidates by interval-class vector
Section titled “Ranking candidates by interval-class vector”The idea
Section titled “The idea”Given one chord, the skill lists five substitutes “ranked by ICV distance” (ChordSubstitutionSkill.cs#L182). GA’s FindNearby (GrothendieckService.cs#L45-L90) walks all 4,096 pitch-class sets and keeps those whose interval-class vector (lesson 4) differs from the chord’s by at most 3, summed over the six classes. Each gets a cost of 0.6 times that distance (#L39-L42). The skill keeps the sets of the chord’s size and takes the first five by cost (ChordSubstitutionSkill.cs#L164-L174).
Sorting by a key that ties is a C# question. Enumerable.OrderBy is stable: “if the keys of two elements are equal, the order of the elements is preserved”. Here nearly everything ties. A chord’s transpositions and inversions have the same vector, so the 24 major and minor triads share one, and the 12 dominant and 12 half-diminished sevenths another. With the zero turned into a one, all of them come out at distance 1 and cost 0.60, and the stable sort leaves them in the order FindNearby met them: 12-bit order.
The program compiles FindNearby as it is, counts the sets with the same vector itself, and prints the skill’s five lines with each set’s 12-bit number and the notes it shares with the chord (Lesson12.SkillCandidates):
== The skill's list for one chord: GA's FindNearby, then the first five of the same size, by costcourse: the other chords of the same size with the same ICV; GA: the chords at the lowest cost it listschord course GA checkG7 23 23 ok - **Dm7b5** — harmonic cost 0.60 (Δ L1=1) id 293, 2 notes in common with G7 - **Ab7** — harmonic cost 0.60 (Δ L1=1) id 329, 0 notes in common with G7 - **F7** — harmonic cost 0.60 (Δ L1=1) id 553, 1 note in common with G7 - **D7** — harmonic cost 0.60 (Δ L1=1) id 581, 1 note in common with G7 - **Ebm7b5** — harmonic cost 0.60 (Δ L1=1) id 586, 0 notes in common with G7 textbook Db7: number 19 of the 155 it lists, cost 0.60Am 23 23 ok - **Cm** — harmonic cost 0.60 (Δ L1=1) id 137, 1 note in common with Am - **C** — harmonic cost 0.60 (Δ L1=1) id 145, 2 notes in common with Am - **Ab** — harmonic cost 0.60 (Δ L1=1) id 265, 1 note in common with Am - **Dbm** — harmonic cost 0.60 (Δ L1=1) id 274, 1 note in common with Am - **Fm** — harmonic cost 0.60 (Δ L1=1) id 289, 1 note in common with Am textbook C: number 2 of the 95 it lists, cost 0.60 textbook F: number 8 of the 95 it lists, cost 0.60C 23 23 ok - **Cm** — harmonic cost 0.60 (Δ L1=1) id 137, 2 notes in common with C - **Ab** — harmonic cost 0.60 (Δ L1=1) id 265, 1 note in common with C - **Dbm** — harmonic cost 0.60 (Δ L1=1) id 274, 1 note in common with C - **Fm** — harmonic cost 0.60 (Δ L1=1) id 289, 1 note in common with C - **Db** — harmonic cost 0.60 (Δ L1=1) id 290, 0 notes in common with C textbook Am: number 6 of the 95 it lists, cost 0.60 textbook Em: number 21 of the 95 it lists, cost 0.60Cmaj7 11 11 ok - **Dbmaj7** — harmonic cost 0.60 (Δ L1=1) id 291, 1 note in common with Cmaj7 - **Abmaj7** — harmonic cost 0.60 (Δ L1=1) id 393, 2 notes in common with Cmaj7 - **Fmaj7** — harmonic cost 0.60 (Δ L1=1) id 561, 2 notes in common with Cmaj7 - **Dmaj7** — harmonic cost 0.60 (Δ L1=1) id 582, 0 notes in common with Cmaj7 - **Amaj7** — harmonic cost 0.60 (Δ L1=1) id 786, 1 note in common with Cmaj7 textbook Em7: not listed (Δ L1=4, beyond 3) textbook Am7: not listed (Δ L1=4, beyond 3)Dm7 11 11 ok - **Fm7** — harmonic cost 0.60 (Δ L1=1) id 297, 2 notes in common with Dm7 - **F#m7** — harmonic cost 0.60 (Δ L1=1) id 594, 1 note in common with Dm7 - **Am7** — harmonic cost 0.60 (Δ L1=1) id 657, 2 notes in common with Dm7 - **Ebm7** — harmonic cost 0.60 (Δ L1=1) id 1098, 0 notes in common with Dm7 - **Cm7** — harmonic cost 0.60 (Δ L1=1) id 1161, 1 note in common with Dm7 textbook Fmaj7: not listed (Δ L1=4, beyond 3)The list is the five smallest numbers of the chord’s set class, the chord itself left out. The textbook substitute is further down. D♭7, the tritone substitute the skill’s own description promises (“tritone subs (G7 → Db7)”, #L28-L33), comes 19th, so the skill’s first example prompt, “Tritone substitution for G7”, never shows it. Em7 and Am7, which share three notes with Cmaj7, are not listed at all: their vector is 4 away. And the same few chords come back for almost every root:
== Over the twelve roots of each chord type, the skill's lists of fivetype different chords first suggestion, and for how many rootsmajor 6 Cm 12m 6 C 1, Cm 11dim 6 Dbdim 1, Cdim 11aug 4 Dbaug 3, Caug 97 6 Dm7b5 12maj7 6 Dbmaj7 11, Abmaj7 1m7 6 Fm7 11, Dm7 1m7b5 6 Dm7b5 11, Ab7 1dim7 3 Dbdim7 4, Cdim7 8Dm7♭5 is the first suggestion for all twelve dominant sevenths. A ranking whose key ties this much needs a second key that means something: the notes in common, which the program prints, or the motion of the root.
GaApi, GA’s web API, serves the same skill logic as two MCP tools of its own, ga_chord_substitutions and ga_chord_compare (ChordSubstitutionMcpTools.cs#L44, #L97), on its /mcp endpoint (registered at Program.cs#L354-L357, mapped at #L514). Two tools called ga_chord_substitutions therefore answer differently: the MCP server’s ranks a key’s chords by common tones, GaApi’s ranks every set by vector distance.
Modal mixture
Section titled “Modal mixture”The idea
Section titled “The idea”Open Music Theory: “Modal mixture (or borrowing) is the harmonic technique of mixing the notes from the parallel major and natural-minor modes (e.g., C major and C minor).” Mixture “is more common in major keys (borrowing from the parallel minor)”, and it “changes the quality of a chord, but not its function” (Open Music Theory, “Modal Mixture”). Lowered roots get a flat: “Chords with lowered roots use a flat sign in front of the Roman numeral (e.g., ♭VI).” In C major the common ones are iv (F minor), ii° and iiø⁷ (D F A♭, with C), ♭VI (A♭), ♭III (E♭) and ♭VII (B♭); changing I to i is common too, V to v less so (same chapter).
Borrowing from the other parallel modes, Dorian, Phrygian, Lydian, Mixolydian and Locrian, extends the idea; jazz and rock musicians call it modal interchange. The course spells each mode on C, one letter per degree, and lists the triads C major does not have, with numerals read against the major scale (Lesson12.CourseBorrowed, Lesson12.Numeral):
== The course's borrowed chords, mode by mode: every triad of the parallel mode that C major lacksmode chordsDorian i Cm, bIII Eb, v Gm, vi° Adim, bVII BbPhrygian i Cm, bII Db, bIII Eb, iv Fm, v° Gdim, bVI Ab, bvii BbmLydian II D, #iv° F#dim, vii BmMixolydian iii° Edim, v Gm, bVII BbAeolian i Cm, ii° Ddim, bIII Eb, iv Fm, v Gm, bVI Ab, bVII BbLocrian i° Cdim, bII Db, biii Ebm, iv Fm, bV Gb, bVI Ab, bvii Bbmcount course GA checkdistinct chords 18 18 okThe Aeolian row is Open Music Theory’s mixture. Across the six modes there are 18 different chords; the GA column of the last row comes from the next section.
In GA: get_borrowed_chords
Section titled “In GA: get_borrowed_chords”GA’s MCP tool get_borrowed_chords passes the key on to GaApi (ContextualChordsTool.cs#L72-L83, ContextualChordsController.cs#L38-L41), whose ContextualChordService.GetBorrowedChordsAsync (ContextualChordService.cs#L75-L119) builds the triads of each parallel mode and keeps those the home key lacks. The program compiles the service as it is, with GA’s ChordTemplateFactory, and asks it for C major. GA writes sharps as ♯; the comparison reads them as #, so only the spelling counts.
== Borrowed chords for C major: GA's get_borrowed_chords (ContextualChordService, compiled as it is), chord by chordGA's mode course GA checkDorian i Cm i Cm ok notes: course C Eb G, GA C D♯ GDorian bIII Eb III D# DIFF notes: course Eb G Bb, GA D♯ G A♯Dorian v Gm v Gm ok notes: course G Bb D, GA G A♯ DDorian vi° Adim vi° Adim ok notes: course A C Eb, GA A C D♯Dorian bVII Bb VII A# DIFF notes: course Bb D F, GA A♯ D FPhrygian bII Db II C# DIFF notes: course Db F Ab, GA C♯ F G♯Phrygian iv Fm iv Fm ok notes: course F Ab C, GA F G♯ CPhrygian v° Gdim v° Gdim ok notes: course G Bb Db, GA G A♯ C♯Phrygian bVI Ab VI G# DIFF notes: course Ab C Eb, GA G♯ C D♯Phrygian bvii Bbm vii A#m DIFF notes: course Bb Db F, GA A♯ C♯ FLydian II D II D okLydian #iv° F#dim iv° F#dim DIFFLydian vii Bm vii Bm okMixolydian iii° Edim iii° Edim ok notes: course E G Bb, GA E G A♯Aeolian ii° Ddim ii° Ddim ok notes: course D F Ab, GA D F G♯Locrian i° Cdim i° Cdim ok notes: course C Eb Gb, GA C D♯ F♯Locrian biii Ebm iii D#m DIFF notes: course Eb Gb Bb, GA D♯ F♯ A♯Locrian bV Gb V F# DIFF notes: course Gb Bb Db, GA F♯ A♯ C♯It finds the same 18 chords, with three differences. Each chord is credited to the first mode of the loop that has it (#L93-L109): B♭ and G minor come out as Dorian, and Open Music Theory’s parallel minor, Aeolian, is left with D diminished alone. Every black-key root is spelled with a sharp (#L137, through Note.cs#L75): D♯ for E♭, A♯ for B♭, G♯ for A♭, and even C minor comes out as C D♯ G. And the numerals carry no accidental (#L157-L170): the A♭ chord is “VI”, and D♭ and D are both “II”.
In GA: ModalInterchange.yaml
Section titled “In GA: ModalInterchange.yaml”GA also describes modal interchange in a configuration file, ModalInterchange.yaml, 1,549 lines of numerals, chords spelled in C major or A minor, songs and tips. The program spells each chord from its numeral in its source mode (Lesson12.ReadMixtureChords):
== GA's ModalInterchange.yaml: each chord spelled from its numeral in its source modeentry, numeral course GA checkParallel Minor bVI Ab major Ab major okParallel Minor bVII Bb major Bb major okParallel Minor iv F minor F minor okParallel Minor ii° D diminished D diminished okParallel Major VI F# minor F major DIFF F major is already a chord of A natural minor: nothing is borrowedParallel Major VII G# diminished G major DIFF G major is already a chord of A natural minor: nothing is borrowedParallel Major III C# minor C major DIFF C major is already a chord of A natural minor: nothing is borrowedDorian IV D major D major okDorian ii B minor B minor okPhrygian bII Bb major Bb major okPhrygian bii° Bb major Bb diminished DIFFMixolydian bVII Bb major Bb major okMixolydian v G minor G minor okNine of the thirteen are right. The three chords “borrowed from the parallel major” into A minor are A minor’s own chords (#L271-L362); borrowing from A major would give F♯ minor, G♯ diminished and C♯ minor. “bii°, Bb diminished” is not in A Phrygian, whose second degree is B♭ major, the entry just above it (#L616-L619). The harmonic and melodic minor examples give numerals only (#L826-L875):
== Its chromatic numerals, read in C: the chord on that degree of the modemode, numeral course GA checkHarmonic Minor V7 V7 V7 ok G B D FHarmonic Minor vii°7 vii°7 vii°7 ok B D F AbHarmonic Minor bVI+ bVI bVI+ DIFF Ab C EbMelodic Minor iv+ IV iv+ DIFF F A CMelodic Minor V7 V7 V7 ok G B D FMelodic Minor vii°7 viiø7 vii°7 DIFF B D F AHarmonic minor’s ♭VI is major, and its augmented triad is ♭III+. Melodic minor’s fourth degree is a major chord. Its seventh chord on vii is half-diminished, not diminished.
I expected nothing in GA to read this file: the configuration watcher lists it, and a change to it falls through to “Unknown configuration file” (ConfigurationWatcherService.cs#L55, #L157-L158). That was wrong. YamlKnowledgeLoader (YamlKnowledgeLoader.fs#L128-L140) reads every YAML file of the configuration directory except five that have their own loaders, and flattens each entry into text. YamlKnowledgeSyncService would store those texts with embeddings “for semantic retrieval by the chatbot agents”, says its comment (YamlKnowledgeSyncService.cs#L8-L25), but nothing runs it at a826864: only AddSyncServices would register it (ServiceCollectionExtensions.cs#L32-L54), nothing calls that method, and GaCLI has the call commented out (Program.cs#L320-L321). The program calls the loader, which it already compiles with GA.Business.Config:
== Who reads the file: GA's YamlKnowledgeLoader (GA.Business.Config, compiled), which flattens every content YAML 8 entries from ModalInterchange.yaml: Borrowed Chords from Parallel Minor Borrowed Chords from Parallel Major Dorian Interchange Phrygian Interchange Mixolydian Interchange Chromatic Modal Interchange Parallel Modal Regions Modal Pivot Chords "InKeyOfAm: F major" in their text: yes "InKeyOfAm: Bb diminished" in their text: yes "bVI+" in their text: yes "iv+" in their text: yesThe wrong chords and numerals reach that text. Nothing at a826864 stores that text, though, and nothing reads the yaml_knowledge collection the sync service would fill: outside that service, the collection appears only as a property of MongoDbService (MongoDbService.cs#L56-L57). On the way, the loader skips SpecializedTunings.yaml, which does not parse, with a message on standard error and nothing else.
On GA’s main at 5c3a52a, the closure’s notes have changed (#681); the default key, the description’s example, the skill’s two tests, the forced distance of 1, the service’s spelling and its credit to the first mode are as above. Read, not run.
Exercises
Section titled “Exercises”- Rank D minor’s diatonic substitutes in F major by the notes they share.
- What is the tritone substitute of A7, and which tritone do the two chords share?
- Which chord does the chatbot skill list first for A7, and why?
- Which chords does G major borrow from G minor? How does
get_borrowed_chords("G major")spell them?
Solutions
- F 2, B♭ 2, G minor 1, A minor 1. F and B♭ have their roots a third from D; C and E diminished share nothing with D minor.
- E♭7. A7 is A C♯ E G and E♭7 is E♭ G B♭ D♭: G and C♯, which sounds as D♭, swap roles.
- Dm7♭5, 12-bit number 293, the smallest of the 23 sets with A7’s vector. The textbook’s E♭7 is further down.
- G minor, A diminished, B♭, C minor, D minor, E♭ and F. GA finds the same seven among its borrowed chords for G major, with A♯ for B♭ and D♯ for E♭.
== Exercise solutionsquestion course GA check1. Dm in F major F 2, Bb 2, Gm 1, Am 1 F 2, Bb 2, Gm 1, Am 1 ok2. A7, tritone Eb7 Eb7 ok A7: A C# E G; Eb7: Eb G Bb Db3. chatbot, A7 Eb7 Dm7b5 DIFF4. G minor in G Gm Adim Bb Cm Dm Eb F Gm Adim A# Cm Dm D# F DIFFKey takeaways
Section titled “Key takeaways”- A substitute does the original chord’s job; a diatonic substitute shares two notes with a triad, its root a third away. GA’s MCP closure ranks a key’s chords the same way, but without a key it uses the major key of the root’s letter, and at
a826864it dropped alterations. - Two dominant sevenths a tritone apart share their tritone, and the substitute resolves down a half step. GA’s test for a major third and a minor seventh missed ninths and thirteenths, which did not carry their seventh at
a826864. - A secondary dominant is a major triad or dominant seventh a fifth above a major or minor chord. GA’s skill checks the roots only, and its interval-vector distance turns 0 into 1.
- Ranking by vector distance ties every chord of a type, and LINQ’s stable
OrderBykeeps the enumeration order: the chatbot’s five substitutes are the smallest 12-bit numbers of the chord’s set class, Dm7♭5 first for every dominant seventh. A ranking needs a tie-breaker that means something. - Modal mixture borrows from the parallel minor, and by extension from every parallel mode. GA’s service finds the same 18 chords as the course for C major, but spells them with sharps, drops the ♭ from the numerals and credits each chord to the first mode of its loop.
ModalInterchange.yamlhas 4 of 13 chords and 3 of 6 numerals wrong, and its text reaches GA’s YAML knowledge loader, though nothing ata826864runs the service that would store it with embeddings.
Sources
Section titled “Sources”- Mark Gotham et al., Open Music Theory, version 2, 2023, CC BY-SA 4.0: chapters Modal Mixture, Substitutions and Tonicization.
- Wikipedia: Chord substitution, quoting Alfred Blatter, Revisiting Music Theory, 2007, and Jerry Coker, Elements of the Jazz Language for the Developing Improvisor, 1997.
- Microsoft Learn:
Enumerable.OrderBy. - GuitarAlchemist/ga at
a826864:GaMcpServer/Tools/GaDslTool.cs,Common/GA.Business.DSL/Closures/BuiltinClosures/DomainClosures.fs,Common/GA.Business.ML/Agents/Skills/ChordSubstitutionSkill.cs,Common/GA.Domain.Services/Atonal/Grothendieck/GrothendieckService.cs,Common/GA.Domain.Services/Atonal/Grothendieck/GrothendieckDelta.cs,Apps/ga-server/GaApi/Services/ContextualChordService.cs,Common/GA.Business.Config/ModalInterchange.yaml,Common/GA.Business.Config/YamlKnowledgeLoader.fs,GA.Data.MongoDB/Services/DocumentServices/YamlKnowledgeSyncService.cs,GA.Data.MongoDB/Extensions/ServiceCollectionExtensions.cs,GA.Data.MongoDB/Services/MongoDbService.cs,GaCLI/Program.cs.