From 0871349c75b39082a3354642d9ed67a120387b31 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 17:36:12 -0700 Subject: [PATCH 1/3] test(security): reproduce key detector log leakage --- services/analysis-engine/tests/test_key_detector.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/services/analysis-engine/tests/test_key_detector.py b/services/analysis-engine/tests/test_key_detector.py index 9164b9f08..29e3638d0 100644 --- a/services/analysis-engine/tests/test_key_detector.py +++ b/services/analysis-engine/tests/test_key_detector.py @@ -3,6 +3,7 @@ from unittest.mock import patch import numpy as np +import pytest from bandscope_analysis.chords.key_detector import ( KeyDetector, @@ -85,12 +86,18 @@ def test_detect_empty_audio() -> None: assert result == {"key": "", "tonic": "", "mode": "", "confidence": 0.0} -def test_detect_chroma_cqt_exception() -> None: - """A failure inside chroma_cqt yields the empty result and never raises.""" +def test_detect_chroma_cqt_exception(caplog: pytest.LogCaptureFixture) -> None: + """A dependency failure stays payload-safe in routine key-detection logs.""" audio = _tone(_NOTE_FREQS["C"], 1.0) - with patch("librosa.feature.chroma_cqt", side_effect=RuntimeError("boom")): + sensitive_detail = "/Users/Alice/private-song.wav token=super-secret" + with patch("librosa.feature.chroma_cqt", side_effect=RuntimeError(sensitive_detail)): result = KeyDetector().detect(audio, SAMPLE_RATE) + assert result == _empty_result() + assert "chroma_cqt failed during key detection" in caplog.text + assert "/Users/Alice" not in caplog.text + assert "private-song.wav" not in caplog.text + assert "super-secret" not in caplog.text def test_detect_empty_chroma() -> None: From 83a791ff7b03149efd25dc8cbc3ffeef44c0d586 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 17:38:38 -0700 Subject: [PATCH 2/3] fix(security): bound key detector failure logs --- .../src/bandscope_analysis/chords/key_detector.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/services/analysis-engine/src/bandscope_analysis/chords/key_detector.py b/services/analysis-engine/src/bandscope_analysis/chords/key_detector.py index a2f3216cc..fcface3f7 100644 --- a/services/analysis-engine/src/bandscope_analysis/chords/key_detector.py +++ b/services/analysis-engine/src/bandscope_analysis/chords/key_detector.py @@ -60,6 +60,8 @@ class KeyDetector: - Bounded by the size of the passed input array. - Safe failure: degenerate input returns an empty result and no exception is allowed to escape ``detect``. + - Unexpected dependency failures log only the operation and exception + class; dependency messages and tracebacks stay out of routine logs. """ def detect(self, audio: np.ndarray, sr: int) -> KeyResult: @@ -83,8 +85,11 @@ def detect(self, audio: np.ndarray, sr: int) -> KeyResult: # detection deterministic and avoids an unstable native pitch-track # code path on pure synthetic tones. chroma = librosa.feature.chroma_cqt(y=audio, sr=sr, tuning=0.0) - except Exception: # noqa: BLE001 - safe failure: never raise to caller. - logger.exception("chroma_cqt failed during key detection") + except Exception as error: # noqa: BLE001 - safe failure: never raise to caller. + logger.error( + "chroma_cqt failed during key detection: %s", + type(error).__name__, + ) return _empty_result() if chroma.size == 0: From 6ee9ada2228a91d6e1a0de776347890e8ea82132 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 17:39:11 -0700 Subject: [PATCH 3/3] docs(changelog): record key detector log privacy repair --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eea696893..9f532d19f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ - Display the analyzed song tempo (BPM) as a badge in the rehearsal workspace. - 각 합주 역할(Role)별 개인 연습 진행도를 0~100% 범위로 기록 및 시각화할 수 있는 연습 진척도(`practiceProgress`) 트래커 기능 추가. UI 컨트롤(슬라이더 및 +/- 버튼)과 한/영 다국어 지원 포함. +### Fixed + +- Keep unexpected key-detection dependency failures out of routine log payloads while retaining bounded operation and exception-class diagnostics. + ## [0.1.3] - 2026-04-29 ### Fixed