Repository: nomadkaraoke/python-audio-separator Branch: main Commit: 0a644dbb07d9 Files: 271 Total size: 4.5 MB Directory structure: gitextract_b_sdr3ak/ ├── .claude/ │ └── plans/ │ └── gha-gpu-runner.plan.md ├── .cursor/ │ ├── commands/ │ │ ├── analyze.md │ │ ├── clarify.md │ │ ├── constitution.md │ │ ├── implement.md │ │ ├── plan.md │ │ ├── specify.md │ │ └── tasks.md │ └── rules/ │ └── specify-rules.mdc ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── BUG_REPORT.yml │ │ └── FEATURE_REQUEST.yml │ ├── prompts/ │ │ ├── analyze.prompt.md │ │ ├── clarify.prompt.md │ │ ├── constitution.prompt.md │ │ ├── implement.prompt.md │ │ ├── plan.prompt.md │ │ ├── specify.prompt.md │ │ └── tasks.prompt.md │ └── workflows/ │ ├── deploy-to-cloudrun.yml │ ├── deploy-to-modal.yml │ ├── github-sponsors.yml │ ├── publish-to-docker.yml │ ├── publish-to-pypi.yml │ ├── run-integration-tests.yaml │ └── run-unit-tests.yaml ├── .gitignore ├── .specify/ │ ├── memory/ │ │ └── constitution.md │ ├── scripts/ │ │ └── bash/ │ │ ├── check-prerequisites.sh │ │ ├── common.sh │ │ ├── create-new-feature.sh │ │ ├── setup-plan.sh │ │ └── update-agent-context.sh │ └── templates/ │ ├── agent-file-template.md │ ├── plan-template.md │ ├── spec-template.md │ └── tasks-template.md ├── Dockerfile.cloudrun ├── Dockerfile.cpu ├── Dockerfile.cuda11 ├── Dockerfile.cuda12 ├── Dockerfile.runpod-cuda11 ├── Dockerfile.runpod-cuda12 ├── LICENSE ├── README.md ├── TODO.md ├── audio_separator/ │ ├── __init__.py │ ├── ensemble_presets.json │ ├── model-data.json │ ├── models-scores.json │ ├── models.json │ ├── remote/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── api_client.py │ │ ├── cli.py │ │ ├── deploy_cloudrun.py │ │ ├── deploy_modal.py │ │ ├── job_store.py │ │ ├── output_store.py │ │ └── requirements.txt │ ├── separator/ │ │ ├── __init__.py │ │ ├── architectures/ │ │ │ ├── __init__.py │ │ │ ├── demucs_separator.py │ │ │ ├── mdx_separator.py │ │ │ ├── mdxc_separator.py │ │ │ └── vr_separator.py │ │ ├── audio_chunking.py │ │ ├── common_separator.py │ │ ├── ensembler.py │ │ ├── roformer/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── bs_roformer_config.py │ │ │ ├── bs_roformer_validator.py │ │ │ ├── configuration_normalizer.py │ │ │ ├── mel_band_roformer_config.py │ │ │ ├── mel_band_roformer_validator.py │ │ │ ├── model_configuration.py │ │ │ ├── model_loading_result.py │ │ │ ├── parameter_validation_error.py │ │ │ ├── parameter_validator.py │ │ │ └── roformer_loader.py │ │ ├── separator.py │ │ └── uvr_lib_v5/ │ │ ├── __init__.py │ │ ├── demucs/ │ │ │ ├── __init__.py │ │ │ ├── __main__.py │ │ │ ├── apply.py │ │ │ ├── demucs.py │ │ │ ├── filtering.py │ │ │ ├── hdemucs.py │ │ │ ├── htdemucs.py │ │ │ ├── model.py │ │ │ ├── model_v2.py │ │ │ ├── pretrained.py │ │ │ ├── repo.py │ │ │ ├── spec.py │ │ │ ├── states.py │ │ │ ├── tasnet.py │ │ │ ├── tasnet_v2.py │ │ │ ├── transformer.py │ │ │ └── utils.py │ │ ├── mdxnet.py │ │ ├── mixer.ckpt │ │ ├── modules.py │ │ ├── playsound.py │ │ ├── pyrb.py │ │ ├── results.py │ │ ├── roformer/ │ │ │ ├── attend.py │ │ │ ├── bs_roformer.py │ │ │ └── mel_band_roformer.py │ │ ├── spec_utils.py │ │ ├── stft.py │ │ ├── tfc_tdf_v3.py │ │ └── vr_network/ │ │ ├── __init__.py │ │ ├── layers.py │ │ ├── layers_new.py │ │ ├── model_param_init.py │ │ ├── modelparams/ │ │ │ ├── 1band_sr16000_hl512.json │ │ │ ├── 1band_sr32000_hl512.json │ │ │ ├── 1band_sr33075_hl384.json │ │ │ ├── 1band_sr44100_hl1024.json │ │ │ ├── 1band_sr44100_hl256.json │ │ │ ├── 1band_sr44100_hl512.json │ │ │ ├── 1band_sr44100_hl512_cut.json │ │ │ ├── 1band_sr44100_hl512_nf1024.json │ │ │ ├── 2band_32000.json │ │ │ ├── 2band_44100_lofi.json │ │ │ ├── 2band_48000.json │ │ │ ├── 3band_44100.json │ │ │ ├── 3band_44100_mid.json │ │ │ ├── 3band_44100_msb2.json │ │ │ ├── 4band_44100.json │ │ │ ├── 4band_44100_mid.json │ │ │ ├── 4band_44100_msb.json │ │ │ ├── 4band_44100_msb2.json │ │ │ ├── 4band_44100_reverse.json │ │ │ ├── 4band_44100_sw.json │ │ │ ├── 4band_v2.json │ │ │ ├── 4band_v2_sn.json │ │ │ ├── 4band_v3.json │ │ │ ├── 4band_v3_sn.json │ │ │ ├── 4band_v4_ms_fullband.json │ │ │ └── ensemble.json │ │ ├── nets.py │ │ └── nets_new.py │ └── utils/ │ ├── __init__.py │ └── cli.py ├── cloudbuild.yaml ├── docs/ │ ├── BIT_DEPTH_IMPLEMENTATION_SUMMARY.md │ ├── BIT_DEPTH_PRESERVATION.md │ ├── CI-GPU-RUNNERS.md │ ├── archive/ │ │ └── 2026-03-22-modal-to-gcp-migration-plan.md │ ├── deton24-audio-separation-info-2026-03-15.md │ └── deton24-model-mapping-and-ensemble-guide.md ├── environment.yml ├── pyproject.toml ├── pytest.ini ├── scripts/ │ └── download_preset_models.py ├── specs/ │ ├── 001-update-roformer-implementation/ │ │ ├── 001-update-roformer-implementation.md │ │ ├── contracts/ │ │ │ ├── fallback_loader_interface.py │ │ │ ├── parameter_validator_interface.py │ │ │ └── roformer_loader_interface.py │ │ ├── data-model.md │ │ ├── plan.md │ │ ├── post-implementation-issues.md │ │ ├── quickstart.md │ │ ├── research.md │ │ └── tasks.md │ └── main/ │ └── plan.md ├── tests/ │ ├── README.md │ ├── TODO.txt │ ├── contract/ │ │ ├── test_parameter_validator_interface.py │ │ └── test_roformer_loader_interface.py │ ├── inputs/ │ │ ├── clocks_piano.flac │ │ ├── fallen24bit20s.flac │ │ ├── levee_drums.flac │ │ ├── mardy20s.flac │ │ ├── mardy20s_(Instrumental)_mel_band_roformer_karaoke_aufr33_viperx_sdr_10.flac │ │ ├── mardy20s_(Vocals)_mel_band_roformer_karaoke_aufr33_viperx_sdr_10.flac │ │ ├── only_time_reverb.flac │ │ ├── reference/ │ │ │ ├── ref_clocks_piano_bass_htdemucs_ft.flac │ │ │ ├── ref_clocks_piano_drums_htdemucs_ft.flac │ │ │ ├── ref_clocks_piano_instrumental.flac │ │ │ ├── ref_clocks_piano_instrumental_karaoke.flac │ │ │ ├── ref_clocks_piano_other_htdemucs_ft.flac │ │ │ ├── ref_clocks_piano_vocals.flac │ │ │ ├── ref_clocks_piano_vocals_htdemucs_ft.flac │ │ │ ├── ref_clocks_piano_vocals_karaoke.flac │ │ │ ├── ref_levee_drums_bass_htdemucs_ft.flac │ │ │ ├── ref_levee_drums_crash_drumsep.flac │ │ │ ├── ref_levee_drums_drums_htdemucs_ft.flac │ │ │ ├── ref_levee_drums_hh_drumsep.flac │ │ │ ├── ref_levee_drums_instrumental.flac │ │ │ ├── ref_levee_drums_instrumental_karaoke.flac │ │ │ ├── ref_levee_drums_instrumental_preset_vocal_balanced.flac │ │ │ ├── ref_levee_drums_kick_drumsep.flac │ │ │ ├── ref_levee_drums_other_htdemucs_ft.flac │ │ │ ├── ref_levee_drums_ride_drumsep.flac │ │ │ ├── ref_levee_drums_snare_drumsep.flac │ │ │ ├── ref_levee_drums_toms_drumsep.flac │ │ │ ├── ref_levee_drums_vocals.flac │ │ │ ├── ref_levee_drums_vocals_htdemucs_ft.flac │ │ │ ├── ref_levee_drums_vocals_karaoke.flac │ │ │ ├── ref_levee_drums_vocals_preset_vocal_balanced.flac │ │ │ ├── ref_only_time_reverb_instrumental.flac │ │ │ ├── ref_only_time_reverb_vocals.flac │ │ │ ├── ref_only_time_reverb_vocals_noreverb.flac │ │ │ ├── ref_only_time_reverb_vocals_reverb.flac │ │ │ ├── ref_sing_sing_sing_brass_instrumental.flac │ │ │ ├── ref_sing_sing_sing_brass_no_woodwinds.flac │ │ │ ├── ref_sing_sing_sing_brass_vocals.flac │ │ │ ├── ref_sing_sing_sing_brass_woodwinds.flac │ │ │ ├── ref_under_pressure_harmonies_backing_vocals.flac │ │ │ ├── ref_under_pressure_harmonies_instrumental.flac │ │ │ ├── ref_under_pressure_harmonies_instrumental_karaoke.flac │ │ │ ├── ref_under_pressure_harmonies_instrumental_preset_karaoke.flac │ │ │ ├── ref_under_pressure_harmonies_instrumental_preset_vocal_balanced.flac │ │ │ ├── ref_under_pressure_harmonies_lead_vocals.flac │ │ │ ├── ref_under_pressure_harmonies_vocals.flac │ │ │ ├── ref_under_pressure_harmonies_vocals_karaoke.flac │ │ │ ├── ref_under_pressure_harmonies_vocals_preset_karaoke.flac │ │ │ └── ref_under_pressure_harmonies_vocals_preset_vocal_balanced.flac │ │ ├── sing_sing_sing_brass.flac │ │ └── under_pressure_harmonies.flac │ ├── integration/ │ │ ├── README.md │ │ ├── generate_multi_stem_references.py │ │ ├── generate_reference_images.py │ │ ├── generate_reference_images_24bit.py │ │ ├── generate_reference_images_ensemble.py │ │ ├── requirements.txt │ │ ├── test_24bit_preservation.py │ │ ├── test_cli_integration.py │ │ ├── test_ensemble_integration.py │ │ ├── test_ensemble_meaningful.py │ │ ├── test_multi_stem_verification.py │ │ ├── test_remote_api_integration.py │ │ ├── test_roformer_audio_quality.py │ │ ├── test_roformer_backward_compatibility.py │ │ ├── test_roformer_config_validation.py │ │ ├── test_roformer_e2e.py │ │ ├── test_roformer_fallback_mechanism.py │ │ ├── test_roformer_model_switching.py │ │ ├── test_roformer_new_parameters.py │ │ └── test_separator_output_integration.py │ ├── model-metrics/ │ │ └── test-all-models.py │ ├── regression/ │ │ ├── test_all_models_stem_verification.py │ │ └── test_roformer_size_mismatch.py │ ├── remote/ │ │ └── README.md │ ├── reproduce_ensemble_bug.py │ ├── unit/ │ │ ├── test_audio_chunking.py │ │ ├── test_bit_depth_detection.py │ │ ├── test_bit_depth_writing.py │ │ ├── test_cli.py │ │ ├── test_configuration_normalizer.py │ │ ├── test_deploy_cloudrun_async.py │ │ ├── test_ensemble_presets.py │ │ ├── test_ensembler.py │ │ ├── test_job_store.py │ │ ├── test_mdxc_roformer_chunking.py │ │ ├── test_model_configuration.py │ │ ├── test_output_store.py │ │ ├── test_parameter_validator.py │ │ ├── test_remote_api_client.py │ │ ├── test_remote_cli.py │ │ ├── test_separator_chunking.py │ │ ├── test_separator_detection.py │ │ ├── test_stem_naming.py │ │ └── test_stft.py │ ├── utils.py │ └── utils_audio_verification.py └── tools/ ├── calculate-model-hashes.py └── sync-to-github.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .claude/plans/gha-gpu-runner.plan.md ================================================ # Plan: GCP GPU Runner for Integration Tests **Created:** 2026-03-16 **Branch:** feat/gha-gpu-runner **Status:** Implemented (pending `pulumi up` and PR merge) ## Overview The python-audio-separator integration tests currently run on a CPU-only self-hosted GHA runner (`e2-standard-4`, 4 vCPU, 16GB RAM). With the new ensemble tests and multi-stem verification tests, CI takes 30+ minutes because each model separation runs on CPU. A GPU runner would reduce this to ~5 minutes. ## Current State ### Existing runner infrastructure - **Location:** `karaoke-gen/infrastructure/compute/github_runners.py` (Pulumi) - **Runners:** 3× `e2-standard-4` (general) + 1× `e2-standard-8` (Docker builds) - **Labels:** `self-hosted`, `Linux`, `X64`, `gcp`, `large-disk` - **Region:** `us-central1-a` - **Models:** Pre-cached at `/opt/audio-separator-models` on runner startup - **Org-level:** Runners are registered to `nomadkaraoke` org, available to all repos - **NAT:** All runners use Cloud NAT (no external IPs) ### Current integration test workflow - File: `.github/workflows/run-integration-tests.yaml` - Runs on: `self-hosted` (picks up any org runner) - Tests: `poetry run pytest -sv --cov=audio_separator tests/integration` - Installs: `poetry install -E cpu` - Problem: All model inference on CPU → very slow for Roformer/Demucs models ## Requirements - [x] GCE VM with NVIDIA GPU (T4 is cheapest, sufficient for inference) - [x] CUDA drivers + PyTorch GPU support pre-installed - [x] Models pre-cached on persistent disk (same as existing runners) - [x] Labeled `gpu` so workflow can target it specifically - [x] Cost-effective — only runs when needed (on-demand, not always-on) - [x] Integration test workflow updated to use `gpu` label - [x] Install `poetry install -E gpu` (onnxruntime-gpu) instead of `-E cpu` ## Technical Approach ### Option A: Dedicated GPU VM (simplest) Add a new GPU runner VM to the existing Pulumi infrastructure. Use an `n1-standard-4` with 1× NVIDIA T4 GPU. Cost: ~$0.35/hr on-demand, ~$0.11/hr spot. **Pros:** Simple, fits existing patterns, fast startup (VM already running) **Cons:** Always-on cost if not managed; or slow cold-start if managed ### Option B: Spot GPU VM with startup/shutdown management Same as A but use spot pricing and the existing runner_manager Cloud Function to start/stop based on CI demand. **Pros:** 70% cheaper ($0.11/hr), fits existing management pattern **Cons:** Spot can be preempted mid-test (rare for short jobs); cold start ~2-3 min ### Option C: Use a cloud GPU service (Modal, Lambda Labs, etc.) Run the integration tests on a cloud GPU service rather than self-hosted. **Pros:** No infrastructure to manage, pay-per-second **Cons:** More complex CI integration, different from existing patterns ### Recommendation: Option B (Spot GPU VM) The integration test takes <10 minutes on GPU, so spot preemption risk is low. Cold start is acceptable since it's triggered by PR events. Cost: ~$0.02 per CI run. ## Implementation Steps ### 1. Pulumi infrastructure (in karaoke-gen repo) 1. [x] Add `GITHUB_GPU_RUNNER` machine type to `config.py`: `n1-standard-4` + 1× T4 2. [x] Add `GPU_RUNNER_LABELS` to `config.py`: `"self-hosted,linux,x64,gcp,gpu"` 3. [x] Create GPU runner VM in `github_runners.py`: - `n1-standard-4` (4 vCPU, 15GB RAM) - 1× NVIDIA T4 GPU (`nvidia-tesla-t4`) - `guest_accelerators` config - `on_host_maintenance: "TERMINATE"` (required for GPU VMs) - Same NAT/networking as existing runners 4. [x] Create GPU startup script (`github_runner_gpu.sh`): - Install NVIDIA drivers via CUDA repo (cuda-drivers + cuda-toolkit-12-4) - Install CUDA toolkit - Verify GPU: `nvidia-smi` - Pre-download models to `/opt/audio-separator-models` - Register as GHA runner with `gpu` label 5. [x] Add spot scheduling for cost optimization 6. [ ] Run `pulumi up` to create the VM ### 2. Workflow update (in python-audio-separator repo) 7. [x] Update `run-integration-tests.yaml`: - Change `runs-on: self-hosted` to `runs-on: [self-hosted, gpu]` - Change `poetry install -E cpu` to `poetry install -E gpu` - Add `nvidia-smi` verification step - Add 30-minute timeout 8. [ ] Add fallback: if no GPU runner available, fall back to CPU with longer timeout - Deferred: not needed initially, the runner_manager auto-starts the GPU VM on demand ### 3. Startup script details The GPU startup script needs to: ```bash # Install NVIDIA drivers (for Debian 12) sudo apt-get update sudo apt-get install -y linux-headers-$(uname -r) nvidia-driver-535 # Verify GPU nvidia-smi # Install CUDA (for PyTorch) # PyTorch bundles its own CUDA, so we mainly need the driver # Pre-download models pip install audio-separator[gpu] python -c " from audio_separator.separator import Separator sep = Separator(model_file_dir='/opt/audio-separator-models') # Download all models used in integration tests models = [ 'model_bs_roformer_ep_317_sdr_12.9755.ckpt', 'mel_band_roformer_karaoke_aufr33_viperx_sdr_10.1956.ckpt', 'MGM_MAIN_v4.pth', 'UVR-MDX-NET-Inst_HQ_4.onnx', 'kuielab_b_vocals.onnx', '2_HP-UVR.pth', 'htdemucs_6s.yaml', 'htdemucs_ft.yaml', # Ensemble preset models 'bs_roformer_vocals_resurrection_unwa.ckpt', 'melband_roformer_big_beta6x.ckpt', 'bs_roformer_vocals_revive_v2_unwa.ckpt', 'mel_band_roformer_kim_ft2_bleedless_unwa.ckpt', 'bs_roformer_vocals_revive_v3e_unwa.ckpt', 'mel_band_roformer_vocals_becruily.ckpt', 'mel_band_roformer_vocals_fv4_gabox.ckpt', 'mel_band_roformer_instrumental_fv7z_gabox.ckpt', 'bs_roformer_instrumental_resurrection_unwa.ckpt', 'melband_roformer_inst_v1e_plus.ckpt', 'mel_band_roformer_instrumental_becruily.ckpt', 'mel_band_roformer_instrumental_instv8_gabox.ckpt', 'UVR-MDX-NET-Inst_HQ_5.onnx', 'mel_band_roformer_karaoke_gabox_v2.ckpt', 'mel_band_roformer_karaoke_becruily.ckpt', # Multi-stem test models '17_HP-Wind_Inst-UVR.pth', 'MDX23C-DrumSep-aufr33-jarredou.ckpt', 'dereverb_mel_band_roformer_anvuew_sdr_19.1729.ckpt', ] for m in models: sep.download_model_and_data(m) " ``` ## Cost Estimate | Config | Hourly | Per CI run (~10 min) | Monthly (est. 100 runs) | |--------|--------|---------------------|-------------------------| | n1-standard-4 + T4 (on-demand) | $0.61 | $0.10 | $10 | | n1-standard-4 + T4 (spot) | $0.19 | $0.03 | $3 | | Current CPU (e2-standard-4) | $0.13 | $0.07 | $7 | Spot GPU is actually cheaper per-run than current CPU because GPU tests finish 5× faster. ## Files to Create/Modify | File | Repo | Action | |------|------|--------| | `infrastructure/config.py` | karaoke-gen | Add GPU machine type + labels | | `infrastructure/compute/github_runners.py` | karaoke-gen | Add GPU runner VM | | `infrastructure/compute/startup_scripts/github_runner_gpu.sh` | karaoke-gen | GPU-specific startup | | `.github/workflows/run-integration-tests.yaml` | python-audio-separator | Target GPU runner | ## Open Questions - [x] Should the GPU runner be spot or on-demand? → **Spot** ($0.19/hr, ~$3/mo) - [x] Should we keep the CPU fallback for when GPU runner is unavailable? → **Deferred** (runner_manager auto-starts VM) - [x] Should the runner startup script install NVIDIA drivers from scratch each boot, or use a pre-built GCP Deep Learning VM image? → **From scratch** (idempotent, matches existing pattern) - [x] Zone availability: T4 GPUs may not be available in us-central1-a → **Available** in all us-central1 zones (a, b, c, f) ## Rollback Plan The GPU runner is additive infrastructure. If it fails: 1. Change workflow back to `runs-on: self-hosted` (CPU) 2. Destroy the GPU VM via `pulumi destroy` targeting just that resource ================================================ FILE: .cursor/commands/analyze.md ================================================ --- description: Perform a non-destructive cross-artifact consistency and quality analysis across spec.md, plan.md, and tasks.md after task generation. --- The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty). User input: $ARGUMENTS Goal: Identify inconsistencies, duplications, ambiguities, and underspecified items across the three core artifacts (`spec.md`, `plan.md`, `tasks.md`) before implementation. This command MUST run only after `/tasks` has successfully produced a complete `tasks.md`. STRICTLY READ-ONLY: Do **not** modify any files. Output a structured analysis report. Offer an optional remediation plan (user must explicitly approve before any follow-up editing commands would be invoked manually). Constitution Authority: The project constitution (`.specify/memory/constitution.md`) is **non-negotiable** within this analysis scope. Constitution conflicts are automatically CRITICAL and require adjustment of the spec, plan, or tasks—not dilution, reinterpretation, or silent ignoring of the principle. If a principle itself needs to change, that must occur in a separate, explicit constitution update outside `/analyze`. Execution steps: 1. Run `.specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks` once from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS. Derive absolute paths: - SPEC = FEATURE_DIR/spec.md - PLAN = FEATURE_DIR/plan.md - TASKS = FEATURE_DIR/tasks.md Abort with an error message if any required file is missing (instruct the user to run missing prerequisite command). 2. Load artifacts: - Parse spec.md sections: Overview/Context, Functional Requirements, Non-Functional Requirements, User Stories, Edge Cases (if present). - Parse plan.md: Architecture/stack choices, Data Model references, Phases, Technical constraints. - Parse tasks.md: Task IDs, descriptions, phase grouping, parallel markers [P], referenced file paths. - Load constitution `.specify/memory/constitution.md` for principle validation. 3. Build internal semantic models: - Requirements inventory: Each functional + non-functional requirement with a stable key (derive slug based on imperative phrase; e.g., "User can upload file" -> `user-can-upload-file`). - User story/action inventory. - Task coverage mapping: Map each task to one or more requirements or stories (inference by keyword / explicit reference patterns like IDs or key phrases). - Constitution rule set: Extract principle names and any MUST/SHOULD normative statements. 4. Detection passes: A. Duplication detection: - Identify near-duplicate requirements. Mark lower-quality phrasing for consolidation. B. Ambiguity detection: - Flag vague adjectives (fast, scalable, secure, intuitive, robust) lacking measurable criteria. - Flag unresolved placeholders (TODO, TKTK, ???, , etc.). C. Underspecification: - Requirements with verbs but missing object or measurable outcome. - User stories missing acceptance criteria alignment. - Tasks referencing files or components not defined in spec/plan. D. Constitution alignment: - Any requirement or plan element conflicting with a MUST principle. - Missing mandated sections or quality gates from constitution. E. Coverage gaps: - Requirements with zero associated tasks. - Tasks with no mapped requirement/story. - Non-functional requirements not reflected in tasks (e.g., performance, security). F. Inconsistency: - Terminology drift (same concept named differently across files). - Data entities referenced in plan but absent in spec (or vice versa). - Task ordering contradictions (e.g., integration tasks before foundational setup tasks without dependency note). - Conflicting requirements (e.g., one requires to use Next.js while other says to use Vue as the framework). 5. Severity assignment heuristic: - CRITICAL: Violates constitution MUST, missing core spec artifact, or requirement with zero coverage that blocks baseline functionality. - HIGH: Duplicate or conflicting requirement, ambiguous security/performance attribute, untestable acceptance criterion. - MEDIUM: Terminology drift, missing non-functional task coverage, underspecified edge case. - LOW: Style/wording improvements, minor redundancy not affecting execution order. 6. Produce a Markdown report (no file writes) with sections: ### Specification Analysis Report | ID | Category | Severity | Location(s) | Summary | Recommendation | |----|----------|----------|-------------|---------|----------------| | A1 | Duplication | HIGH | spec.md:L120-134 | Two similar requirements ... | Merge phrasing; keep clearer version | (Add one row per finding; generate stable IDs prefixed by category initial.) Additional subsections: - Coverage Summary Table: | Requirement Key | Has Task? | Task IDs | Notes | - Constitution Alignment Issues (if any) - Unmapped Tasks (if any) - Metrics: * Total Requirements * Total Tasks * Coverage % (requirements with >=1 task) * Ambiguity Count * Duplication Count * Critical Issues Count 7. At end of report, output a concise Next Actions block: - If CRITICAL issues exist: Recommend resolving before `/implement`. - If only LOW/MEDIUM: User may proceed, but provide improvement suggestions. - Provide explicit command suggestions: e.g., "Run /specify with refinement", "Run /plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'". 8. Ask the user: "Would you like me to suggest concrete remediation edits for the top N issues?" (Do NOT apply them automatically.) Behavior rules: - NEVER modify files. - NEVER hallucinate missing sections—if absent, report them. - KEEP findings deterministic: if rerun without changes, produce consistent IDs and counts. - LIMIT total findings in the main table to 50; aggregate remainder in a summarized overflow note. - If zero issues found, emit a success report with coverage statistics and proceed recommendation. Context: $ARGUMENTS ================================================ FILE: .cursor/commands/clarify.md ================================================ --- description: Identify underspecified areas in the current feature spec by asking up to 5 highly targeted clarification questions and encoding answers back into the spec. --- The user input to you can be provided directly by the agent or as a command argument - you **MUST** consider it before proceeding with the prompt (if not empty). User input: $ARGUMENTS Goal: Detect and reduce ambiguity or missing decision points in the active feature specification and record the clarifications directly in the spec file. Note: This clarification workflow is expected to run (and be completed) BEFORE invoking `/plan`. If the user explicitly states they are skipping clarification (e.g., exploratory spike), you may proceed, but must warn that downstream rework risk increases. Execution steps: 1. Run `.specify/scripts/bash/check-prerequisites.sh --json --paths-only` from repo root **once** (combined `--json --paths-only` mode / `-Json -PathsOnly`). Parse minimal JSON payload fields: - `FEATURE_DIR` - `FEATURE_SPEC` - (Optionally capture `IMPL_PLAN`, `TASKS` for future chained flows.) - If JSON parsing fails, abort and instruct user to re-run `/specify` or verify feature branch environment. 2. Load the current spec file. Perform a structured ambiguity & coverage scan using this taxonomy. For each category, mark status: Clear / Partial / Missing. Produce an internal coverage map used for prioritization (do not output raw map unless no questions will be asked). Functional Scope & Behavior: - Core user goals & success criteria - Explicit out-of-scope declarations - User roles / personas differentiation Domain & Data Model: - Entities, attributes, relationships - Identity & uniqueness rules - Lifecycle/state transitions - Data volume / scale assumptions Interaction & UX Flow: - Critical user journeys / sequences - Error/empty/loading states - Accessibility or localization notes Non-Functional Quality Attributes: - Performance (latency, throughput targets) - Scalability (horizontal/vertical, limits) - Reliability & availability (uptime, recovery expectations) - Observability (logging, metrics, tracing signals) - Security & privacy (authN/Z, data protection, threat assumptions) - Compliance / regulatory constraints (if any) Integration & External Dependencies: - External services/APIs and failure modes - Data import/export formats - Protocol/versioning assumptions Edge Cases & Failure Handling: - Negative scenarios - Rate limiting / throttling - Conflict resolution (e.g., concurrent edits) Constraints & Tradeoffs: - Technical constraints (language, storage, hosting) - Explicit tradeoffs or rejected alternatives Terminology & Consistency: - Canonical glossary terms - Avoided synonyms / deprecated terms Completion Signals: - Acceptance criteria testability - Measurable Definition of Done style indicators Misc / Placeholders: - TODO markers / unresolved decisions - Ambiguous adjectives ("robust", "intuitive") lacking quantification For each category with Partial or Missing status, add a candidate question opportunity unless: - Clarification would not materially change implementation or validation strategy - Information is better deferred to planning phase (note internally) 3. Generate (internally) a prioritized queue of candidate clarification questions (maximum 5). Do NOT output them all at once. Apply these constraints: - Maximum of 5 total questions across the whole session. - Each question must be answerable with EITHER: * A short multiple‑choice selection (2–5 distinct, mutually exclusive options), OR * A one-word / short‑phrase answer (explicitly constrain: "Answer in <=5 words"). - Only include questions whose answers materially impact architecture, data modeling, task decomposition, test design, UX behavior, operational readiness, or compliance validation. - Ensure category coverage balance: attempt to cover the highest impact unresolved categories first; avoid asking two low-impact questions when a single high-impact area (e.g., security posture) is unresolved. - Exclude questions already answered, trivial stylistic preferences, or plan-level execution details (unless blocking correctness). - Favor clarifications that reduce downstream rework risk or prevent misaligned acceptance tests. - If more than 5 categories remain unresolved, select the top 5 by (Impact * Uncertainty) heuristic. 4. Sequential questioning loop (interactive): - Present EXACTLY ONE question at a time. - For multiple‑choice questions render options as a Markdown table: | Option | Description | |--------|-------------| | A |