feat(core): carry chord harmony fn + template voicing on the wire (§6.3.1, §6.6) - #540
Merged
Conversation
….3.1, §6.6)
Add two OPTIONAL per-chord harmony annotations (feedpak 1.7.0), mirroring the
teaching-marks (fg/ch/sd) wire work:
- Chord.fn (instance): {rn, q, deg} harmonic-function object, key-dependent.
Validated by _validate_fn on BOTH decode and emit so a partial / out-of-range
fn (which would fail the schema's required-keys rule) never rides the wire.
Default-omitted, mirroring bend bnv.
- ChordTemplate.voicing (template): key-independent voicing-type string
("open", "triad", "shell", "drop2", "barre", ...). Emitted only when
non-empty; non-string wire values fall back to "".
Display/teaching only — never fed to a grader (honesty rule). fn auto-derivation
is DEFERRED (carry-only): a complete rn/q needs chord-quality analysis, and a
deg-only fn would be schema-invalid, so server.py carries author-provided fn
unchanged. GP import unchanged (no reliable per-chord function/voicing).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 21, 2026
13 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #334
PR 1 of 3 (stacked) implementing the per-chord harmony annotations from feedpak 1.7.0 (FEP #24). This PR is the core wire carry; renderer (PR2) and editor authoring (PR3) follow.
What
Two OPTIONAL per-chord harmony annotations, mirroring the teaching-marks (
fg/ch/sd) wire work (#536):Chord.fn(chord instance, §6.3.1):{rn: str, q: str, deg: int 0..11}harmonic-function object. Key-dependent, so it rides the instance. Validated by_validate_fnon both decode and emit — a partial or out-of-rangefn(which would fail the schema's required-keys rule) never rides the wire. Default-omitted, mirroring bendbnv.ChordTemplate.voicing(chord template, §6.6): key-independent voicing-type string ("open","triad","shell","drop2","barre", …). Emitted only when non-empty; non-string wire values fall back to"".Honesty rule
Display/teaching only. Nothing here is wired into scoring / NoteVerifier.
Deferral: fn auto-derivation = carry-only
The spec requires all three keys when
fnis present.degcould be derived from the chord root, but a completern/qneeds real chord-quality (interval) analysis — out of scope — and adeg-onlyfnwould be schema-invalid. Soserver.pyis unchanged: it carries author-providedfnand derives nothing. Author-providedfnalways wins by construction.caged/guideTonesfrom the FEP are also deferred per the spec.GP import is unchanged — GP files have no reliable per-chord function/voicing.
Tested locally
pytest tests/test_song.py→ 134 passed (round-trip, omit-when-default, malformed/partial/out-of-range →None, emit-side validation of directly-constructed chords, voicing fallback).fn) — fixed by validating on emit too; re-review clean.tests/test_diagnostics_redact.py::test_song_filename_redacted_consistentlyfailure on cleanmainis not touched here.CI may be red on infra; the above was verified locally.
🤖 Generated with Claude Code