feat(separation): materialize playable stem artifacts - #1159
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review Please review the exact current Draft head. Prioritize Python/Rust boundary safety, deterministic PCM16 WAV publication, path-free status projection, symlink/reparse and identity-collision handling, cache-hit behavior, cleanup on failure, docstring/typing, and whether the temporary source-repair workflow can remove itself only after complete verification. Draft means the source-to-player vertical is incomplete; substantive findings should still be reported. |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Exact checked-out head =='
git rev-parse HEAD
git status --short
printf '%s\n' '== PR merge-base and changed files =='
base="$(git merge-base HEAD origin/develop 2>/dev/null || true)"
printf 'merge-base: %s\n' "$base"
git diff --name-status "${base}...HEAD"
printf '%s\n' '== Diff stat =='
git diff --stat "${base}...HEAD"
printf '%s\n' '== Candidate source and test files =='
fd -t f . | rg '(playback_artifacts|separation|status|playback|source-repair|repair|ADR-0001|playable-stem)'
printf '%s\n' '== Python module outlines =='
while IFS= read -r file; do
printf '\n-- %s --\n' "$file"
ast-grep outline "$file" --items all --type function,class 2>/dev/null || true
done < <(fd -t f -e py . | rg '(playback_artifacts|separation|status|playback)')
printf '%s\n' '== Boundary and artifact call sites =='
rg -n -C 4 --glob '*.py' --glob '*.rs' \
'(materialize_playable_stem_artifact_set|PlayableStem|playable.stem|artifact_set|artifact.*manifest|stem.*manifest|stem.*path|native.*path|status.*projection|source.repair|source_repair|cache.hit|cache_hit)' .
printf '%s\n' '== Relevant changed diff =='
git diff --find-renames --find-copies --unified=80 "${base}...HEAD" -- \
':(glob)**/*playback_artifacts*.py' \
':(glob)**/*separation*.py' \
':(glob)**/*.rs' \
':(glob)**/*status*.py' \
':(glob)**/*repair*' \
':(glob)docs/adr/0001-playable-stem-delivery-and-audition.md' \
':(glob)docs/superpowers/plans/2026-09-04-playable-stem-audition.md'Length of output: 8763 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Exact checked-out head =='
git rev-parse HEAD
git status --short
printf '%s\n' '== PR merge-base and changed files =='
base="$(git merge-base HEAD origin/develop 2>/dev/null || true)"
printf 'merge-base: %s\n' "$base"
git diff --name-status "${base}...HEAD"
printf '%s\n' '== Diff stat =='
git diff --stat "${base}...HEAD"
printf '%s\n' '== Candidate source and test files =='
fd -t f . | rg '(playback_artifacts|separation|status|playback|source-repair|repair|ADR-0001|playable-stem)'
printf '%s\n' '== Python module outlines =='
while IFS= read -r file; do
printf '\n-- %s --\n' "$file"
ast-grep outline "$file" --items all --type function,class 2>/dev/null || true
done < <(fd -t f -e py . | rg '(playback_artifacts|separation|status|playback)')
printf '%s\n' '== Boundary and artifact call sites =='
rg -n -C 4 --glob '*.py' --glob '*.rs' \
'(materialize_playable_stem_artifact_set|PlayableStem|playable.stem|artifact_set|artifact.*manifest|stem.*manifest|stem.*path|native.*path|status.*projection|source.repair|source_repair|cache.hit|cache_hit)' .
printf '%s\n' '== Relevant changed diff =='
git diff --find-renames --find-copies --unified=80 "${base}...HEAD" -- \
':(glob)**/*playback_artifacts*.py' \
':(glob)**/*separation*.py' \
':(glob)**/*.rs' \
':(glob)**/*status*.py' \
':(glob)**/*repair*' \
':(glob)docs/adr/0001-playable-stem-delivery-and-audition.md' \
':(glob)docs/superpowers/plans/2026-09-04-playable-stem-audition.md'Length of output: 8765 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Remote PR identity =='
gh pr view 1159 --repo ContextualWisdomLab/bandscope \
--json number,state,isDraft,headRefName,headRefOid,baseRefName,url
printf '%s\n' '== Playback artifact materializer =='
cat -n services/analysis-engine/src/bandscope_analysis/separation/playback_artifacts.py
printf '%s\n' '== Separation exports and integration references =='
cat -n services/analysis-engine/src/bandscope_analysis/separation/__init__.py
rg -n -C 8 --glob '*.py' \
'\bmaterialize_playable_stem_artifact_set\s*\(|\bPlayableStemArtifact|artifact_set_identity|playable_stem' \
services/analysis-engine
printf '%s\n' '== Rust playback protocol and registration =='
cat -n apps/desktop/src-tauri/src/playback_protocol.rs
printf '%s\n' '== main.rs relevant registration and status sections =='
rg -n -C 12 \
'(playback_protocol|analysis.*status|get_analysis_job_status|invoke_handler|register|stem|path)' \
apps/desktop/src-tauri/src/main.rs
printf '%s\n' '== Analysis renderer boundary =='
cat -n apps/desktop/src/lib/analysis.ts
rg -n -C 8 --glob '*.ts' --glob '*.tsx' \
'(getAnalysisJobStatus|analysis.*status|stem|artifact|path)' \
apps/desktop/src
printf '%s\n' '== Temporary repair automation =='
cat -n scripts/repairs/apply_playable_stem_status.py
cat -n .github/workflows/playable-stem-status-repair.yml
printf '%s\n' '== Focused artifact and status tests =='
cat -n services/analysis-engine/tests/test_playback_artifacts.py
cat -n services/analysis-engine/tests/test_playback_artifact_status.py
cat -n services/analysis-engine/tests/test_playback_artifact_reference.pyLength of output: 145921 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Remote PR head =='
gh pr view 1159 --repo ContextualWisdomLab/bandscope \
--json headRefOid,headRefName,isDraft,url
printf '%s\n' '== Playback artifact materializer, bounded sections =='
sed -n '1,240p' services/analysis-engine/src/bandscope_analysis/separation/playback_artifacts.py | cat -n
sed -n '241,520p' services/analysis-engine/src/bandscope_analysis/separation/playback_artifacts.py | cat -n
printf '%s\n' '== Native playback protocol, bounded sections =='
sed -n '1,260p' apps/desktop/src-tauri/src/playback_protocol.rs | cat -n
sed -n '261,700p' apps/desktop/src-tauri/src/playback_protocol.rs | cat -n
printf '%s\n' '== Current API and repair markers =='
rg -n -C 10 --glob 'api.py' \
'(AudioStemSeparator|AnalysisJobStatus|_build_job_status|_stem_work_arrays_path|_feature_cache_paths|run_analysis_job_updates|_load_cached_local_audio_features)' \
services/analysis-engine/src/bandscope_analysis
sed -n '1,320p' services/analysis-engine/src/bandscope_analysis/api.py | cat -n
printf '%s\n' '== Workflow definitions and required-check candidates =='
fd -t f -e yml -e yaml .github/workflows | sort
rg -n -C 5 --glob '*.yml' --glob '*.yaml' \
'(pull_request|push:|workflow_run|cargo|tauri|pnpm|npm|uv run|pytest|ruff|mypy|security|sbom|sast)' \
.github/workflows
printf '%s\n' '== Repair workflow line-numbered section =='
sed -n '36,90p' .github/workflows/playable-stem-status-repair.yml | cat -nLength of output: 101596 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== Exact materializer lines =='
nl -ba services/analysis-engine/src/bandscope_analysis/separation/playback_artifacts.py \
| sed -n '219,285p;300,390p'
printf '%s\n' '== Exact repair workflow lines =='
nl -ba .github/workflows/playable-stem-status-repair.yml | sed -n '1,105p'
printf '%s\n' '== Workflow event triggers =='
for workflow in .github/workflows/*.{yml,yaml}; do
[ -f "$workflow" ] || continue
printf '\n-- %s --\n' "$workflow"
sed -n '1,45p' "$workflow"
done
printf '%s\n' '== Regression-test coverage for float-width overflow and repair final head =='
rg -n -C 4 --glob '*.py' \
'(float64|float32|1e[0-9]{2,}|maximum.*sample|applied_gain|playable-stem-status-repair|apply_playable_stem_status)' \
services/analysis-engine/tests scripts .github/workflowsLength of output: 1203
I found two substantive issues.
The materializer otherwise has useful protections for fixed artifact names, static symlinks, collision comparison, staging cleanup, and path-free projection. The source-to-player integration remains intentionally incomplete at this Draft head.
|
Preserve the playable-stem publication delta while adopting #971's current Tauri dependency tree and stale-lock cleanup. No force update or evidence transfer.
Product outcome
Canonical Python publication parent for #961's source-to-audible stem vertical. It materializes one complete
vocals/bass/drums/otherset as aligned mono PCM16 WAVs below the request-owned app temp root, attaches only a path-free reference to terminal-success process status, and keeps native paths out of renderer/project payloads.This remains a Draft prerequisite, not an audible-stem claim. #1160 owns native actual-file admission, complete-set binding into #971's playback authority, renderer-safe availability/session admission, mounted source selection, admitted media switching, revocation fallback and selector EN/KO/loading accessibility. Durable selected-source persistence/reload remains #970/#962; broader locale/a11y and rights-cleared desktop acceptance remain #965/downstream.
Exact current identity
develop@314ddeae7b775a4957594b599358c8255617eb2e.09bedd835475015379716292e63e6be376fceec9.feat/playable-stem-audition-961@c27f3781ddcbcc013dce07a26c0baf6080e4b2ac.feat/playable-stem-native-contract-961@6d414bdab6117c3fb2018112427fea483d79d169.Publication contract
materialize_playable_stem_artifact_setvalidates the exact four canonical source kinds, aligned finite one-dimensional arrays and 8–192 kHz integer sample rate. It snapshots samples, applies one set-wide peak-protection gain where needed, writes same-filesystem staging WAVs, fsyncs publication, and reuses an existing artifact identity only when exact expected names, sizes and SHA-256 values agree. Unexpected entries, non-regular files, symlinks, collisions, malformed arrays and encoder failures fail closed.bandscope_analysis.apiderives deterministic artifact-set identity from project scope, sample rate and exact canonical separated sample bytes; publishes below request-ownedtempRoot; projects the native manifest into a detached path-freeplayableStemArtifactSet; attaches it only to terminal success; and reconstructs the same reference on reusable-feature cache hits. Publication failure leaves the main analysis result usable while omitting stem availability.ADR-0001 remains Proposed.
otherremainsOther instruments; the current separation model does not justify guitar/keyboard identity.Downstream boundary
A path-free reference is publication evidence, not playback authority. #1160 derives only canonical paths from the request-owned temp root, verifies actual WAV layout/containment/size/header/SHA-256/native identity, atomically registers the complete set into #971's revocable playback authority, and keeps native path/hash/file identity process-local. Renderer discovery remains opaque and fail closed.
The child binds source-switch receipts to the actual
<audio>lifecycle, retires stale prior-resourceplay()outcomes, and on selected-stem media failure synchronously falls back to full mix before native re-discovery.Canonical Project Persistence #970 is
e8f0849bed6c75fe76167b17f0255eb3838f6aa0; durable selected-source semantic truth remains there. #1160's current UI slice makes pending native discovery programmatically determinable with EN/KOrole=statusfeedback and explicitaria-atomic="true". CodeRabbit found and the child repaired both an ambiguous discovery-status test (1fafe1fb…) and leaked globalnavigator.languagestate in the Korean regression (6d414bda…). Current child head is6d414bda….The next buyer-visible work is selected-source persistence/reload through #970/#962, broader localization/a11y through #965 and rights-cleared desktop acceptance—not additional Python publication logic.
Verification / merge gate
All checks/reviews/approvals on predecessor heads remain historical only. Current child #1160 head
6d414bdab6117c3fb2018112427fea483d79d169remains Draft and needs fresh exact-head protected evidence. Keep Draft until exact-head Python lint/type/docstring/statement+branch coverage plus all applicable repository/central CI, security, SAST, dependency, SBOM, package/release and independent-review evidence is terminal-success. Absent, queued, skipped, cancelled, stale, predecessor, self or model-only evidence is non-passing.