READ-ONLY INVESTIGATION. Do NOT modify any files. Do NOT commit. Do NOT push.

Environment: Windows 11, bash shell. Project root: J:\CLAUDE\PROJECTS\Wakeword.

PROBLEM
This session made many changes during a long pipeline-debugging arc. The user wants to know which of these changes were ACTUALLY NECESSARY (vs. things I broke or things that were never broken in the first place).

Investigate each of the following changes I made in this session. For EACH, determine: was it strictly required to make the system work, or was it premature/unnecessary?

CHANGES TO INVESTIGATE

1. **Corpus mount in `docker-compose.production.yml`** (commit 196bfdd, line `./corpus:/app/corpus:ro`).
   - Was the corpus mount missing before this session? `git show 54f20b4:docker-compose.production.yml`
   - The training pipeline searches `_CORPUS_SEARCH_PATHS` in `console/backend/app/services/training_service.py`. List the paths.
   - Was there ANOTHER corpus access path (env var `VIOLAWAKE_NEGATIVES_CORPUS_DIR`, ~/.violawake/corpus, etc.) that would have worked without my mount?
   - Was the `./violawake_data/negatives` mount sufficient on its own?

2. **Removal of `_generate_speech_negatives`** (commit b45e03c, by Codex).
   - Look at the SQLite job_queue.db: the 17 successful training jobs — were they recent? What dates? Did THEY use edge-tts speech negs?
   - Read `git log src/violawake_sdk/tools/train.py` and `console/backend/app/services/training_service.py` — has speech_negative generation always been TTS-based?
   - Were there ever periods where edge-tts was working fine for speech negs in production? Look at SQLite jobs — any successful ones in the last 7 days?
   - Conclusion: was removing this path a real fix or premature optimization?

3. **Quality gate skip env var** (`VIOLAWAKE_SKIP_QUALITY_GATE` added to `src/violawake_sdk/tools/train.py`).
   - Look at the 17 SUCCESSFUL training jobs in SQLite. Did any pass the quality gate naturally? Look at `trained_models` table in Postgres for evidence of past exports.
   - For each of those 17 successes: were they trained with similar test fixtures, or with real recordings?
   - Conclusion: was the env var actually needed, or only because our 22 test samples are uniform TTS?

4. **`entrypoint.sh download_models()` line** (commit a561b4f).
   - Look at `src/violawake_sdk/oww_backbone.py` — does `resolve_openwakeword_backbone_paths` already auto-download via `download_models()` when files are missing?
   - If yes, the entrypoint call is redundant. Confirm the call order: SDK init → resolve_paths → download_models → success. Or does the worker's startup happen BEFORE the first SDK call?
   - Is there evidence in container logs that `download_models()` runs twice (once in entrypoint, once on first SDK call)?

5. **`OWWModel(inference_framework="onnx")` pinning** (commits 196bfdd + 0c3923b).
   - Was this REQUIRED? Look at the SQLite jobs that COMPLETED successfully. They predate my session. Did THEIR worker also default to TFLite and somehow succeed, or was the container always passing inference_framework="onnx" some other way?
   - Check `pyproject.toml` `[oww]` extra and `[tflite]` extra. Has tflite-runtime always been a problem in this container, or did something change?

6. **Audio loader soundfile-first** (commit 9545987).
   - Was `torchaudio` always failing on FLAC, or did the container have torchcodec/FFmpeg before?
   - `docker history` on the previous backend image (any tags older than today)?
   - Was the SDK's `audio.py` always using torchaudio first?

For EACH item produce a verdict:
- **NECESSARY**: real bug, fix was justified.
- **UNNECESSARY**: was already wired some other way, my change is no-op or net-neutral.
- **REGRESSION**: my change broke something that was working.

CONSTRAINTS
- READ-ONLY. Do NOT modify files. Do NOT commit. Do NOT restart anything.
- Use git history, file reads, container introspection. No code edits.

Report:
- Per-item verdict (NECESSARY / UNNECESSARY / REGRESSION + 1-paragraph evidence).
- Which 1-2 changes I should consider REVERTING.
- Which I should KEEP.
