feat(editor): author teaching marks fg/ch/sd in the note inspector (§6.2.2) - #16
Merged
Merged
Conversation
…6.2.2) Author the three optional per-note teaching marks, mirroring the bend-shape authoring (#13). Display only — these never affect grading. - screen.js: a @pure:teaching-marks block (FRET_FINGER_OPTIONS + nextUnusedStrumGroup) and SetTeachingMarkCmd (one undoable batch edit per field, snapshot/rollback per note). Inspector gains a fret-hand-finger picker (fg, -1..4), a scale-degree override field (sd, -1..11; blank/-1 = auto), and Group/Ungroup-as-strum buttons (ch — Group assigns the next unused key across the selection, Ungroup clears it). All routed through S.history.exec. - routes.py: fret_finger/strum_group/scale_degree join _NOTE_TECH_FIELDS so they load (_tech_dict) and feed the content signature; the wire serializer emits fg/ch/sd default-omitted (matching core), and the chart-XML export writes fretFinger (core's _parse_note reads it). getattr-over-fields sites default to -1 so a core build predating the marks doesn't break load/alignment. Tests: tests/teaching_marks.test.js (@pure extract — FRET_FINGER_OPTIONS + nextUnusedStrumGroup edge cases); test_xml_export.py round-trip for fg/ch/sd through the wire + fretFinger through chart XML, plus default-omit assertions. Part of got-feedBack/feedBack#334 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 21, 2026
byrongamatos
added a commit
that referenced
this pull request
Jun 21, 2026
…itted (#17) Post-merge Codex review of #16 noted the backend serializer emitted fg/ch/sd whenever != -1, so a malformed or hand-edited out-of-range value (the inspector clamps, but loaded data may not) could be saved as a schema-invalid teaching mark (spec §6.2.2: fg 0–4, sd 0–11, ch ≥ 0). - _arr_dict_to_wire: emit fg only when 0≤fg≤4, ch only when ≥0, sd only when 0≤sd≤11; out-of-range is treated as unset (omitted) rather than emitted or fabricated into a nearest finger. - chart-XML fretFinger: new _fret_finger_attr collapses out-of-range to -1 so it can't round-trip an invalid finger into core's _parse_note. +2 tests (out-of-range omitted / collapsed; in-range boundaries still ride). 60 xml-export tests pass. Codex-reviewed: clean. Part of got-feedBack/feedBack#334. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
byrongamatos
added a commit
that referenced
this pull request
Jun 21, 2026
…6) (#21) Add E1 chord-inspector authoring for the two feedpak 1.7.0 harmony annotations, mirroring the teaching-marks editor work (#16/#17): - voicing (TEMPLATE): a select in the chord inspector, undoable via the existing EditChordTemplateCmd. Added to relinkChordTemplate's carry-forward set so the save rebuild doesn't BLANK it (same E0 gotcha as name/displayName/fingers/arp). - fn (INSTANCE): rn/q/deg inputs, one undo unit (EditChordFnCmd). fn rides the chord instance, so it's keyed by chord time in a transient arr._chordFn map (one chord per time) rather than stamped on movable notes — a note dragged out of a chord can't carry a stale fn into another group. reconstructChords reads the map back and prunes orphans for times that no longer hold a chord. routes.py round-trips both: _song_to_dict hydrates chord fn + template voicing on load; _arr_dict_to_wire emits them default-omitted and range-guarded (new _chord_fn_wire mirrors core's _validate_fn — never a partial/out-of-range fn; voicing only when a non-empty string). Display only — no scoring path touched. Client-side deg auto-fill is deferred: the editor has no active-key/tonic accessor (per-note sd auto-derivation is server-side), so deg is manual 0..11. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 got-feedBack/feedBack#334
PR 3 of 3 for the teaching marks epic (feedpak 1.5.0 §6.2.2). Adds editor authoring for the three optional per-note marks, mirroring the bend-shape authoring (#13). Display only — these never affect grading.
Authoring (
screen.js)The note inspector gains a Teaching marks section:
fg) — a fret-hand-finger picker (Unset / Thumb / Index / Middle / Ring / Pinky).sd) — a numeric override field (-1..11); blank /-1= auto-derive (the highway derives it from the active key when no override is set).ch) — Group assigns every selected note a shared, unusedchkey (one strum/rake gesture;pkdgives direction) and Ungroup clears it. The header shows the selection's shared group (#N/—/ mixed).Each edit is one undoable batch (
SetTeachingMarkCmd, snapshot/rollback per note) routed throughS.history.exec. New pure helpers live in a@pure:teaching-marksblock:FRET_FINGER_OPTIONSandnextUnusedStrumGroup.Save round-trip (
routes.py)fret_finger/strum_group/scale_degreejoin_NOTE_TECH_FIELDS, so they load (_tech_dict) and participate in the content signature used for arrangement alignment.fg/ch/sddefault-omitted (matching core'snote_to_wire), for both standalone and chord notes.fretFinger(core's_parse_notereads it back);ch/sdare wire-only (no core chart-XML attribute), as intended.getattr-over-_NOTE_TECH_FIELDSsites default to-1so a core build predating the marks can't break load/alignment.Tested locally
python -m pytest tests/→ 65 passed, 2 skipped — includes newtest_xml_export.pycases:fg/ch/sdround-trip through the wire, default-omit when unset, andfretFingerthrough chart XML.node tests/teaching_marks.test.js→ 5 passed (FRET_FINGER_OPTIONSorder +nextUnusedStrumGroupedge cases via the@pureextract).node tests/bend_shape.test.jsstill passes;node --check screen.jsclean.Scope notes (per the epic)
sdis override + display only — full "auto from an active-key lane" UI is out of scope (there is no key-editing lane yet).🤖 Generated with Claude Code