feat(editor): keys parts get a playability lint too#356
Conversation
|
Warning Review limit reached
Next review available in: 19 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Keys were the one instrument with NO advisory playability lint: the pass
is fret/anchor-shaped, so `_lintResults()` bailed to an empty result on
`isKeysArr()` — a keys chart could ask an impossible reach and nothing
flagged it.
A piano lint now runs for keys parts instead of bailing, over each
onset-clustered simultaneity:
- keys-span one HAND (by the per-note lh/rh assignment) reaching over
an octave (a look) / over a 10th (beyond most hands);
- keys-hand more than five notes in one hand at once (five fingers);
- keys-muddy-low the two lowest simultaneous pitches within a major
3rd, below ~E2, where close intervals turn to mud.
Span/count use the authored hand where present (assign hands to get that
feedback — unassigned notes are skipped there); muddy-low is pitch-only,
so it runs regardless. Same advisory posture as the fretted lint (yellow
underline + count chip + popover, never blocks). Thresholds are exported
named constants for the pedagogy seat to tune. Large-hand exception and a
hand-leap/impossible-shift rule are noted as follow-ups.
Tests: tests/keys_lint.test.mjs pins the rules (octave is fine, over it
warns, over a 10th escalates; span is PER HAND so a wide two-hand voicing
is fine; unassigned skipped; >5-in-a-hand; muddy-low high/open negatives;
onset clustering) AND the wiring (_lintResults now yields keys issues +
flags the notes, empty on main). npm test green apart from the two
known-on-main reds; pytest untouched; lint clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xGPjDBF8NTwTK7VQvizix
Signed-off-by: ChrisBeWithYou <chris@rifflarr.local>
8a63d6e to
d52a3af
Compare
The gap
Keys were the one instrument with no advisory playability lint at all. The lint pass is fret/anchor-shaped (stretch/overlap/open-bend/legato/finger-conflict), so
_lintResults()just bailed to an empty result on any keys arrangement (|| isKeysArr()). A keys chart could ask a physically impossible reach and nothing flagged it. This closes the "keys parts get NO playability lint" gap called out inEDITOR-NEXT-WINS§2 Step C.What it lints
For keys parts, a piano lint now runs (instead of bailing), over each onset-clustered simultaneity — using the pedagogy seat's thresholds:
keys-span— one hand (grouped by the per-notelh/rhassignment) reaching over an octave (a look) / over a 10th (beyond most hands,KEYS_SPAN_ERR). An exact octave is fine.keys-hand— more than five notes in one hand at once (a hand has five fingers).keys-muddy-low— the two lowest simultaneous pitches within a major 3rd, below ~E2, where close intervals turn to mud.Span/count use the authored hand where present — assign hands (the merged hand-arc) to get that feedback; unassigned notes are skipped there.
muddy-lowis pitch-only, so it runs whether or not hands are assigned. Thresholds are exported named constants so the pedagogy seat can tune them without reading the rules.Same advisory posture as the fretted lint — a yellow underline on the flagged notes, the count chip, and the click-to-seek popover (labels added for the three keys rules). Never blocks, never auto-fixes.
Scope / deferred
Per the pedagogy spec, two refinements are noted as follow-ups rather than pulled in: a large-hand exception flag on the 10th error, and a hand-leap / impossible-shift rule (a same-hand leap over a 12th faster than ~150ms). Both are additive to the same pass.
Tests
tests/keys_lint.test.mjspins the rules — an exact octave is fine, over it warns, beyond a 10th escalates; span is PER HAND (a wide two-hand voicing is fine); unassigned notes aren't span-linted;>5-in-a-hand; muddy-low's high-register and open-interval negatives, and that it judges the two lowest pitches; onset clustering — and the wiring:_lintResults()now yields keys issues and flags the reached notes (empty onmain).npm testgreen apart from the two known-on-mainreds (mixer_meter_teardown,song_fit); pytest untouched (JS-only); lint clean (0 errors).🤖 Generated with Claude Code