-
feat(lint): pvlint — the bugs that silenced this rig, encoded as rules · 81eb4dc0
Three evenings this week went to bugs that were VISIBLE IN THE TEXT and that no eye caught mid-set, because none of them produce an error message. They produce silence, on stage: * desire.tidal — `off 0.125 (|+ note 12 . (|* gain 0.6))`. `.` binds looser than application, so this composes a FUNCTION into a ValueMap. GHC refuses the whole block, and since a blank line is Tidal's block separator, ONE character silenced nine orbits while the file looked perfect on screen. * you_my_sunshine.tidal — a local `let gF3 = (# djfbus 3 (range 0.05 0.95 "^51"))` shadowing the global helper we had already fixed. SuperDirt maps djf through linexp(0, 0.5, 20, 10000): bypass is 0.5, and 0.05 is a ~26 Hz low-pass. Four orbits (d5/d7/d9/d11) inaudible until a knob crossed centre. * the #55 mute-bomb — an untouched `^NN` yields NO events, so `range a b "^NN"` is `silence`, not a number. All three are static properties of the file, so they belong in a linter. Seven rules, each earned by a real failure: PV001 local djfbus shadow (with an autofix that deletes the line so the track inherits the corrected global), PV002 operator-section composition (autofix adds the missing parens), PV003 double-applied global gain, PV004 shared cut group, PV005 duplicate orbit in one block, PV006 sample index past the end of its folder, PV007 orbit inventory (the input to the orphan-orbit transition check, `--setlist`). Three of my own rules were wrong on first contact with the corpus, and the corpus caught all three — which is the argument for running a linter against 694 real files before trusting it: * PV002 was string-blind and called four mini-notation `.` separators compile-killers (`"k ~ ~ k . ~"` is grouping, not composition). 13 findings -> 0, all of them false. * PV003 claimed the whole 77-84 fader bank was "owned by Ardour" and raised 1109 errors. BootTidal itself reads `^77` (midiGGlobal); reading a fader CC is the documented convention. Narrowed to the actual hazard — ^77 applied twice — and demoted to a warning. * PV005 flagged every re-declaration of an orbit, but keeping several evaluable versions per file is normal live practice. Scoped to one block: 576 findings -> 32. * PV006 pooled all indices in an orbit against all folders and invented a finding on d8 (n=24 is org_jungle_breaks', not breaks165's). Also fixed the parser: ORBIT_RE demanded a same-line `$` and so dropped d5 from you_my_sunshine's inventory WHILE THE TRACK WAS PLAYING IT — PLN writes `d5 -- comment` with the `$` on the continuation line, which Haskell's layout rule allows. A linter that under-reports is worse than none. Corpus after the corrections: 694 tracks, 316 errors (all PV001 shadows, in archive material), 281 warnings. First real run found a live one — d5 and d11 of you_my_sunshine share cut group 5, so the voice and the chop truncate each other. 33 unit tests, every negative case a real corpus line that an earlier rule version wrongly flagged.PLN (Algolia) authored81eb4dc0
×