fix: cap YouTube URL input length#528
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.
Caps YouTube URL input length across desktop UI, desktop bridge (Tauri), and the analysis engine to avoid expensive parsing/regex work on oversized attacker-controlled strings, and adds regression tests plus a short security note.
Changes:
- Add a
MAX_YOUTUBE_URL_LENGTHguard before URL parsing in Python, TypeScript, and Rust. - Enforce the same limit in the desktop UI textbox and add regression tests for oversized URLs.
- Document the length-limit lesson in sentinel notes.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| services/analysis-engine/tests/test_youtube.py | Adds regression test rejecting oversized (but otherwise valid) YouTube URLs. |
| services/analysis-engine/src/bandscope_analysis/youtube.py | Introduces MAX_YOUTUBE_URL_LENGTH and early length check in validate_url. |
| apps/desktop/src/lib/analysis.ts | Adds/export MAX_YOUTUBE_URL_LENGTH and rejects oversized URLs before new URL(...). |
| apps/desktop/src/lib/analysis.test.ts | Adds a test ensuring oversized URLs are rejected before invoking the Tauri bridge. |
| apps/desktop/src/App.tsx | Sets maxLength on the YouTube URL input using the shared constant. |
| apps/desktop/src/App.test.tsx | Adds a test asserting the YouTube URL input is capped. |
| apps/desktop/src-tauri/src/main.rs | Adds MAX_YOUTUBE_URL_LENGTH and rejects oversized URLs before Rust URL parsing; includes test. |
| .jules/sentinel.md | Records the URL length-limit learning/prevention note. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Addressed the YouTube URL length review feedback in c9ffefe. Changes:
Verification:
|
There was a problem hiding this comment.
Pull request overview
OpenCode cannot approve yet because required coverage evidence did not pass.
Review outcome
1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence
-
Problem: The required coverage-evidence job result was
failure, so OpenCode cannot establish approval sufficiency for this head. -
Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.
-
Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports
successwith required evidence or explicit no-source not-applicable evidence. -
Regression test: Keep the approval branch checking
needs.coverage-evidence.result == successbefore posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present. -
Result: REQUEST_CHANGES
-
Reason: coverage-evidence result was
failure, so required test/docstring evidence was not proven for current headd94a966bd13ad3d4b3a47213eed9eece2e89caf4. -
Head SHA:
d94a966bd13ad3d4b3a47213eed9eece2e89caf4 -
Workflow run: 28589478583
-
Workflow attempt: 1
Coverage evidence
Coverage Evidence
- Head SHA:
d94a966bd13ad3d4b3a47213eed9eece2e89caf4 - Required test evidence: supported repository test suites must pass.
- Required docstring evidence: repository-owned docstring gates must pass when configured; otherwise docstring coverage is advisory.
Python project dependencies (services/analysis-engine)
Using CPython 3.12.3 interpreter at: /usr/bin/python3.12
Creating virtual environment at: services/analysis-engine/.venv
Resolved 49 packages in 0.68ms
Building bandscope-analysis @ file:///home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine
Downloading pygments (1.2MiB)
Downloading scipy (33.6MiB)
Downloading mypy (13.0MiB)
Downloading numpy (15.8MiB)
Downloading yt-dlp (3.0MiB)
Downloading scikit-learn (8.5MiB)
Downloading soundfile (1.3MiB)
Downloading ruff (10.7MiB)
Downloading llvmlite (53.7MiB)
Downloading numba (3.6MiB)
Downloaded soundfile
Downloaded pygments
Built bandscope-analysis @ file:///home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine
Downloaded numba
Downloaded ruff
Downloaded yt-dlp
Downloaded scikit-learn
Downloaded numpy
Downloaded llvmlite
Downloaded scipy
Downloaded mypy
Prepared 44 packages in 2.01s
Installed 44 packages in 77ms
+ audioread==3.1.0
+ bandit==1.9.4
+ bandscope-analysis==0.1.0 (from file:///home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine)
+ certifi==2026.2.25
+ cffi==2.0.0
+ charset-normalizer==3.4.6
+ coverage==7.13.4
+ decorator==5.2.1
+ idna==3.18
+ iniconfig==2.3.0
+ joblib==1.5.3
+ lazy-loader==0.5
+ librosa==0.11.0
+ librt==0.8.1
+ llvmlite==0.45.1
+ markdown-it-py==4.0.0
+ mdurl==0.1.2
+ msgpack==1.2.1
+ mypy==1.19.1
+ mypy-extensions==1.1.0
+ numba==0.62.1
+ numpy==2.3.5
+ packaging==26.0
+ pathspec==1.0.4
+ platformdirs==4.9.4
+ pluggy==1.6.0
+ pooch==1.9.0
+ pycparser==3.0
+ pygments==2.20.0
+ pytest==9.0.3
+ pytest-cov==7.0.0
+ pyyaml==6.0.3
+ requests==2.33.0
+ rich==15.0.0
+ ruff==0.15.5
+ scikit-learn==1.8.0
+ scipy==1.17.1
+ soundfile==0.13.1
+ soxr==1.0.0
+ stevedore==5.7.0
+ threadpoolctl==3.6.0
+ typing-extensions==4.15.0
+ urllib3==2.7.0
+ yt-dlp==2026.6.9
- Result: PASS
Python coverage with missing-line report (services/analysis-engine)
============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.0.3, pluggy-1.6.0
rootdir: /home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine
configfile: pyproject.toml
plugins: cov-7.0.0
collected 433 items
tests/test_activity.py ........ [ 1%]
tests/test_anchors.py .... [ 2%]
tests/test_api.py ......................... [ 8%]
tests/test_chord_recognizer.py .................... [ 13%]
tests/test_chords.py ......................... [ 18%]
tests/test_cli.py ................. [ 22%]
tests/test_extractor.py ...... [ 24%]
tests/test_health.py . [ 24%]
tests/test_pipeline_integration.py ......... [ 26%]
tests/test_pitch_tracker.py ............... [ 30%]
tests/test_priority.py ........... [ 32%]
tests/test_ranges.py ................... [ 36%]
tests/test_release_asset_selection.py ........ [ 38%]
tests/test_release_metadata.py ....... [ 40%]
tests/test_release_packaging.py ......... [ 42%]
tests/test_roles.py ....... [ 44%]
tests/test_roles_ml.py ... [ 44%]
tests/test_segmenter.py ..................... [ 49%]
tests/test_separation.py .................................. [ 57%]
tests/test_supply_chain_policy.py ...................................... [ 66%]
........................................................................ [ 82%]
......................................... [ 92%]
tests/test_temporal.py ......... [ 94%]
tests/test_transcription.py ... [ 95%]
tests/test_tuning.py ..... [ 96%]
tests/test_youtube.py ................ [100%]
=============================== warnings summary ===============================
tests/test_pipeline_integration.py::test_pipeline_without_detected_sections_falls_back
tests/test_roles.py::test_role_extractor_falls_back_when_activity_detection_fails
/home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine/.venv/lib/python3.12/site-packages/librosa/core/pitch.py:103: UserWarning: Trying to estimate tuning from empty frequency set.
return pitch_tuning(
tests/test_roles.py::test_role_extractor_falls_back_when_activity_detection_fails
/home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine/.venv/lib/python3.12/site-packages/librosa/core/spectrum.py:266: UserWarning: n_fft=2048 is too large for input signal of length=100
warnings.warn(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================== 433 passed, 3 warnings in 89.41s (0:01:29) ==================
Name Stmts Miss Cover Missing
------------------------------------------------------------------------------------
src/bandscope_analysis/__init__.py 3 0 100%
src/bandscope_analysis/api.py 571 0 100%
src/bandscope_analysis/chords/__init__.py 5 0 100%
src/bandscope_analysis/chords/analyzer.py 116 0 100%
src/bandscope_analysis/chords/capo.py 10 0 100%
src/bandscope_analysis/chords/chord_recognizer.py 192 0 100%
src/bandscope_analysis/chords/model.py 15 0 100%
src/bandscope_analysis/cli.py 68 0 100%
src/bandscope_analysis/health.py 7 0 100%
src/bandscope_analysis/ranges/__init__.py 4 0 100%
src/bandscope_analysis/ranges/analyzer.py 77 0 100%
src/bandscope_analysis/ranges/model.py 19 0 100%
src/bandscope_analysis/ranges/pitch_tracker.py 54 0 100%
src/bandscope_analysis/roles/__init__.py 4 0 100%
src/bandscope_analysis/roles/activity.py 59 0 100%
src/bandscope_analysis/roles/extractor.py 118 0 100%
src/bandscope_analysis/roles/model.py 58 0 100%
src/bandscope_analysis/roles/priority.py 13 0 100%
src/bandscope_analysis/roles/tuning.py 11 0 100%
src/bandscope_analysis/sections/__init__.py 6 0 100%
src/bandscope_analysis/sections/anchors.py 5 0 100%
src/bandscope_analysis/sections/extractor.py 38 0 100%
src/bandscope_analysis/sections/model.py 35 0 100%
src/bandscope_analysis/sections/segmenter.py 140 0 100%
src/bandscope_analysis/sections/utils.py 8 0 100%
src/bandscope_analysis/separation/__init__.py 4 0 100%
src/bandscope_analysis/separation/audio_separator.py 145 0 100%
src/bandscope_analysis/separation/model.py 31 0 100%
src/bandscope_analysis/separation/separator.py 34 0 100%
src/bandscope_analysis/temporal/__init__.py 3 0 100%
src/bandscope_analysis/temporal/analyzer.py 49 0 100%
src/bandscope_analysis/temporal/model.py 9 0 100%
src/bandscope_analysis/transcription/__init__.py 2 0 100%
src/bandscope_analysis/transcription/api.py 11 0 100%
src/bandscope_analysis/youtube.py 84 0 100%
------------------------------------------------------------------------------------
TOTAL 2008 0 100%
- Result: PASS
Python docstring coverage
- Result: DEFERRED
- Reason: package.json defines check:python-docstrings; repository-owned docstring coverage runs after package dependency setup.
JavaScript/TypeScript dependencies (npm ci)
added 272 packages, and audited 275 packages in 7s
71 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
- Result: PASS
Repository docstring coverage
> [email protected] check:python-docstrings
> sh -c 'cd services/analysis-engine && uv run ruff check src tests ../../scripts --select D100,D101,D102,D103,D104,D105,D106,D107'
All checks passed!
- Result: PASS
JavaScript/TypeScript test coverage
> [email protected] test
> npm run test --workspaces --if-present && sh -c 'cd services/analysis-engine && uv run pytest tests --cov=src/bandscope_analysis --cov-report=term-missing --cov-fail-under=100' --coverage
> @bandscope/[email protected] test
> node -e "require('node:fs').mkdirSync('coverage/.tmp', { recursive: true })" && vitest run --coverage
�[1m�[30m�[46m RUN �[49m�[39m�[22m �[36mv4.1.9 �[39m�[90m/home/runner/work/bandscope/bandscope/pr-head/apps/desktop�[39m
�[2mCoverage enabled with �[22m�[33mv8�[39m
�[32m✓�[39m src/lib/export.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
�[32m✓�[39m src/lib/analysis.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
�[32m✓�[39m src/features/workspace/Workspace.test.tsx �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[33m 1676�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m enables bass transcription from selected role metadata rather than role id text �[33m 487�[2mms�[22m�[39m
�[32m✓�[39m src/components/ui/ui-primitives.test.tsx �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 210�[2mms�[22m�[39m
�[32m✓�[39m src/i18n/index.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
�[32m✓�[39m src/features/workspace/RoleSwitcher.test.tsx �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[33m 307�[2mms�[22m�[39m
�[32m✓�[39m src/features/workspace/SectionRoadmap.test.tsx �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 463�[2mms�[22m�[39m
�[32m✓�[39m src/App.test.tsx �[2m(�[22m�[2m57 tests�[22m�[2m)�[22m�[33m 13756�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m renders the rehearsal cockpit shell before analysis starts �[33m 631�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m renders the loaded song as a dark rehearsal command board �[33m 581�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m renders a rehearsal song structure timeline from real section ranges �[33m 443�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m does not show unavailable analysis metrics as detected facts �[33m 413�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m summarizes confidence from the lowest-confidence loaded section �[33m 329�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m starts an analysis job and renders the returned rehearsal result �[33m 666�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m shows the engine stage label and accessible progress value while analysis runs �[33m 388�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m animates rendered progress toward the running job target �[33m 472�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m uses translated progress labels when status payloads omit a progress label �[33m 347�[2mms�[22m�[39m
## Changed-File Evidence Map
```mermaid
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Changed file (10 files)"]
S1 --> I1["repository behavior"]
I1 --> R1["Review risk: Changed file (10 files)"]
R1 --> V1["required checks"]
Evidence --> S2["Docs: dependency-policy.md"]
S2 --> I2["operator or user guidance"]
I2 --> R2["Review risk: Docs: dependency-policy.md"]
R2 --> V2["docs review"]
Evidence --> S3["Test: test_youtube.py"]
S3 --> I3["regression suite"]
I3 --> R3["Review risk: Test: test_youtube.py"]
R3 --> V3["targeted test run"]
OpenCode Review Overview
Pull request overviewOpenCode cannot approve yet because required coverage evidence did not pass. Review outcome1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence
Coverage evidenceCoverage Evidence
Python project dependencies (services/analysis-engine)
Python coverage with missing-line report (services/analysis-engine)
Python docstring coverage
JavaScript/TypeScript dependencies (npm ci)
Repository docstring coverage
JavaScript/TypeScript test coverage |
There was a problem hiding this comment.
Pull request overview
OpenCode cannot approve yet because required coverage evidence did not pass.
Review outcome
1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence
-
Problem: The required coverage-evidence job result was
failure, so OpenCode cannot establish approval sufficiency for this head. -
Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.
-
Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports
successwith required evidence or explicit no-source not-applicable evidence. -
Regression test: Keep the approval branch checking
needs.coverage-evidence.result == successbefore posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present. -
Result: REQUEST_CHANGES
-
Reason: coverage-evidence result was
failure, so required test/docstring evidence was not proven for current headc2e25944b907ade26c3e713cebf3740458a35c04. -
Head SHA:
c2e25944b907ade26c3e713cebf3740458a35c04 -
Workflow run: 28626246237
-
Workflow attempt: 1
Coverage evidence
Coverage Evidence
- Head SHA:
c2e25944b907ade26c3e713cebf3740458a35c04 - Required test evidence: supported repository test suites must pass.
- Required docstring evidence: repository-owned docstring gates must pass when configured; otherwise docstring coverage is advisory.
Python project dependencies (services/analysis-engine)
Using CPython 3.12.3 interpreter at: /usr/bin/python3.12
Creating virtual environment at: services/analysis-engine/.venv
Resolved 49 packages in 0.62ms
Building bandscope-analysis @ file:///home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine
Downloading pygments (1.2MiB)
Downloading scipy (33.6MiB)
Downloading scikit-learn (8.5MiB)
Downloading soundfile (1.3MiB)
Downloading yt-dlp (3.0MiB)
Downloading ruff (10.7MiB)
Downloading numpy (15.8MiB)
Downloading mypy (13.0MiB)
Downloading numba (3.6MiB)
Downloading llvmlite (53.7MiB)
Downloaded soundfile
Downloaded pygments
Built bandscope-analysis @ file:///home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine
Downloaded numba
Downloaded ruff
Downloaded scikit-learn
Downloaded yt-dlp
Downloaded numpy
Downloaded llvmlite
Downloaded scipy
Downloaded mypy
Prepared 44 packages in 2.07s
Installed 44 packages in 74ms
+ audioread==3.1.0
+ bandit==1.9.4
+ bandscope-analysis==0.1.0 (from file:///home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine)
+ certifi==2026.2.25
+ cffi==2.0.0
+ charset-normalizer==3.4.6
+ coverage==7.13.4
+ decorator==5.2.1
+ idna==3.18
+ iniconfig==2.3.0
+ joblib==1.5.3
+ lazy-loader==0.5
+ librosa==0.11.0
+ librt==0.8.1
+ llvmlite==0.45.1
+ markdown-it-py==4.0.0
+ mdurl==0.1.2
+ msgpack==1.2.1
+ mypy==1.19.1
+ mypy-extensions==1.1.0
+ numba==0.62.1
+ numpy==2.3.5
+ packaging==26.0
+ pathspec==1.0.4
+ platformdirs==4.9.4
+ pluggy==1.6.0
+ pooch==1.9.0
+ pycparser==3.0
+ pygments==2.20.0
+ pytest==9.0.3
+ pytest-cov==7.0.0
+ pyyaml==6.0.3
+ requests==2.33.0
+ rich==15.0.0
+ ruff==0.15.5
+ scikit-learn==1.8.0
+ scipy==1.17.1
+ soundfile==0.13.1
+ soxr==1.0.0
+ stevedore==5.7.0
+ threadpoolctl==3.6.0
+ typing-extensions==4.15.0
+ urllib3==2.7.0
+ yt-dlp==2026.6.9
- Result: PASS
Python coverage with missing-line report (services/analysis-engine)
============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.0.3, pluggy-1.6.0
rootdir: /home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine
configfile: pyproject.toml
plugins: cov-7.0.0
collected 433 items
tests/test_activity.py ........ [ 1%]
tests/test_anchors.py .... [ 2%]
tests/test_api.py ......................... [ 8%]
tests/test_chord_recognizer.py .................... [ 13%]
tests/test_chords.py ......................... [ 18%]
tests/test_cli.py ................. [ 22%]
tests/test_extractor.py ...... [ 24%]
tests/test_health.py . [ 24%]
tests/test_pipeline_integration.py ......... [ 26%]
tests/test_pitch_tracker.py ............... [ 30%]
tests/test_priority.py ........... [ 32%]
tests/test_ranges.py ................... [ 36%]
tests/test_release_asset_selection.py ........ [ 38%]
tests/test_release_metadata.py ....... [ 40%]
tests/test_release_packaging.py ......... [ 42%]
tests/test_roles.py ....... [ 44%]
tests/test_roles_ml.py ... [ 44%]
tests/test_segmenter.py ..................... [ 49%]
tests/test_separation.py .................................. [ 57%]
tests/test_supply_chain_policy.py ...................................... [ 66%]
........................................................................ [ 82%]
......................................... [ 92%]
tests/test_temporal.py ......... [ 94%]
tests/test_transcription.py ... [ 95%]
tests/test_tuning.py ..... [ 96%]
tests/test_youtube.py ................ [100%]
=============================== warnings summary ===============================
tests/test_pipeline_integration.py::test_pipeline_without_detected_sections_falls_back
tests/test_roles.py::test_role_extractor_falls_back_when_activity_detection_fails
/home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine/.venv/lib/python3.12/site-packages/librosa/core/pitch.py:103: UserWarning: Trying to estimate tuning from empty frequency set.
return pitch_tuning(
tests/test_roles.py::test_role_extractor_falls_back_when_activity_detection_fails
/home/runner/work/bandscope/bandscope/pr-head/services/analysis-engine/.venv/lib/python3.12/site-packages/librosa/core/spectrum.py:266: UserWarning: n_fft=2048 is too large for input signal of length=100
warnings.warn(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================== 433 passed, 3 warnings in 86.59s (0:01:26) ==================
Name Stmts Miss Cover Missing
------------------------------------------------------------------------------------
src/bandscope_analysis/__init__.py 3 0 100%
src/bandscope_analysis/api.py 571 0 100%
src/bandscope_analysis/chords/__init__.py 5 0 100%
src/bandscope_analysis/chords/analyzer.py 116 0 100%
src/bandscope_analysis/chords/capo.py 10 0 100%
src/bandscope_analysis/chords/chord_recognizer.py 192 0 100%
src/bandscope_analysis/chords/model.py 15 0 100%
src/bandscope_analysis/cli.py 68 0 100%
src/bandscope_analysis/health.py 7 0 100%
src/bandscope_analysis/ranges/__init__.py 4 0 100%
src/bandscope_analysis/ranges/analyzer.py 77 0 100%
src/bandscope_analysis/ranges/model.py 19 0 100%
src/bandscope_analysis/ranges/pitch_tracker.py 54 0 100%
src/bandscope_analysis/roles/__init__.py 4 0 100%
src/bandscope_analysis/roles/activity.py 59 0 100%
src/bandscope_analysis/roles/extractor.py 118 0 100%
src/bandscope_analysis/roles/model.py 58 0 100%
src/bandscope_analysis/roles/priority.py 13 0 100%
src/bandscope_analysis/roles/tuning.py 11 0 100%
src/bandscope_analysis/sections/__init__.py 6 0 100%
src/bandscope_analysis/sections/anchors.py 5 0 100%
src/bandscope_analysis/sections/extractor.py 38 0 100%
src/bandscope_analysis/sections/model.py 35 0 100%
src/bandscope_analysis/sections/segmenter.py 140 0 100%
src/bandscope_analysis/sections/utils.py 8 0 100%
src/bandscope_analysis/separation/__init__.py 4 0 100%
src/bandscope_analysis/separation/audio_separator.py 145 0 100%
src/bandscope_analysis/separation/model.py 31 0 100%
src/bandscope_analysis/separation/separator.py 34 0 100%
src/bandscope_analysis/temporal/__init__.py 3 0 100%
src/bandscope_analysis/temporal/analyzer.py 49 0 100%
src/bandscope_analysis/temporal/model.py 9 0 100%
src/bandscope_analysis/transcription/__init__.py 2 0 100%
src/bandscope_analysis/transcription/api.py 11 0 100%
src/bandscope_analysis/youtube.py 84 0 100%
------------------------------------------------------------------------------------
TOTAL 2008 0 100%
- Result: PASS
Python docstring coverage
- Result: DEFERRED
- Reason: package.json defines check:python-docstrings; repository-owned docstring coverage runs after package dependency setup.
JavaScript/TypeScript dependencies (npm ci)
added 272 packages, and audited 275 packages in 7s
71 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
- Result: PASS
Repository docstring coverage
> [email protected] check:python-docstrings
> sh -c 'cd services/analysis-engine && uv run ruff check src tests ../../scripts --select D100,D101,D102,D103,D104,D105,D106,D107'
All checks passed!
- Result: PASS
JavaScript/TypeScript test coverage
> [email protected] test
> npm run test --workspaces --if-present && sh -c 'cd services/analysis-engine && uv run pytest tests --cov=src/bandscope_analysis --cov-report=term-missing --cov-fail-under=100' --coverage
> @bandscope/[email protected] test
> node -e "require('node:fs').mkdirSync('coverage/.tmp', { recursive: true })" && vitest run --coverage
�[1m�[30m�[46m RUN �[49m�[39m�[22m �[36mv4.1.9 �[39m�[90m/home/runner/work/bandscope/bandscope/pr-head/apps/desktop�[39m
�[2mCoverage enabled with �[22m�[33mv8�[39m
�[32m✓�[39m src/lib/export.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
�[32m✓�[39m src/lib/analysis.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 32�[2mms�[22m�[39m
�[32m✓�[39m src/features/workspace/Workspace.test.tsx �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[33m 1848�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m enables bass transcription from selected role metadata rather than role id text �[33m 422�[2mms�[22m�[39m
�[32m✓�[39m src/components/ui/ui-primitives.test.tsx �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 218�[2mms�[22m�[39m
�[32m✓�[39m src/i18n/index.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
�[32m✓�[39m src/features/workspace/RoleSwitcher.test.tsx �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[33m 350�[2mms�[22m�[39m
�[32m✓�[39m src/features/workspace/SectionRoadmap.test.tsx �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 438�[2mms�[22m�[39m
�[32m✓�[39m src/App.test.tsx �[2m(�[22m�[2m57 tests�[22m�[2m)�[22m�[33m 14664�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m renders the rehearsal cockpit shell before analysis starts �[33m 692�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m renders the loaded song as a dark rehearsal command board �[33m 579�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m renders a rehearsal song structure timeline from real section ranges �[33m 398�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m does not show unavailable analysis metrics as detected facts �[33m 407�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m summarizes confidence from the lowest-confidence loaded section �[33m 304�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m selects a local audio source and starts a local-audio analysis job �[33m 423�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m falls back to generic local-audio error copy when selection omits a message �[33m 319�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m starts an analysis job and renders the returned rehearsal result �[33m 670�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m shows the engine stage label and accessible progress value while analysis runs �[33m 465�[2mms�[22m�[39m
## Changed-File Evidence Map
```mermaid
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Changed file (7 files)"]
S1 --> I1["repository behavior"]
I1 --> R1["Review risk: Changed file (7 files)"]
R1 --> V1["required checks"]
Evidence --> S2["Test: test_youtube.py"]
S2 --> I2["regression suite"]
I2 --> R2["Review risk: Test: test_youtube.py"]
R2 --> V2["targeted test run"]
Summary
Scope note: this PR intentionally touches 8 files:
.jules/sentinel.md, desktop UI/test/bridge files, the Tauri backend, and the analysis-engine YouTube validator/test.Supersedes #410, #498, and #522 with a clean patch that avoids unrelated workflow/test churn and addresses the review feedback that UI-only maxLength is insufficient.
Verification