Skip to content

note identifier exercise + retire legacy playable_keyboard path

jedmund requested to merge jedmund/note-identifier into main

Created by: jedmund

Summary

Four commits adding the note_identifier scored exercise, migrating every prompt-mode lesson onto it, retiring the legacy playable_keyboard scored-exercise path, and sharpening a few pieces of surrounding UX.

  • fde3c5e note identifier: add scored exercise, retire legacy playable_keyboard exercise path. New note_identifier type built on the ScaleBuilder pattern (flash-red/shake on wrong, flash-green/advance on correct, ScoringOverlay wrap). Homepage gets a tile before Scale Builder. Migrates 8 prompt-mode lesson exercises (1-1 through 1-6 and 2-1), moves "Seven from Twelve" to scale_builder via its existing guided_sequence support, and drops "Blues Playground" from the scored list. Lesson 1-1 configs gain bold-markdown prompt names; ex2 grows from 8 to 10 prompts so every black key is covered twice. Retires PlayableKeyboardState, ExerciseStateRegistry.exerciseState(for:), the PageContainer legacy branch, and the prompts/shufflePrompts/Prompt fields on PlayableKeyboardConfig. ExerciseStateRegistry now guards restoration against zero-total progress records (the old path could persist total=0 and corrupt the restored state).
  • dd72f71 scoring overlay: render markdown answers, split two columns at 10+ prompts. Review rows parse PromptResult.answer (and correctAnswer) through AttributedString(markdown:) so bolded note names render correctly. 10+ prompts split into two side-by-side columns so the card stays a reasonable height.
  • 332267f docked keyboard: drop -200 background overextension. The docked keyboard's dark background had a -200pt negative bottom padding to conceal the seam during the Playground slide-up animation. On lesson pages it was bleeding into the next page during scroll transitions. Removed. If the Playground seam returns, it can be concealed as a Playground-only modifier.
  • 399993f claude.md: document CurriculumRegistry as source of truth. Future agents kept assuming lessons/*.json is loaded at runtime (it isn't). The real curriculum structure lives in synthesize/synthesize/SampleData/CurriculumRegistry.swift as a Swift literal, and that's what CurriculumStore reads. Added this to the root CLAUDE.md and Views/Tools/CLAUDE.md's grep targets, and clarified which directories actually get loaded by ContentLoader.

Test plan

  • Playground: Note Identifier tile appears before Scale Builder in the Exercises section.
  • Launch it standalone: answer a few prompts, wrong taps flash red and shake, correct taps flash green and advance. Scoring card + retry works. Configurator sidebar toggles shuffle/accidentals/enharmonic/octave-range/total-questions and a restart respects them.
  • Lesson 1-1 "Locating the Twelve" renders the new exercise with bolded prompt note names; completing it shows a 12-row single-column review with bold note names.
  • Lesson 1-1 "Same Key, Two Names" shows 10 prompts; completion review splits into two 5-row columns.
  • Lessons 1-2 ex1, 1-3, 1-4, 1-5, 1-6, 2-1 all render Note Identifier as their first-exercise slot.
  • Lesson 1-2 "Seven from Twelve" runs as Scale Builder via guided sequence (C major scale ascending).
  • Lesson 2-6 no longer lists "Blues Playground" as a scored exercise.
  • Stale progress guard: a lesson-scoped activity with a legacy total=0 record does not surface as "X of 0 correct"; the exercise plays fresh and overwrites the record on completion.
  • Lesson scroll transitions: the docked keyboard's dark background no longer bleeds into the page below.
  • Playground PlayableKeyboard tool still works (free-play + optional guided sequence); it no longer shows the old prompt/completion chrome.

Merge request reports

Loading