feedBack/tests
Byron Gamatos 8bec8d2466
refactor(app): carve the playback transport out of app.js — and RETIRE 8 host hooks (R3a) (#894)
static/js/transport.js (377) — bodies VERBATIM. app.js 6,643 → 6,316.

THIS IS THE FIRST CARVE THAT SUBTRACTS HOOKS INSTEAD OF ADDING THEM.

Every carve before this one added host hooks: a module pulled out of app.js still had
to call back into it. But four modules were all reaching through the seam for the SAME
handful of names — _audioSeek, _audioTime, setPlayButtonState, _songEventPayload,
jucePlayer. Those names have an owner, and it isn't app.js. Give them one, and the
consumers import them directly:

    count-in.js           5 hooks -> 0     (host import deleted)
    juce-audio.js         4 hooks -> 0     (host import deleted)
    loops.js              6 hooks -> 4
    section-practice.js  10 hooks -> 7
    ----------------------------------------------------------
    configureHost()      20 hooks -> 12

A hook is a cycle you agreed to live with. An import is a dependency you actually have.
Prefer the import whenever the name has a real owner.

_audioSeekGen now stays PRIVATE. It has exactly one writer — _resetAudioSeekState(),
which moved with it — so readers get audioSeekGen() and nobody outside can desync it.
Strictly better than the hook it replaces, which handed out a getter and left the writer
behind in app.js.

THE SCAN HAD A HOLE, AND IT BIT. Picking the carve by dependency closure over app.js's
own top-level decls said this cluster was downward-closed. It wasn't:
_currentPlaybackSnapshot reads loopA/loopB — which live in ./js/loops.js, and loops.js
imports transport. The scan saw nothing, because loopA STOPPED BEING an app.js decl the
moment loops.js was carved out. Any dependency scan of a partly-carved monolith has to
resolve the imports too, or it will confidently hand you a cycle. Added that pass; it
found exactly one back-edge, and _currentPlaybackSnapshot stays in app.js (as does
restartCurrentSong, which calls _cancelCountIn). app.js is the root — it imports both
sides for free.

TESTS. Four harnesses retargeted (play_button_reroute_guard, song_event_payload,
song_seek -> transport.js; playback_app_adapter SPLIT, since
_installPlaybackTransportAdapter stayed behind).

The two CENSUS tests — "≥8 song:* emit sites", "every seek callsite passes a reason" —
now scan app.js AND every static/js/*.js, not one file. Pointed at a single file, their
count silently shrinks as code leaves, which reads as "someone deleted an emit" or, worse,
passes while genuinely missing sites. Both bite-tested: stripping a _songEventPayload()
from an emit and adding a reason-less _audioSeek() each fail the suite.

VERIFIED. A/B against origin/main, real song, real playback: song:play payload is exactly
{audioT, chartT, perfNow, time}; song:seek carries reason "seek-by" with finite from/to;
all five song:* events fire; seekBy advances the clock; restartCurrentSong returns to zero;
the play button's aria-pressed tracks state. IDENTICAL on all 21 probes, zero page errors.

pytest 2396, node 1040/1040, host contract 2/2, ESLint 0 (no-cycle clean), Codex 0.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:26:35 +02:00
..
browser feat(v3): DOM-virtualize the Songs grid (#636 item 3 stage 2) (#643) 2026-06-29 12:26:29 +02:00
fixtures Remove unused binary test fixture; correct stale scan comments 2026-06-16 18:49:40 +01:00
js refactor(app): carve the playback transport out of app.js — and RETIRE 8 host hooks (R3a) (#894) 2026-07-11 23:26:35 +02:00
plugins fix(tuner): anchor injectPlayerButton to a direct-child button (feedBack#800) 2026-07-07 09:54:06 +02:00
__init__.py Clean release snapshot 2026-06-16 18:47:13 +02:00
conftest.py refactor(server): move the metadata-enrichment subsystem into lib/enrichment.py (R3) (#861) 2026-07-11 11:32:21 +02:00
test_acoustid_match.py feat(enrichment): AcoustID audio-fingerprint identification (opt-in) (#759) 2026-07-05 00:17:43 +02:00
test_albums_view.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_appstate.py feat(server): add appstate.py, the router seam (R3) (#833) 2026-07-10 15:06:22 +02:00
test_art_candidates.py refactor(server): extract the album-art routes into routers/art.py (R3) (#862) 2026-07-11 11:56:53 +02:00
test_art_layer.py refactor(server): extract the album-art routes into routers/art.py (R3) (#862) 2026-07-11 11:56:53 +02:00
test_artist_alias.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_artist_page.py refactor(server): move the metadata-enrichment subsystem into lib/enrichment.py (R3) (#861) 2026-07-11 11:32:21 +02:00
test_artist_sort_title_order.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_audio_bundled.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_audio_effect_mappings.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_audio_local_path.py refactor(server): extract the media/file-serving routes into routers/media.py (R3) (#869) 2026-07-11 15:36:22 +02:00
test_audio.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_batch_user_meta.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_builtin_diagnostic_seed.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_builtin_starter_seed.py feat(library): add Star-Spangled Banner + Ode to Joy starter content (#744) 2026-07-03 22:58:39 +02:00
test_collections_api.py refactor(server): extract library + collections routes + the provider registry (R3) (#866) 2026-07-11 14:56:12 +02:00
test_context_menu_api.py refactor(server): move the metadata-enrichment subsystem into lib/enrichment.py (R3) (#861) 2026-07-11 11:32:21 +02:00
test_correlation_id.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_curated_album.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_demo_mode.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_diagnostics_bundle.py fix(tests): isolate plugin routes modules + redact .feedpak filenames (#736) 2026-07-03 13:01:07 +02:00
test_diagnostics_hardware.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_diagnostics_redact.py fix(tests): isolate plugin routes modules + redact .feedpak filenames (#736) 2026-07-03 13:01:07 +02:00
test_dlc_junction.py fix(library): serve art/load for songs mounted through a library junction (#766) 2026-07-05 00:15:50 +02:00
test_drums_lib.py Purge external-format terminology from code, tests and docs 2026-06-16 19:36:53 +01:00
test_enrichment_plumbing.py refactor(server): move the metadata-enrichment subsystem into lib/enrichment.py (R3) (#861) 2026-07-11 11:32:21 +02:00
test_env_compat.py refactor(ui)!: remove the classic v2 shell — v3 is the only UI (R3a) (#871) 2026-07-11 16:33:03 +02:00
test_feedpak_extension.py refactor(server): extract the settings routes into routers/settings.py (R3) (#863) 2026-07-11 12:35:05 +02:00
test_field_overrides.py refactor(server): move the metadata-enrichment subsystem into lib/enrichment.py (R3) (#861) 2026-07-11 11:32:21 +02:00
test_gap_fill.py feat(v3 library): "Fix metadata" popup — per-song override + lock, cover picker, MusicBrainz + AcoustID (#777) 2026-07-05 21:09:38 +02:00
test_gp2midi.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_gp2notation.py fix: correctly import and notate multi-staff (piano/keys) tracks from GP8 (#692) 2026-07-02 08:40:20 +02:00
test_gp2rs_drums.py feat(drums): capture velocities alongside times in unmapped-percussion reporting (#808) 2026-07-07 23:58:49 +02:00
test_gp2rs_gpx.py fix(gpx): clamp partial final BCFS sector so GP6 .gpx import works (#749) 2026-07-05 00:20:31 +02:00
test_gp2rs.py fix(gp2rs): write beat times at 6-decimal precision so imported tempo matches Guitar Pro (#819) 2026-07-10 13:12:10 +02:00
test_gp_audio_sync.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_gp_autosync_warp.py feat(gp_autosync): piecewise time-warp helpers + refine_sync onset pass (#787) 2026-07-05 20:08:19 +02:00
test_group_filter_law.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_highway_3d_routes.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_highway_ws_authors.py refactor(server): extract the highway WebSocket into routers/ws_highway.py (R3) (#844) 2026-07-10 21:12:54 +02:00
test_highway_ws_instrument_routing.py refactor(server): extract the highway WebSocket into routers/ws_highway.py (R3) (#844) 2026-07-10 21:12:54 +02:00
test_highway_ws_notation.py refactor(server): extract the highway WebSocket into routers/ws_highway.py (R3) (#844) 2026-07-10 21:12:54 +02:00
test_library_filters.py feat(library): sort and badge by personal difficulty rating (#810) 2026-07-07 23:57:20 +02:00
test_library_keyset.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_library_providers.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_lift_keys_notation.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_logging_setup.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_loops_concurrency.py fix(loops): take the DB lock for the count+insert and the list read (#840) 2026-07-10 19:16:01 +02:00
test_loose_traversal.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_loosefolder.py Purge external-format terminology from code, tests and docs 2026-06-16 19:36:53 +01:00
test_lyrics_transcribe.py Purge external-format terminology from code, tests and docs 2026-06-16 19:36:53 +01:00
test_mb_enrichment.py refactor(server): move the metadata-enrichment subsystem into lib/enrichment.py (R3) (#861) 2026-07-11 11:32:21 +02:00
test_mb_match.py feat(enrichment): alias-aware scoring — auto-confirm non-Latin-primary artists (#772) 2026-07-05 01:11:38 +02:00
test_midi_import_drums.py feat(drums): capture velocities alongside times in unmapped-percussion reporting (#808) 2026-07-07 23:58:49 +02:00
test_midi_import.py fix(midi): guard non-positive division in the legacy inline tempo path (#805) 2026-07-07 10:27:45 +02:00
test_midi_tempo_map.py feat(midi): convert_midi_tempo_map — extract tempos, time signatures, beat grid (#796) 2026-07-07 10:27:17 +02:00
test_minigames_routes.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_notation_lib.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_notation_lift.py fix: correctly import and notate multi-staff (piano/keys) tracks from GP8 (#692) 2026-07-02 08:40:20 +02:00
test_notation_to_notes.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_packaging.py fix(build): move appstate.py + routers/ under lib/ so the desktop app ships them (#836) 2026-07-10 17:16:34 +02:00
test_parse_arrangement.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_playlist_cover_errors.py fix(playlists): split cover decode (400) from persist (500), unique temp, existence re-check (#842) 2026-07-10 20:16:22 +02:00
test_playlists_api.py refactor(server): extract the playlists routes into routers/playlists.py (R3) (#841) 2026-07-10 19:58:09 +02:00
test_plugin_manifest_contract.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_plugin_runtime_idempotence.py refactor(app): carve the JUCE/desktop audio shims out of app.js (R3a) (#893) 2026-07-11 22:44:03 +02:00
test_plugin_src_route.py R0: module-migration rails (src/ serving, live-edit cache, scriptType loading, governance) (#812) 2026-07-08 10:14:40 +02:00
test_plugins.py feat(plugins): full-screen (immersive) plugin screens via manifest opt-in (#590) 2026-06-25 00:02:16 +02:00
test_practice_suggestions.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_profile_api.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_profile_domains.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_progression_api.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_progression.py Purge external-format terminology from code, tests and docs 2026-06-16 19:36:53 +01:00
test_safepath.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_scraper_options.py refactor(server): move the metadata-enrichment subsystem into lib/enrichment.py (R3) (#861) 2026-07-11 11:32:21 +02:00
test_settings_api.py refactor(server): extract the settings routes into routers/settings.py (R3) (#863) 2026-07-11 12:35:05 +02:00
test_settings_export_library_db.py refactor(server): extract the settings routes into routers/settings.py (R3) (#863) 2026-07-11 12:35:05 +02:00
test_settings_export.py refactor(server): extract the settings routes into routers/settings.py (R3) (#863) 2026-07-11 12:35:05 +02:00
test_settings_instrument.py settings: add host instrument profiles (#753) 2026-07-05 00:16:42 +02:00
test_sloppak_cent_offset.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_sloppak_cover_art.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_sloppak_drumtab_load.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_sloppak_feedpak_version.py feat(core): adopt feedpak_version — read on load + stamp on manifest writes (spec §4) (#530) 2026-06-20 21:59:04 +02:00
test_sloppak_file_traversal.py refactor(server): extract the media/file-serving routes into routers/media.py (R3) (#869) 2026-07-11 15:36:22 +02:00
test_sloppak_jsonc_load.py feat(core): read .jsonc data files (strip C-style comments) (feedpak-spec §8) 2026-06-20 14:10:04 -07:00
test_sloppak_keys_load.py feat(core): consume keys.json — song-level key/scale track (loader + WS) (#528) 2026-06-20 21:23:48 +02:00
test_sloppak_notation_load.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_sloppak_original_audio_load.py feat(sloppak): expose full-mix original_audio alongside stems (#583) 2026-06-23 18:05:45 +02:00
test_sloppak_song_timeline_load.py feat(core): consume song_timeline tempos + time_signatures + per-chart tempos (feedpak 1.2.0) (#529) 2026-06-20 21:35:07 +02:00
test_song_score.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_song_stats_api.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_song_user_meta.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_song.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_songmeta.py fix: Edit Metadata persists into .feedpak files (suffix gate predated the rename) (#725) 2026-07-02 20:51:57 +02:00
test_starter_suggestions.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_startup_status.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_tailwind_rebuild.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
test_tones.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_tunings.py Serve exact MIDI notes from GET /api/tunings (tuningMidis) (#829) 2026-07-10 13:05:39 +02:00
test_version_endpoint.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_vocal_pitch.py Clean release snapshot 2026-06-16 18:47:13 +02:00
test_wanted_api.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_work_charts_api.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_work_grouping.py fix(tests): join background scan/enrich workers before closing the DB (#735) 2026-07-03 12:15:43 +02:00
test_ws_highway_disconnect.py fix(ws_highway): swallow a mid-stream WebSocketDisconnect quietly (#845) 2026-07-10 21:30:53 +02:00
test_xp.py Clean release snapshot 2026-06-16 18:47:13 +02:00