File size: 7,592 Bytes
03d531b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e07820e
 
 
 
 
 
 
ab6f318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fa35534
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# Interactive UX progress

## Last updated

2026-05-12

## Current phase

Implementation is now in **Phase 1–3 foundation**: persistent state, constraints, events, confidence/review queue, and supervised cluster interactions are implemented at the semantic-state layer.

## Completed in this pass

| Item | Status | Notes |
|---|---|---|
| Add supplied docs to `docs/interactive-ux/` | done | All supplied Markdown docs were copied into this directory and aligned with the implemented project. |
| Persistent job state | done | `supervision_state.json` is created beside `manifest.json` for each completed run. |
| Hit/cluster state schema | done | Implemented in `supervised_state.py` using JSON-serializable dictionaries. |
| Event log | done | State mutations append `job.state.created`, `constraint.created`, `hit.moved`, `hit.pulled_out`, `cluster.locked`, `hit.suppressed`, `suggestion.created`, etc. |
| Constraint store | done | Supports `force-cluster`, `must-link`, `cannot-link`, `lock-cluster`, `suppress-pattern`, and `pin-representative`. |
| Confidence scoring | partial | Heuristic scores based on cluster size, label agreement, energy rank, representative/favorite/explicit state, suppression, and lock state. Feature-vector margin scoring is not implemented yet. |
| Outlier-first review queue | done | Backend computes `review_queue`; UI renders it and lets the user jump to the selected hit. |
| Move hit to cluster | done | Endpoint creates constraints and updates state; it also proposes similar move suggestions. |
| Pull hit into new cluster | done | Endpoint creates `cannot-link` and `force-cluster` constraints and a user cluster. |
| Lock cluster | done | Endpoint toggles lock state and records a lock constraint. |
| Suppress hit as bleed/noise | done | Endpoint creates `suppress-pattern`, marks the hit suppressed, and proposes similar suppressions. |
| Favorite sample / pin representative | partial | Endpoint supports `review` status `favorite`, records `pin-representative`, and updates the representative hit in semantic state. Audio artifact selection is not re-exported yet. |
| Suggestion inbox | partial | Open suggestions render in the UI and can be accepted/rejected. Suggestion generation is heuristic and limited to move/split/suppress patterns. |
| Cluster explanation drawer | done | Endpoint and UI show representative, confidence reasons, outliers, relevant constraints, and label distribution. |
| Undo | done | Last semantic edit can be restored using an undo snapshot stack. |
| Validation script | done | Added `scripts/test_interactive_supervision.py`. |

## Not yet implemented

- Real cached feature-vector store for local reclustering.
- Artifact re-export after semantic edits.
- Waveform click-to-add missed onset.
- Restore suppressed hit/batch restore.
- Real local neighborhood reclustering that changes assignments beyond explicit move/suggestion acceptance.
- Constraint violation detection and reporting.
- Predictive diff preview before accepting suggestions.
- Reconstruction-error-driven correction.
- Multi-resolution/hierarchical clusters.
- User correction profiles / teach mode across songs.
- Frontend TypeScript migration and browser automation tests.

## Current risks

| Risk | Impact | Mitigation |
|---|---|---|
| Semantic edits do not rewrite exports yet | User may expect moved/suppressed hits to affect ZIP/MIDI immediately | Next task should be edited-state export. |
| Confidence scores are heuristic | Review queue may sometimes prioritize the wrong hits | Add cached mel/transient features and margin-to-next-cluster scoring. |
| Suggestions are simple | May over-suggest or under-suggest | Keep them previewable, explicit, and undoable; never silently apply. |
| Locks are semantic only | Batch reruns do not yet replay constraints | Add deterministic replay/local recluster using constraints. |
| No browser tests | UI regressions are easy | Add Playwright or lightweight DOM tests. |

## Next implementation milestone

Milestone: **edited-state export and force-onset correction**.

Minimum deliverables:

1. Add `POST /api/jobs/{job_id}/export/supervised` that creates a ZIP/MIDI/manifest from `supervision_state.json`.
2. Exclude suppressed hits/clusters from the supervised export.
3. Honor favorite/pinned representatives in exported samples.
4. Add force-onset endpoint that slices a new hit from cached `stem.wav`.
5. Add waveform shift-click or add-onset mode in the UI.
6. Add tests proving semantic edits change the supervised export without rerunning stem extraction.

## Definition of done for the current foundation

This loop now works:

```text
analyze audio
→ inspect clusters
→ load semantic state
→ move one wrong hit
→ store constraints/events
→ see confidence/review queue update
→ lock corrected cluster
→ suppress bleed
→ inspect explanations and suggestions
→ undo semantic edits
→ reload the job and preserve explicit decisions
```

The remaining missing piece is that edited semantic state is not yet reflected in a regenerated sample pack.


## Pass 5 alignment

The interactive UX docs are now aligned with the implemented semantic edit/export loop. The project supports move, pull-out, suppress, restore, favorite, lock, force-onset, suggestion diff preview, undo, and edited artifact export. The current boundary is no longer “semantic only”; edits can now produce separate supervised WAV/MIDI/reconstruction/ZIP artifacts while original batch outputs remain immutable.

Remaining UX work is concentrated around cluster-level editing and comparison: merge/relabel/split, feature-vector local reclustering, edited-vs-original diff views, and browser tests.

## 2026-05-12 automatic card-flow update

The default UX now follows the interactive-doc direction more closely by hiding most expert controls and making the user action model concrete:

- drop/upload starts processing automatically;
- waveform appears before backend processing finishes;
- real backend progress tints the waveform;
- sample candidates appear as cards grouped by type;
- dismissing a card becomes a supervised suppression when state is available;
- drawing another candidate models the "draw a card" interaction for missing samples;
- trim/extend controls can save adjusted timing as a forced hit;
- waveform zoom/pan supports close inspection without leaving the main flow.

The remaining mismatch is that drawn candidate cards are still frontend candidate previews, not persisted representative-selection constraints. That should be promoted into the semantic state model next.


## Pass 14: selected cards and Spleeter backend

Completed in this pass:

1. Added `spleeter` as the default separation backend, with selectable `spleeter:2stems`, `spleeter:4stems`, and `spleeter:5stems` profiles.
2. Kept `demucs` as a quality/fallback backend and `none` as the full-mix preview backend.
3. Added optional `requirements-spleeter.txt` instead of forcing TensorFlow/Spleeter into the base install.
4. Added per-card checkbox state with manual select-all/clear behavior.
5. Added selected-only backend export via `POST /api/jobs/{job_id}/export-selected`.
6. Made `draw another` persist the chosen representative in semantic state.
7. Made trim/extend rewrite playable preview audio immediately under `overrides/hits/`.
8. Added `scripts/test_selected_export_card_actions.py`.

Outcome:

The default app now behaves more like a card review tool: drop audio, let Spleeter/fallback separation run, review grouped cards, select/dismiss/draw/trim, and export only the selected pack.