1. 07 Jun, 2026 2 commits
    • feat(sample-meta): L1 filename-metadata harvester (free per-file signal) · 521127ff
      RIFF chunk dump proved samples carry NO semantic embedded metadata (only encoder
      tags) — the Pulsar browser shows FILENAMES. So harvest the filename: leading pad
      index + instrument-token lexicon → fleet family + source hint. Conservative: opaque
      names (JUPI, doing_it_right, 808hc's 'HC') stay family=None → fall back to audio.
      Detects kit-like folders (≥2 families by name), the 'jazz is a kit' case.
      Corpus coverage: 49% folders / 31% files named, 36 kit-like folders.
      PLN (Algolia) authored
    • perf(sample-classify): batch CLAP per folder + parallel decode + progress · acf6a7c1
      One forward pass per folder (text tower computed once) instead of per-file —
      ~Nx fewer forwards; ffmpeg decode on a thread pool. validate prints a live
      [i/N] running-accuracy line. source field now reflects method:mode.
      PLN (Algolia) authored
  2. 06 Jun, 2026 15 commits
    • feat(sample-classify): fine ontology + PANNs + ensemble methods · bb70f394
      Per PLN: richer ontology + PANNs/AudioSet + ensembles for sample grounding.
      - sample_ontology.py: 99 fine descriptors across the 12 families ('this is the
        sound of {a reese bass}'); scored per-descriptor then marginalized to family.
        CLAP fine: 58% -> 68% top-1 (coarse super-family 76%) vs the noisy name truth.
      - sample_panns.py: PANNs Cnn14 (AudioSet 527) -> conservative label->family map ->
        per-family prob vector. ffmpeg @32k, zero-pad short one-shots (Cnn14 needs >=1s
        of mel frames or conv5 collapses). Weak on electronic one-shots (AudioSet
        'Clapping'=applause, not a drum-machine clap).
      - sample_classify.py: --method clap|panns|ensemble, --fine|--coarse. clap_vector()
        exposes the family-prob vector; ensemble = mean of CLAP+PANNs vectors -> argmax.
      
      Scoreboard (vs name-heuristic, itself noisy): clap-coarse 58% | clap-fine 68% |
      panns - | ensemble - (head-to-head primed, not yet run). Stubborn residual =
      bass<->kick one-shot (spectral decay tiebreaker is the next lever).
      PLN (Algolia) authored
    • feat(sample-classify): CLAP zero-shot sample-family analyzer (katana) · 3e14a623
      Ground sample families by LISTENING, not by name. sample_classify.py runs
      laion/clap-htsat-unfused (transformers, torch CPU) over Dirt-Samples one-shots,
      scoring each against text prompts for the 12 fleet families; aggregates per folder
      (dominant + homogeneity → kits show as mixed). ffmpeg audio I/O, no librosa.
      validate/run/one commands; validate measures top-1 vs the name-confident folders.
      
      Finding (validate): 58% top-1 agreement with the name-heuristic at fine 12-way.
      KEY: the name 'ground truth' itself is wrong in many disagreements — CLAP correctly
      calls 808hc/808mc congas (perc), which the name-classifier mislabeled bass via '808'.
      CLAP is near-perfect on vox/break/clear-bass/kick/keys; the genuinely fuzzy zone is
      the melodic cluster (synth/lead/keys/pad). Prompt-tuning is whack-a-mole on noisy
      truth. Conclusion: trust CLAP coarsely, not at fine 12-way silently.
      PLN (Algolia) authored
    • fix(classifier): refuse to guess kits + source-named folders; fix sept1 morpher · e9bba22c
      PLN-flagged chain of labeling errors, traced to the SSOT classifier:
      - 'jazz' was matched to BREAK, but jazz is a multisample KIT (jazz:0=kick,
        :1=snare/hat…). A folder name is not a reliable family signal: it may be one
        family, a heterogeneous kit, or a demucs grab named after a SOURCE song
        (wap, take5, the_revolution, xplosive, rample*). classify_sample_family now
        fires ONLY on names that lexically encode an instrument; everything else is
        None (= needs per-sample analysis). No 'kit registry' (that's name-guessing too).
      - removed over-reaching genre/source tokens: jazz, dnb, jungle, loop from break;
        drum from perc. This also FIXES jungle_pads (→pad, was break) and
        jungle_vocals (→vox). amen kept (amencutup genuinely is the Amen break).
      - tempo: strip Tidal '--' line comments before parsing cps (ton_numero's
        commented-out morpher no longer counts); a track with a live 'cps (range …)'
        is now flagged morph even when it also declares a fixed setcps. morphing=1
        (Septembre 1er, 60→180), was 0.
      - report: + stage_tempo_by_year, sources/roadmap, recurrence gig_slugs,
        classified/unclassified coverage (21% of palette uses need analysis, honest).
      - tests: classifier refuses kit/source names; jungle_pads→pad guard. 60 green.
      PLN (Algolia) authored
    • feat(corpus-viz): hover tooltips + all-dots collab view + copy de-slop · 3f2863d4
      PLN review pass:
      - tooltip layer: hover any mark for the tracks/examples behind it. cloud dots
        (track + bpm + date), tempo line dots (median + what it means), histogram
        bands, gig/sample columns, family segments (count + % + example members),
        idiom bars (plain-language gloss of each phrase), staple bars, collab dots
      - collab story now plots EVERY track as a dot; tracks at the same BPM pile into
        one larger dot (radius ~ count); median drawn as a tick; sample-tell chips get
        lift tooltips. needs tide_eda collab_fingerprint to emit per-track {name,bpm}
      - copy: removed cheap 'not X, Y' contrasts + em dashes per impeccable clarify;
        added 'hover anything' affordance hints
      PLN (Algolia) authored
    • feat(corpus-viz): 'by the numbers' scrollytelling dataviz (task #64) · 33d49591
      Phase-2 infodesign of the tide_eda corpus EDA: a standalone, scroll-driven
      data essay (corpus.html) on the Ship's Bridge dark instrument language.
      
      Six curated stories, vanilla SVG (zero npm deps), measured-width responsive:
      1. the slow climb — studio vs club tempo, dual median lines + track cloud +
         histogram + felt-vs-written 2x inset; studio<->club lens is first-class
      2. 2024 breakout — vocab burst + gig cadence on a shared time axis, magenta
         reserved for the one earned 2024 accent
      3. palette — 12 sample families as a proportion bar, fleet colors + glyphs
      4. the accent — signature gMask/gMute idioms (f*16 in 62/73)
      5. collab fingerprint — per-collab bpm range + distinctive samples (raph fast)
      6. set-staples — recurrence, Cafe trilogy highlighted
      
      - tide_eda: add stage_tempo_by_year (gig-date x track-tempo) for the club lens
      - build_corpus.py + 'tide.py corpus': inline-bundle to one self-contained file
        for deploy to me.nech.pl/parvagues/viz (dist/ gitignored)
      - IntersectionObserver reveal/lazy-draw, reduced-motion + mobile reflow,
        load-fail banner; lens auto-disables on single-lens sections (honest)
      - 59 tests green
      PLN (Algolia) authored
    • docs(corpus-viz): confirmed design brief + implementation spec (task #64) · 830d2dd1
      Phase-2 infodesign brief from /impeccable shape: standalone scrollytelling
      'ParVagues, by the numbers', 6 curated stories on the fleet color language,
      studio<->club toggle as first-class lens, vanilla SVG no-deps, deploy static
      to me.nech.pl/parvagues/viz. Exact eda_report.json field->chart map for a
      clean post-compact build.
      PLN (Algolia) authored
    • feat(backlog_setlists v2): explicit ends, label-strip, leet fallback + tests · 9a428b6e
      - ANCHORS support (slug, end_line) to bound bleeders (mephisteuf/opal-2025/
        38c3-toilet) into clean blocks — no more swallowing neighbour setlists.
      - clean_track_line: strip leading set-position labels (Intro:/Finale:/Sunset),
        keep 'Label: Name' / drop 'Name: gloss'; recovers the LIVE-Noctambule pattern.
      - leet_fold fallback (B00K→book, T01l3ts→toilets, G00D→good) — resolves only
        after a straight miss so genuine digits (sept1) still match first.
      - 9 gap gigs recovered (opal-2024 14/14, algolia-fdlm 26/26, 39c3 13/14…).
      - 6 mechanical tests (leet, label, gloss, bpm/transition, ascii/comment skip,
        real-backlog coverage guard). 59 pass.
      PLN (Algolia) authored
    • fix(eda holes): canonical sample classifier + style normalization · 21d003dd
      - models.py: add classify_sample_family() SSOT (token-aware, DM-suffix gated,
        strong-contains fallback) + extend SAMPLE_FAMILIES cues → unclassified 89→34
        uses (~93% classified); honest unknowns (armora, 90s_matrix) stay None.
      - models.py: STYLE_ALIASES + norm_style() merges nu-jazz/nujazz, breaks/breakbeat,
        chip/chiptune, hip-hop/hip so the style chart is honest.
      - tide_eda + tests use the canonical classifier (DRY); +3 mechanical tests
        (token cases, no-overreach incl. the shil-'oh' FP, style norm). 53 pass.
      - regen tokens (cues feed match[] arrays).
      PLN (Algolia) authored
    • feat(tide_eda): phase-1 EDA over the corpus (tempo, collab, pairings, time) · f7132e2d
      Reusable data-scientist pass that finds the stories before any viz:
      - TRUE tempo parsed from setcps (corner A), vs metadata bpm (C), with AC delta
        (most conflicts are exact 2× half-time/double-time notation, not errors)
      - studio tempo (git-creation date) vs stage tempo (gig date) — the creep 110→126
      - collab fingerprint: bpm profile + lift-distinctive samples per collaborator
        (raph outed as the fast/club one ~138bpm; nova-solo ~117)
      - sample pairings: lift-ranked co-occurrence, ad-hoc 'pair <prefix>' query
      - cadence (all 37 canonical gigs), sample-family split, signature idioms,
        set-staples, vocabulary growth (Dirt-Samples symlink mtime, 334-pack Jul'24 burst)
      Emits eda_report.json (tidy cuts for the viz phase).
      PLN (Algolia) authored
    • feat(backlog_setlists): recover gig setlists from backlog.md → resolved .tidal · 5acf72f7
      The site tracks.json covers only 23/37 gigs; the rest live in backlog.md as
      codename-keyed setlist blocks. New mechanical parser cleans the noisy lines
      (ASCII-art, emoji, emphasis, inline [bpm]/{transition} notes, commented-out
      tracks) and resolves names to canonical .tidal paths via the catalog's own
      alias index (DRY). Gig-codename→slug mapping is authored (confirm:-flagged
      when uncertain); suspect_bleed flags blocks that swallowed a neighbour list.
      6 gigs cleanly recovered (52 track-slots); seam is larger (dozens of setlists).
      PLN (Algolia) authored
    • fleet color language + triangle UX redesign (impeccable pass) · 6815967f
      ontology in models (SSOT) → generated tokens:
      - models.py: OntologyTerm + ColorFamily; ROLE/LIFECYCLE/AGREE terms (color+glyph+
        label) and an authored 12-family SAMPLE-WORLD model (hue-anchored). Variation =
        OKLCH lightness ladder + ±8° hue-fan → 8 shades/family = 96 sample slots. Sample
        axis (conceptual) kept separate from the measured-register axis (ROLE_FAMILIES).
      - tools/gen_tokens.py: OKLCH→sRGB (no deps) → tokens.css (armada/ui) + tokens.json
        (triangle fetches at runtime, overrides :root). Validated vs DesignTokens. New
        tide.py 'tokens' step. Never hue alone (glyph+label per term).
      
      triangle UX (low cognitive load, clear hierarchy):
      - header calm at rest: one title line, one quiet coverage line, and the agreement
        bar is now the interactive sea-state instrument (overview + legend + level filter
        in one) — replaces the duplicated chips+stack+pills.
      - faceted full-text search: free terms + scopes (sample:/gig:/phrase:/take:/style:/
        name:), covers the pattern registry, with 'matched-in' hints so results never feel
        mysterious; '/' focuses, clear button, teaching empty state.
      - sound chips colored by sample family (shared lexical classifier from tokens),
        glyph-paired; agreement painted from the ontology (unparsed no longer red).
      - tests: 51 green (OKLCH math, shade ladder greyscale-distinctness, ontology
        integrity, unparsed≠conflict, DRY tokens contract, classifier examples).
      PLN (Algolia) authored
    • triangle #60: surface pattern registry — kin + phrases in drawer, Clusters view · aa0de028
      - drawer 'patterns & kin' section: a track's nearest tracks (shared n-gram
        similarity, clickable to jump) + notable phrase chips ( shared idiom /
        ⟳ repeated section), click a phrase to filter the table to who else plays it
      - Clusters view toggle: connected components of the neighbor graph rendered as
        family cards (members + the shared phrases that bind them) + a distinctive/solo
        roster. 8 families + 54 solos on the real corpus
      - pattern_registry.json loaded best-effort alongside catalog_view.json
      PLN (Algolia) authored
    • tide-table: load-once viz (embed source/audio), usability, #56 take-filter, #59 pattern n-grams · dc8af085
      - triangle viz loads once: .tidal source embedded per-row in catalog_view.json
        (no per-file fetch / relative-path fragility); take audio resolved at build
        time so a player only renders when a proxy exists; data-load failure banner
      - usability: full-width search, fixed colgroup widths, ellipsized sound-lists,
        tooltip'd empty states (corner-C/B gap, not a disagreement)
      - tide.py serve: serves the tide-table dir load-once, prints the triangle URL
      - #56: drop empty/sketch take-types from candidate links (Take63/64 noise)
      - #59 pattern_ngrams.py + PatternRegistry: mini-notation phrases as 'things'
        (unique/repeated/shared), track clustering by sound-token n-gram Jaccard
        (df-filtered + min-shingle guard). 73 tracks -> 1325 phrases, 193 shared,
        33 repeated; surfaces the gMask/gMute boolean idioms + euclid figures
      - tests: 43 green (new guards: no empty/sketch candidates, source embedded,
        audio paths resolve; full UT+IT for the pattern registry)
      PLN (Algolia) authored
    • pipeline driver + generated catalog + ground-truth drawer · 975f9150
      tide.py: one command regenerates every downstream artifact in dependency order
      (track_recording_map → catalog_view → catalog → ts_types) + `tide.py test`.
      
      Demote catalog.yaml (hand-state, no valid-as-of) → generated artifact:
      - catalog.authored.yaml: the ONLY hand facts (license/collab/inspiration/status/
        notes), each with provenance; keyed by .tidal path
      - build_catalog.py: catalog_view ⊕ overlay → catalog.generated.json (73 tracks,
        7 authored), validated against models.Catalog on emit
      - catalog.yaml marked DEPRECATED
      
      Triangle drawer = ground-truth validator (per corner):
      - A: scrollable, syntax-highlighted .tidal source (fetched live) + parsed orbits
      - B: audio player when a take proxy exists
      - C: per-gig bpm/style/dur + external gig link + raw ingredient list (site's claim)
      - search now spans ingredients/samples too
      - enrich catalog_view rows with raw ingredients (+ Ingredient/Catalog models, TS)
      
      Serve from the REPO ROOT so source/audio resolve:
        python3 armada/serve.py --dir . --port 8731
        → /armada/tide-table/triangle.html
      
      30 pytest green.
      PLN (Algolia) authored
    • triangle: catalog confirmation view (A=score ⋈ C=metadata ⋈ B=recording) · 2704f92c
      Reconcile every track across three corners and light the cells where they
      agree or fight, so "is our analysis good?" becomes a measured number.
      
      - build_catalog_view.py: reconciler over 73 tracks; pure build() + thin main(),
        validates against the pydantic CatalogView on emit
      - tidal_score.py: parse indented do-block dN (recovered burn_this_book + 13 more)
      - agree() taxonomy: unparsed / no-claim / agree / partial / conflict / divergent
        — a parser miss is NEVER reported as a disagreement (the cardinal fix)
      - models.py CatalogView → gen_ts_types.py → types.gen.ts (DRY single source)
      - tests/: 28 pytest — parser regressions, agree taxonomy, IT-on-real-data with
        coverage regression guards, DRY contract (mechanically tests the metadata prior)
      - triangle.html: Ship's Bridge lit-cell dashboard (served by serve.py)
      - tasks/013: captain's log
      
      Result: 47 agree / 5 partial / 2 conflict / 3 divergent / 16 no-claim;
      recorded 40/73; EDA coverage 1/63 (the gap, now visible). The first conflicts
      flagged were our own parser bugs — metadata was righter than the machine.
      PLN (Algolia) authored
  3. 05 Jun, 2026 7 commits
    • edl_render: proxy→master alignment + fragment-test loop (#36) · 5bb32aea
      Reframe (per PLN): we split the MASTERED set into shippable units (tracks / EP /
      gapless BC album); we don't touch the gig recording. Source is swappable (online
      streaming_final today; a re-rendered master can drop in).
      
      - align: measure proxy→master offset by xcorr of energy envelopes (proxy from
        stemmap, master decoded). Coarse 2s + fine 0.25s + two-half drift check.
        Result: master_t = proxy_t + 2.75s, stable across halves (peak 0.69-0.80) —
        confirms the manifest's calibrated +3. (Caught + fixed a sign bug on first pass:
        measure, then verify your own number.) Per-source: the +3 was the gig-GT, this
        is the stem-render; same ballpark, but measured not assumed.
      - frag: audition cut variants for a boundary from the real master — context,
        standalone clean edges (trim bleed + fade), and xf_direct (WAP tail acrossfades
        into 'Plosive head, the bordel dropped = PLN's 'crossfade direct de 0326 a 0345').
        Skip window auto-set from the v2 bleed detector. Each render self-verified non-silent.
      - WAP->'Plosive (cut4) rendered: 5 frags @ /frags/ for phone audition.
      
      Next: split (hybrid gapless-exact + standalone-fade outputs) once PLN picks edges.
      PLN (Algolia) authored
    • bleed v2: per-sound spectral novelty on shared orbits (#39) · d19c1220
      v1 only saw a foreign ORBIT lighting up on the wrong side of a cut; it was blind
      to a foreign SOUND on an orbit active on BOTH sides (e.g. breaks playing through
      a transition). v2 (--spectral) closes that:
      - per shared orbit, profile tail/head probe windows + each track's interior ref,
        composite timbral distance (band-shape cosine + centroid shift); flag when the
        tail sounds like the NEXT track (incoming) or the head like the PREVIOUS (outgoing).
      - gated by MIN_REF_DIST (versions must differ) and SPEC_MIN_RMS=-50 (probe must
        have real sound — the silence gate caught 4 of my own false positives).
      - independently flagged the WAP->'Plosive breaks bleed (orbit-08, Delta=0.475) that
        v1 missed = PLN's 'bordel jusqu'a 0342' zone; + Premier Septembre->Techno Orage.
      - EDL now 9 ear + 7 orbit + 6 spectral derived rows; round-trips through MasterEDL.
      
      Delta = severity rank; live crossfades blend by design, so PLN's ear gates feel.
      PLN (Algolia) authored
    • judge: derive orbit labels from score, graded activation, DRY types, waveform zoom/loop · 91a9ac89
      #40 Judge annotations were stale+wrong: labels came from a hardcoded ROLE_MAP
      (orbit-03 'hats' though punkachien.tidal plays 'dr'; d6/meth_bass missing) and a
      hard -38dB on/off gate hid audible orbits that dip within a 2s bin (PLN saw only
      d3 OR d8 while hearing both).
      - tidal_score.py: parse per-orbit sound map from any .tidal (reuses tfidf vocab;
        also accepts the bare $ "sample" source form). dr/meth_bass/jungle_breaks now correct.
      - audio_lens: classify_family() (breaks->tops, drums->percs by identity, register
        by measured centroid), profile peak_db. Fix orbit_files to try padded+unpadded
        channel names (Take89 uses 'Tidal 01-1' -> centroids were silently None).
      - build_player_data: labels from score, family validated by centroid, two
        thresholds (litFloorDb -52 visible / activeDb -38 driving), emits validated PlayerData.
      - OrbitRail: graded activation (dim->vivid), no orbit vanishes when quiet.
      
      #42 DRY: pydantic models in models.py are the single source of truth; gen_ts_types.py
      generates ui/src/types.gen.ts (types.ts is now a re-export). No more hand-synced shapes.
      
      #41 WaveformPlayer: Audacity-style zoom (+/-/ctrl-wheel) + scroll, drag-select a span
      and loop it (Regions plugin), keyboard L=loop. tsc + vite build green.
      PLN (Algolia) authored
    • feat(boundary_bleed): auto-detect cross-boundary sound leaks → EDL · 9089a988
      Embodies the division-of-labor principle: the machine flags OBJECTIVE boundary
      leaks so PLN's ears judge only feel. Detector = exclusive-orbit ignition: at each
      cut, an orbit core to one neighbour but not the other, lit on the wrong side (down
      to a sensitive -55dB floor for quiet foreign onsets).
      
      Validated on Take89 (Montreuil): independently caught BOTH of PLN's hand-flagged
      bad_cuts — cut1 (Take5 bass pre-echo, "changement de basse avant le cut") and cut5
      (Plosive→Jeudi Drill, the Bogdan stabs on d9/orbit-09, ~-48dB) — plus 5 new
      candidates. Auto-populates master_edl_take89.json: 16 edits = 9 ear + 7 derived.
      
      Mapping nailed down (was wrong first pass): stemmap orbit-NN == dN; Tidal's
      `# orbit X` is SuperDirt-0-indexed → d(X+1) (so `# orbit 8` == d9). d8 = always
      breaks. Honest coverage cap logged: a foreign SOUND on a shared+active orbit is
      invisible at orbit level → v2 = spectral/per-sound novelty.
      PLN (Algolia) authored
    • feat(tfidf): index synths as sound sources; identify Take35 = Septième Armée · ce494fda
      PLN: "samples and synths are the same class for fingerprinting." sample_tfidf now
      indexes synthdef names (SC synthdefs/ + SCLOrkSynths quark + SuperDirt builtins)
      alongside Dirt-Samples, tags each sound sample|synth, and persists kinds. vocab
      871 sounds (293 samples + 63 synths used). septieme_armee signature now surfaces
      moogBass/FMRhodes1/bassWarsaw — but all common (no rare tell): its identity is the
      orbit-arrangement (the SNA riff), not a signature sound. L3 needs both signals.
      
      Take35 identified by blind ear-test as Septième Armée (Seven Nation Army cover,
      septieme_armee.tidal, 4:35), NOT the 38C3 "Pitbul Punk" the ±3d date-join guessed.
      Corroborated by orbit→sound map (d4 bassWarsaw = the riff bass, etc.). take_gig_map
      corrected; performance_notes logs the find + cover-license caveat.
      PLN (Algolia) authored
    • feat(audio_lens): reusable spectral "ears" + self-verifying stem mixer · 78f564ff
      audio_lens.py consolidates the spectral toolbox (profile / stemmap / mix) so the
      machine catches OBJECTIVE audio defects autonomously, reserving PLN's ears for
      subjective feel.
      
      - profile(file): band-energy % + centroid → is_broadband() gate (centroid >140Hz
        and >18% energy above 150Hz). A pure-kick mix is centroid ~111Hz, mid<12% → FAIL.
      - mix(take, --orbits): EXPLICIT numpy sum of local interchange stems (no amix black
        box, no freebox), peak-normalized, then SELF-VERIFIES the render is broadband and
        exits non-zero on FAIL. Caught + fixed the kick-clone bug that shipped twice.
      - stemmap(take): per-orbit activity (driving/sparse/silent) for arrangement reads.
      
      Take35 mix rebuilt via the tool (v3): cen 168Hz, mid present, PASS — replaces the
      two broken kick-clone mixes (deleted). Lesson: measure your own output; extend the
      toolbox, no /tmp throwaways.
      
      EDL: seed_edl_take89.py + master_edl_take89.json (9 typed edits, 3 bad_cut labels)
      from PLN's WH-1000XM5 review, logged in performance_notes.md. tasks/011 captures the
      TF-IDF + verify-your-output story. #25 reframed: auto-detect boundary sample-leak.
      PLN (Algolia) authored
    • feat(armada): tidal→tracks tooling — locate-matrix, sample TF-IDF, pydantic models, master EDL · cb010b96
      First versioned import of L'Armada (media/marketing toolbox) plus this session's
      tidalcycles→tracks tooling work. Audio kept out of git (armada/.gitignore).
      
      Tooling:
      - tools/sample_tfidf.py — sample TF-IDF over the local .tidal corpus (772 docs).
        Vocabulary = local Dirt-Samples folder names (custom packs symlinked in);
        sound-context extraction (s/sound/#) so mininotation booleans don't pollute.
        Derives discriminative samples: PunkAChien = vec1_acid(df18)+cpluck(df23);
        jungle_breaks(df78) is common filler. → sample_tfidf.json (validated).
      - armada/tide-table/models.py — shared pydantic v2 models: Provenance, LocateCell,
        MasterEDL/MasterEdit, TfidfReport. Typed, JSON in/out, provenance-carrying.
      - armada/tide-table/locate-matrix.md + build_track_recording_map.py — L0 metadata
        map (site tracklists × take_gig_map), canonical track id = .tidal path.
      - armada/tide-table/seed_edl_take89.py + master_edl_take89.json — PLN's phone+
        WH-1000XM5 resplit review as 9 typed edits (3 bad_cut = detector ground-truth).
      - armada/serve.py — Range-capable LAN static server for phone audition.
      - armada/ui/ — Vite+React+TS+Tailwind Judge pilot (Ship's Bridge design system);
        PRODUCT.md + DESIGN.md design language.
      
      Correction captured: the "Hamburg PunkAChien" was a misID (Insouciance→Liquid
      Finale @ 39C3); real 38C3 PunkAChien = Take35 (pending ear-verify). meth_bass/d6
      silence is a controller-ergonomics artifact, not a track tell — dropped as a
      fingerprint feature. See performance_notes.md, tasks/010 + 011.
      PLN (Algolia) authored
  4. 02 Jun, 2026 3 commits
    • live: latest tracks, backlog, perf + analysis tooling · b407cc0f
      Sync-up of the workspace: edits across nova/collab tracks
      (quand_on_decolle, take_5_drops, punkachien, jeudrill,
      sunny_side_up, plosive, wap, perfect, techno_orage, ...),
      new collab/solo pieces (mains_libres, the_revolution_will_be_sampled,
      bois_bumbum, do_it_right, bullet_train), backlog/CLAUDE.md
      project notes, perf.sh (CPU governor helper), and the
      analyze_samples / fan_check / shipowiz tools.
      PLN (Algolia) authored
    • feat(tools): vendor pulsar-parvagues-hud package · ad30f3d5
      Pulsar editor plugin rendering a track-aware HUD topbar
      (role colors, LCXL spatial layout, header_comments). Was
      sitting loose at ~/Work/Tools/pulsar-parvagues-hud with no
      git; vendored into tools/ so the package travels with the
      livecoding workspace and can be shared in one clone.
      
      node_modules excluded; run `apm install` (or `npm install`)
      inside the dir to set up.
      PLN (Algolia) authored
  5. 19 Apr, 2026 2 commits
  6. 21 Mar, 2026 1 commit
  7. 20 Mar, 2026 8 commits
    • wip(copycat): pyin bass transcription — Bb1F2 vamp, not V chord arp · c5066aa1
      TODO verify together: bass rewritten from pyin analysis (librosa),
      kick LPF raised for click, d3 cut groups for OH ring-over, cello updated.
      Bass was wrong — NTO uses sustained Bb1/F2 alternation with chromatic
      slides, NOT F/A/C arpeggio. A2 never appears in any segment.
      PLN (Algolia) authored
    • feat(copycat): d5 slow-2x with fast-2 on ^58, d9 warm pad n8 · b129304d
      d5: keep dope slow-2x base, ^58 now layers fast 2 (original NTO speed)
      d9: 90s_synatm:8 (99.7% low, 0% hi — warm, not windy)
      PLN (Algolia) authored
    • feat(copycat): d4 octersubbus, d5 richer 16-bar arp, d7 tighter cello · 8b6a3a4c
      d4 bass: octersubbus replaces lpfbus on ^53 (user preference)
      d5 arp: 16-bar cycle with A3/C4 variations (demucs melody arc)
        Bb/F anchor bars + A3/F4 + A3/C4 + Eb/Gb variations
      d7 cello: tighter room (0.25), shorter legato (1.2), rhythmic
        answer phrase on beat 3, mirrors bass V chord one octave up
      PLN (Algolia) authored
    • feat(copycat): 32-bar automations on all voices (NTO evolution style) · 20ddb929
      Every voice now has subtle 32-bar sweeps matching NTO's arrangement evolution:
      - d1 kick: lpf 700→250 (darker), room 0→0.15 (opening)
      - d2 clap: gain 0.5→0.8 (grows into mix)
      - d3 OH: n 5→9 (brightening), hpf 2k→5k, gain 1.2→1.5
      - d4 bass: room 0.05→0.2 (space opens)
      - d5 arp: room 0.2→0.5, sz 0.3→0.7 (tail grows)
      - d6 piano: modIndex 1→3.5 (richer harmonics)
      - d7 cello: room 0.3→0.6, gain 0.8→1.1 (presence grows)
      - d9 pad: lpf 1.2k→6k (warm→bright), gain 0.7→1.0 (swells)
      All manual controls preserved — automations are background evolution.
      PLN (Algolia) authored
    • feat(copycat): deep drum rework from onset+envelope analysis · af0637a7
      Full NTO drum character applied:
      - d1 kick: att 0.05 (round thud), lpf darkening over time (saw 800→300)
      - d2 clap: quiet (gain 0.7), dry (room 0.1), hpf 800 — mid-snap only
      - d3 OH: evolving brightness (n6→n8), att 0.04 (soft onset),
        ^44 toggles whisper-shimmer mode (gain 0.3, hpf 6000, legato 0.15)
      - Header: full drum voice analysis with centroid evolution,
        attack/decay times, peak levels per section
      PLN (Algolia) authored
    • feat(copycat): drum rework from detailed onset analysis · 43e0a477
      Deep demucs drum study findings:
      - Kick: 8th note pulse (NOT 4otf), ghost doubles before drop
      - Cymbal: THE defining texture, upbeat 8ths throughout most of track
      - Clap: appears late (~200s) on contretemps (beats 1&3), ~1200Hz dry snap
      - Drop at 2:20: kick disappears, pure cymbal upbeat 8ths
      - Arrangement: kick 8ths → cymbal break → kick+cymbal+clap climax
      
      Changes:
      - d1 kick: rewritten as 8th note pulse, ^29 ghost double control
      - d2 clap: ^43 ON = contretemps (beats 1&3), OFF = backbeat
      - d3 hats: OH on every upbeat 8th, ^44 toggles cymbal breakdown mode
      PLN (Algolia) authored
    • feat(copycat): bass V-chord pattern, d6 piano, full onset evidence · 127f3eac
      Major findings from demucs onset analysis:
      - NTO bass uses ONLY F2/A2/C2 (V chord tones) — never sits on Bb root!
      - Bass is rhythmically alive, not held notes. Varies each 2-bar phrase.
      - Guitar(arp) stem evolves: F3/F4 base → Bb3/A3 mid → Gb4/E4 breakdown
      - Piano: sparse Bb3 stabs with F3/A3, only in specific sections
      
      Changes:
      - d4 bass: rewritten as rhythmic V chord figure (f2/a2/c2 variation)
      - d6 piano: NEW — sparse FMRhodes1 stabs, ^31 knob controls density
      - d7 cello: reworked as counter-melody (sustained 5ths/3rds)
      - d9 pad: fixed cut group collision (was cut 7, now cut 9)
      PLN (Algolia) authored
    • feat(copycat): melodic rework — demucs onset analysis, controller mapping · 14331d16
      NTO La Clé des Champs algoraoke:
      - Bass: dropped to Bb1/F2 (demucs confirmed 58-87Hz range)
      - Bass answer: V chord tones A2→C2→F2 (onset analysis, not Eb Db C)
      - Answer timing: quarter notes over 2 bars (was 83ms triplets, now 500ms)
      - Arp: simplified to <[bf4 f4]*8!6 [ef4 gf4]*8!2> (no note-flip)
      - Cello d7: reworked as sustained counter-melody (5ths/3rds), not bass double
      - Drums: added sometimesBy knob control (^30 clap flam, ^32 hat roll, ^52 legato)
      - d8 breaks: full treatment (^92 ply, ^60 chop mode, ^36/^56 break switch)
      - Header: rewritten with demucs spectral evidence and onset analysis data
      - SC: s.volume=2 + StageLimiter.activate for output levels
      PLN (Algolia) authored
  8. 18 Mar, 2026 1 commit
  9. 15 Mar, 2026 1 commit
    • feat: copycat NTO - La Clé des Champs algoraoke · 7cc1f16d
      Research + MIDI analysis of the original track:
      - Key: Bb minor (harmonic minor dominant F)
      - Arp from MIDI: 2-note 16th oscillation (Bf4/F4, order flips per chord)
      - 16-bar cycle: Bbm(4) | F(4) | Bbm(4) | Ebm(4)
      - Drums: 808bd+clubkick, h2o handclap, h2o hats (sparse offbeat)
      - All melodic voices on MiOmi (bass, arp, pad, lead)
      - Timbral faders for live "wider before drop" sweep (FM/detune/cutoff)
      Co-Authored-By: 's avatarClaude Opus 4.6 (1M context) <noreply@anthropic.com>
      PLN (Algolia) authored