diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 2fbaac03e..ec98393a4 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,5 @@ blank_issues_enabled: false contact_links: - name: Security reporting - url: https://github.com/seonghobae/bandscope/security/advisories/new + url: https://github.com/ContextualWisdomLab/bandscope/security/advisories/new about: Use private vulnerability reporting for security issues when available. diff --git a/CHANGELOG.md b/CHANGELOG.md index 34331fb86..ae0457d0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ ### Fixed +- Kept the public BandScope surface honest about stem-preview playback being a coming-soon goal, and aligned the issue-template security route with the current ContextualWisdomLab repository owner. +- Made the vulnerability-reporting fallback reachable through an explicit + security-contact request while forbidding vulnerability details in that public + request, and added a documentation contract that prevents the destination from + disappearing. - Upgraded the local score PDF parser to `pdfjs-dist` 6.2.108, pinned Undici 7.29.0 across the workspace, and constrained PDF loading to copied in-memory bytes with a same-origin bundled worker and npm-generated lock provenance. ## [0.1.3] - 2026-04-29 diff --git a/README.md b/README.md index 74312e3e4..eff039a25 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,127 @@ # BandScope -BandScope is a public GitHub project for a local-first desktop app that turns a song into a practical rehearsal view: likely harmony by section and by instrument or vocal role, section roadmap, tempo and groove cues, rough stem previews, playable ranges, simplification hints, transposition or capo guidance, overlap cues, visible confidence, and rehearsal priorities without DAW complexity. +[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ContextualWisdomLab/bandscope) -It does not promise notation-grade full arrangement transcription or DAW-style production editing. +**귀로만 버티던 카피를, 눈으로 정리해 합주 시간을 음악에 더 쓰게 합니다.** -Brand and product voice source of truth: `docs/brand-story.md` -App security source of truth: `docs/security/app-security.md` -Dependency and SBOM source of truth: `docs/security/dependency-policy.md` -Cross-platform build policy source of truth: `docs/security/cross-platform-build-policy.md` -GitHub bootstrap execution source of truth: `docs/workflow/github-bootstrap-execution-policy.md` +BandScope is a local-first rehearsal assistant for people who need to understand a song quickly before practice. Drop in audio, inspect likely harmony by section and playing role, follow the song form, check tempo and groove cues, see playable ranges and overlap warnings, and turn uncertainty into a short list of things the band should verify first. -## Public repository baseline +Stem preview and role-focused playback remain coming-soon goals; the current workspace does not present its disabled Play stem, Loop section, or Solo / mute others actions as shipped capability. -- GitHub is the source of truth for review, CI/CD, release distribution, Code Security, dependency review, and SBOM retention. -- Gitflow is the default branch strategy. Read `docs/repository/gitflow.md`. -- Contribution entrypoint: `CONTRIBUTING.md` -- Governance baseline: `docs/repository/governance.md` -- Security and reporting baseline: `SECURITY.md` +BandScope is not a DAW, notation-grade transcription system, or authority that claims one automatic answer is always correct. Analysis stays editable, confidence stays visible, and the product is designed to help musical judgment rather than replace it. -## Security quick start +## What you get before rehearsal -Read these before proposing PRDs, TRDs, UX copy, architecture changes, or implementation details: +| Need | BandScope view | +| --- | --- | +| “What happens in each section?” | Section roadmap with likely harmony, entries, dropouts, pickups, stops, tags, and handoffs. | +| “What should *my* part do?” | Role-specific guidance for instruments, vocals, and hand-specific keyboard parts when the arrangement exposes them. | +| “Where will we lose time?” | Rehearsal priorities, confidence flags, range/density or overlap warnings, and simplification hints. | +| “Can we make this playable tonight?” | Transposition, capo/tuning/setup cues and rehearsal-friendly export summaries where supported. | +| “Can I trust the result?” | Local-first analysis, visible uncertainty, editable output, provenance for automatic versus user-confirmed decisions, and narrow security boundaries. | -- `docs/brand-story.md` -- `docs/security/app-security.md` -- `docs/security/dependency-policy.md` -- `docs/security/cross-platform-build-policy.md` -- `docs/workflow/github-bootstrap-execution-policy.md` -- `docs/repository/bootstrap-plan.md` -- `docs/security/code-security.md` -- `docs/security/sbom-policy.md` -- `ARCHITECTURE.md` -- `docs/plans/2026-03-10-bandscope-harness.md` +The product source of truth for audience, tone, and prioritization is [`docs/brand-story.md`](docs/brand-story.md). The tie-breaker is simple: **does this help people rehearse better, sooner, without lowering the accuracy they need?** -If a change touches files, URLs, subprocesses, IPC, WebView, model loading, updates, cache, logs, telemetry, or export behavior, include `Security Notes` and keep the design aligned with narrow allowlists, untrusted-input handling, and safe failure. -If a change adds or updates dependencies, Actions, bundled binaries, or model artifacts, keep it aligned with lockfile, dependency-review, audit, and SBOM policy. -If a change affects build, packaging, release, updater, bundled assets, or target-OS behavior, keep it aligned with the mandatory Windows and macOS build policy. -If GitHub-specific execution is required and no repo exists yet, treat that as bootstrap work rather than a default blocker. +## Quick start -## Current Status +### Prerequisites -The core implementation backlog (Issue #26) has been successfully completed. BandScope now features a functioning local-first workflow, including audio intake, Python-based offline analysis, section/role extraction, manual user overrides, and CSV/JSON cue-sheet exports. The repository maintains 100% measured test coverage and 100% measured docstring coverage for the `services/analysis-engine` package and `apps/desktop` frontend components. +- Node `>=22.13 <23` and npm `10.9.9` for the desktop workspace +- Python 3.12+ and `uv` for the analysis engine +- Rust stable plus the platform-native toolchain when validating the Tauri desktop package -## Workspace layout - -- `apps/desktop` - Tauri + React desktop shell -- `packages/shared-types` - shared TypeScript contracts -- `services/analysis-engine` - Python analysis engine -- `scripts/harness` - reproducible verification entrypoints -- `docs/` - architecture, plans, and testing notes - -## Setup - -### Desktop prerequisites - -- Rust stable toolchain for the Tauri shell -- macOS: Xcode command line tools and accepted Xcode license (`sudo xcodebuild -license`) -- Windows: MSVC build tools - -### Node +Install the JavaScript and Python workspaces: ```bash npm install -``` - -### Python - -```bash uv sync --project services/analysis-engine --group dev ``` -## Verification +Run the repository's primary local verification path: ```bash ./scripts/harness/quickcheck.sh ``` -Optional Rust/Tauri lane: +When the native desktop toolchain is ready, include the Rust/Tauri lane: ```bash BANDSCOPE_ENABLE_RUST_CHECK=1 ./scripts/harness/quickcheck.sh ``` -## Goals of this harness +macOS requires Xcode command line tools and an accepted Xcode license. Windows native packaging requires the MSVC build toolchain. Cross-platform release evidence remains governed by the repository's Windows and macOS build policy rather than by a single developer machine. + +## Product boundaries + +BandScope analyzes for **rehearsal decisions**, not studio prestige. Its target model is `song → section → role`, so simultaneous players can receive different guidance instead of one flattened chord label for the entire arrangement. + +The product should expose, where supported and sufficiently confident: + +- likely harmony by section and role; +- section form and rehearsal cues; +- tempo, groove, entry, dropout, stop, pickup, and handoff cues; +- instrument and vocal ranges; +- stem previews and role-focused listening support (coming soon); +- density/overlap warnings and simplification guidance; +- transposition, capo, tuning, or setup guidance; +- role-specific rehearsal priorities; +- confidence and provenance that distinguish automatic analysis from user-confirmed edits; +- compact cue-sheet/JSON/CSV-style outputs intended for rehearsal use. + +Uncertain output must stay visibly uncertain. Product simplification should remove friction, not hide evidence or lower analytical correctness. + +## Local-first architecture + +The desktop shell and the analysis engine are separated by explicit shared contracts. User-facing rehearsal decisions remain distinct from lower-level analysis evidence, and risky capabilities—files, URLs, subprocesses, IPC, model loading, updates, cache, logs, telemetry, and exports—are expected to stay narrow, allowlisted, and fail-safe. + +Repository map: + +- `apps/desktop` — desktop UI and local application shell +- `packages/shared-types` — cross-boundary rehearsal contracts +- `services/analysis-engine` — offline audio analysis +- `scripts/harness` — reproducible verification entry points +- `docs/` — product, architecture, security, operations, and delivery evidence + +See [`ARCHITECTURE.md`](ARCHITECTURE.md) for the current technical boundary and [`docs/security/app-security.md`](docs/security/app-security.md) for the trust model. + +## Current implementation status + +The repository currently contains the local-first workflow, audio intake, offline analysis path, section/role outputs, playable-range and overlap warnings, manual user overrides, and CSV/JSON cue-sheet exports described by the existing implementation baseline. Coverage and docstring claims remain meaningful only where current repository checks measure them; protected CI and release evidence, not this README, are authoritative for exact-current quality status. + +### Commercial dependency status + +The repository's own source is MIT-licensed, but the current analysis dependency set includes `soundfile>=0.13.1`. The Python SoundFile wrapper is BSD-3-Clause; its documented platform-wheel/runtime path relies on and can bundle **libsndfile**, which is LGPL. That transitive native path does not satisfy ContextualWisdomLab's commercial inbound-license baseline. + +[Issue #1129](https://github.com/ContextualWisdomLab/bandscope/issues/1129) owns replacement/removal of the libsndfile-backed path with commercially approved provenance and equivalent real-audio behavior. Until that closes with Windows/macOS evidence, do not describe the current analysis stack as fully compliant with the organization's commercial inbound-license policy. + +## Security and supply chain + +Before changing product or implementation boundaries, start with: + +- [Application security](docs/security/app-security.md) +- [Dependency policy](docs/security/dependency-policy.md) +- [Cross-platform build policy](docs/security/cross-platform-build-policy.md) +- [Code security](docs/security/code-security.md) +- [SBOM policy](docs/security/sbom-policy.md) +- [GitHub bootstrap execution policy](docs/workflow/github-bootstrap-execution-policy.md) +- [Repository governance](docs/repository/governance.md) + +Changes involving files, URLs, subprocesses, IPC, WebView, models, updates, cache, logs, telemetry, exports, dependencies, Actions, bundled binaries, or model artifacts must preserve those controls and update the corresponding evidence rather than adding local exceptions. + +## Documentation + +- [Public documentation home](docs/index.md) +- [Brand story](docs/brand-story.md) +- [Architecture](ARCHITECTURE.md) +- [Contributing](CONTRIBUTING.md) +- [Security reporting](SECURITY.md) +- [Gitflow](docs/repository/gitflow.md) +- [GitHub bootstrap execution policy](docs/workflow/github-bootstrap-execution-policy.md) +- [Repository governance](docs/repository/governance.md) +- [Deployment/runbook](docs/operations/deploy-runbook.md) + +## License + +BandScope's ContextualWisdomLab-owned source is provided under the [MIT License](LICENSE). -- make the repository bootstrappable on a clean machine -- keep frontend and Python engine contracts explicit -- keep rehearsal-domain outputs explicit across sections, roles, cues, confidence, and exports -- enforce mechanical checks early -- keep docs visible to future agents -- keep brand, product voice, and UX tone consistent through repo docs -- keep security rules visible and mechanically enforced for future agents +Third-party software and model artifacts remain under their own licenses and must satisfy the repository's dependency/SBOM policy and the organization's commercial inbound-license policy. The libsndfile LGPL exception currently reachable through SoundFile is a tracked product/compliance defect, not part of the MIT grant and not an approved commercial baseline. diff --git a/SECURITY.md b/SECURITY.md index ec1e07d14..7ef6ee985 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,14 +2,29 @@ ## Scope -BandScope is a local-first desktop app. Treat every file, URL, metadata field, project file, model artifact, cache entry, and export target as untrusted input. +BandScope is a local-first desktop app. Treat every file, URL, metadata field, +project file, model artifact, cache entry, and export target as untrusted input. ## Reporting vulnerabilities -- Prefer GitHub private vulnerability reporting or a GitHub Security Advisory draft when the repository has that feature enabled. -- For secure reporting of any vulnerability, please email `seonghobae@example.com` or open a [Private Vulnerability Report](https://github.com/seonghobae/bandscope/security/advisories/new) securely. -- We expect vulnerability disclosure timelines to follow coordinated practices, generally providing a 90 days expectation to fix before public disclosure. -- If private reporting is not yet enabled, treat repository bootstrap as incomplete and escalate to the repository owner to enable it before public release. +- Prefer this repository's GitHub private vulnerability reporting or Security + Advisory workflow when that feature is enabled: + [Private security advisory](https://github.com/ContextualWisdomLab/bandscope/security/advisories/new). +- If that private repository feature is unavailable to you, open a + [security contact request](https://github.com/ContextualWisdomLab/bandscope/issues/new?title=Security%20contact%20request) + so a maintainer can establish a private intake channel. The public request must + contain only your GitHub handle and a request for private security contact; do + not include vulnerability details, affected versions, reproduction steps, + logs, links, or attachments. Continue disclosure only after a maintainer + confirms the private channel. +- Never include production credentials, private project material, copyrighted + model artifacts, or other sensitive data in a public report. +- We expect vulnerability disclosure timelines to follow coordinated practices, + generally allowing up to 90 days for remediation before public disclosure + unless severity or an active exploitation situation requires a different + coordinated plan. +- If private reporting is not enabled, treat repository bootstrap as incomplete + and resolve that owner-side reporting boundary before public release. ## Source of truth @@ -18,7 +33,8 @@ BandScope is a local-first desktop app. Treat every file, URL, metadata field, p - Code Security rules: `docs/security/code-security.md` - SBOM retention rules: `docs/security/sbom-policy.md` - Cross-platform build rules: `docs/security/cross-platform-build-policy.md` -- Gitflow and bootstrap rules: `docs/repository/gitflow.md`, `docs/repository/bootstrap-plan.md`, `docs/repository/governance.md` +- Gitflow and bootstrap rules: `docs/repository/gitflow.md`, + `docs/repository/bootstrap-plan.md`, `docs/repository/governance.md` - Brand and product voice: `docs/brand-story.md` - Architecture and repo boundaries: `ARCHITECTURE.md` @@ -29,13 +45,18 @@ BandScope is a local-first desktop app. Treat every file, URL, metadata field, p - do not add generic exec, read, or write surfaces - do not add untrusted HTML to the WebView - use allowlisted IPC only -- require Security Notes for changes that touch files, URLs, subprocesses, IPC, WebView, updates, or model downloads -- require dependency review, audit, SBOM generation, and lockfiles for supply-chain changes -- require Windows and macOS build validation for protected-branch and release-path changes +- require Security Notes for changes that touch files, URLs, subprocesses, IPC, + WebView, updates, or model downloads +- require dependency review, audit, SBOM generation, and lockfiles for + supply-chain changes +- require Windows and macOS build validation for protected-branch and release-path + changes ## Review triggers -If a change touches any of the following, it must reference `docs/security/app-security.md` and include `Security Notes` in the plan, design, or implementation summary: +If a change touches any of the following, it must reference +`docs/security/app-security.md` and include `Security Notes` in the plan, design, +or implementation summary: - file import or export - URL handling diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..7d3911fff --- /dev/null +++ b/docs/index.md @@ -0,0 +1,58 @@ +# BandScope + +BandScope is a local-first rehearsal assistant that turns a song into a practical rehearsal map: section-aware harmony, role-specific cues, song form, tempo and groove guidance, playable ranges, overlap warnings, simplification/transposition hints, visible confidence, and rehearsal priorities without DAW complexity. + +Stem preview and role-focused playback remain coming-soon goals; the current workspace labels its disabled Play stem, Loop section, and Solo / mute others actions accordingly. + +**귀로만 버티던 카피를, 눈으로 정리해 합주 시간을 음악에 더 쓰게 합니다.** + +[Ask DeepWiki](https://deepwiki.com/ContextualWisdomLab/bandscope) + +## Start here + +- [Repository README](https://github.com/ContextualWisdomLab/bandscope/blob/develop/README.md) — product value, setup, boundaries, verification, and licensing status. +- [Brand story](brand-story.md) — product promise, audience, positioning, and voice. +- [Architecture](https://github.com/ContextualWisdomLab/bandscope/blob/develop/ARCHITECTURE.md) — product boundaries, runtime structure, and integration decisions. +- [Application security](security/app-security.md) — desktop trust boundaries and safe-failure expectations. +- [Dependency policy](security/dependency-policy.md) — dependency review, lockfile, audit, and supply-chain rules. +- [Cross-platform build policy](security/cross-platform-build-policy.md) — Windows and macOS release-build expectations. +- [Code security](security/code-security.md) — repository security controls and review expectations. +- [SBOM policy](security/sbom-policy.md) — component inventory and retained software-bill-of-materials evidence. +- [Repository governance](repository/governance.md) — contribution and review governance. +- [Gitflow](repository/gitflow.md) — branch and integration workflow. +- [Contributing](https://github.com/ContextualWisdomLab/bandscope/blob/develop/CONTRIBUTING.md) — contributor entry point. +- [Security reporting](https://github.com/ContextualWisdomLab/bandscope/blob/develop/SECURITY.md) — vulnerability reporting guidance. + +## Product and architecture + +BandScope is built for rehearsal decisions rather than production editing. Its analysis target is `song → section → role`, so different players can receive different guidance in the same section instead of one flattened global chord label. Automatic analysis stays editable and confidence/provenance should remain visible when uncertainty can change rehearsal decisions. + +The desktop shell and offline analysis engine are separated by explicit shared contracts. Files, URLs, subprocesses, IPC, WebView, model loading, updates, cache, logs, telemetry, exports, dependencies, bundled binaries, and model artifacts remain governed by the repository security and supply-chain controls. + +## Onboarding and verification + +Install the Node and Python dependencies described in the README, then use the repository harness as the primary local verification entry point: + +```bash +./scripts/harness/quickcheck.sh +``` + +The optional Rust/Tauri lane can be enabled with `BANDSCOPE_ENABLE_RUST_CHECK=1`. A pull request is not release-ready merely because documentation source exists; repository and central CI, security, SAST, SBOM, coverage, cross-platform build, and review gates remain authoritative. + +## Commercial licensing status + +BandScope's ContextualWisdomLab-owned source is provided under the repository's MIT License. Third-party source, native libraries, and model artifacts remain under their own licenses and must satisfy dependency/SBOM policy. + +The current Python analysis dependency set includes `soundfile>=0.13.1`. SoundFile itself is BSD-3-Clause, but its documented binary-wheel/runtime path relies on and can bundle LGPL libsndfile. [Issue #1129](https://github.com/ContextualWisdomLab/bandscope/issues/1129) owns replacement/removal of that native path. Until it closes with equivalent real-audio and Windows/macOS evidence, the current analysis stack is not represented as fully compliant with ContextualWisdomLab's commercial inbound-license baseline. + +- [MIT project license](https://github.com/ContextualWisdomLab/bandscope/blob/develop/LICENSE) +- [Dependency policy](security/dependency-policy.md) +- [SBOM policy](security/sbom-policy.md) + +## Releases and deeper exploration + +- [GitHub Releases](https://github.com/ContextualWisdomLab/bandscope/releases) +- [Ask DeepWiki](https://deepwiki.com/ContextualWisdomLab/bandscope) +- [ContextualWisdomLab](https://github.com/ContextualWisdomLab) + +This file is the public documentation landing source. GitHub Pages should be described as published only after repository settings, deployment, HTTPS availability, and live content are verified. diff --git a/scripts/checks/verify_docs.py b/scripts/checks/verify_docs.py index 850921591..a67768c39 100644 --- a/scripts/checks/verify_docs.py +++ b/scripts/checks/verify_docs.py @@ -39,12 +39,23 @@ REQUIRED_REFERENCES = { Path("README.md"): [ + "Stem preview and role-focused playback remain coming-soon goals", "docs/security/app-security.md", "docs/security/dependency-policy.md", "docs/repository/gitflow.md", "docs/security/cross-platform-build-policy.md", "docs/workflow/github-bootstrap-execution-policy.md", ], + Path("docs/index.md"): [ + "Stem preview and role-focused playback remain coming-soon goals", + ], + Path(".github/ISSUE_TEMPLATE/config.yml"): [ + "https://github.com/ContextualWisdomLab/bandscope/security/advisories/new", + ], + Path("SECURITY.md"): [ + "https://github.com/ContextualWisdomLab/bandscope/security/advisories/new", + "https://github.com/ContextualWisdomLab/bandscope/issues/new?title=Security%20contact%20request", + ], Path("AGENTS.md"): [ "docs/security/app-security.md", "docs/security/dependency-policy.md", @@ -60,6 +71,12 @@ ], } +FORBIDDEN_REFERENCES = { + Path(".github/ISSUE_TEMPLATE/config.yml"): [ + "https://github.com/seonghobae/bandscope/security/advisories/new", + ], +} + def main() -> int: """Return a failing exit code when required docs or references are missing.""" @@ -75,6 +92,11 @@ def main() -> int: for required_text in required_texts: if required_text not in content: broken_refs.append(f"{path} missing reference: {required_text}") + for path, forbidden_texts in FORBIDDEN_REFERENCES.items(): + content = path.read_text(encoding="utf-8") + for forbidden_text in forbidden_texts: + if forbidden_text in content: + broken_refs.append(f"{path} contains stale reference: {forbidden_text}") if broken_refs: print("Missing required doc references:") diff --git a/services/analysis-engine/tests/test_supply_chain_policy.py b/services/analysis-engine/tests/test_supply_chain_policy.py index 1d8224c5a..6a0853944 100644 --- a/services/analysis-engine/tests/test_supply_chain_policy.py +++ b/services/analysis-engine/tests/test_supply_chain_policy.py @@ -1275,9 +1275,7 @@ def test_workflow_concurrency_cancels_only_superseded_pr_heads() -> None: workflow = (workflows_dir / workflow_name).read_text(encoding="utf-8") assert "concurrency:" in workflow, workflow_name assert "cancel-in-progress: false" in workflow, workflow_name - assert "contents: read" in workflow or "permissions: read-all" in workflow, ( - workflow_name - ) + assert "contents: read" in workflow or "permissions: read-all" in workflow, workflow_name assert "pull_request:" not in (workflows_dir / "release.yml").read_text(encoding="utf-8")