diff --git a/docs/doctoring/product-gap-baseline-2026-09-01.md b/docs/doctoring/product-gap-baseline-2026-09-01.md new file mode 100644 index 000000000..23fde1ea0 --- /dev/null +++ b/docs/doctoring/product-gap-baseline-2026-09-01.md @@ -0,0 +1,106 @@ +# Product Gap Baseline Doctoring — 2026-09-01 + +## Purpose + +This note records why `docs/product-technical-gap-baseline.md` is maintained on canonical PR #1116 instead of layering stale queue snapshots over product truth. It preserves exact-head corrections, causal repairs, naming-contract evidence, and research traceability without rewriting historical observations as current facts. The baseline is a live synthesis governed by `AGENTS.md`, `ARCHITECTURE.md`, the owning security/repository/engineering guidance, and `docs/brand-story.md`; prose does not replace executable repository gates. + +## Current live-state correction — 2026-09-02 + +Protected BandScope source remains `develop@749511c3ad4000090048718f685c6bee6b3d2c25` at this capture. A fresh complete accessible-repository sweep begun at **2026-09-02 21:56 KST** queried all **74** currently visible `ContextualWisdomLab` repositories individually and summed **2,940 open pull requests**. A subsequent organization-wide aggregate returned **2,941 open pull requests** with `incomplete_results=false`. The one-PR difference is a non-atomic observation, not attribution to a particular repository: PR creation and closure can occur during or after a sequential census, so the result remains dated evidence rather than permanent product truth. + +`ContextualWisdomLab/bandscope` was the highest observed backlog at **194 open pull requests** and a fresh issue search returned **19 open issues**. Fresh high-backlog peers were `ContextualWisdomLab/naruon` 148, `ContextualWisdomLab/OriginWeave` 142, `ContextualWisdomLab/newsdom-api` 139, `ContextualWisdomLab/pg-erd-cloud` 138, `ContextualWisdomLab/TEPP` 130, `ContextualWisdomLab/.github` 128, `ContextualWisdomLab/html4tree` 127, `ContextualWisdomLab/Orgmetra` 117, and `ContextualWisdomLab/LineageWeave` 113. BandScope remains selected by both backlog and product responsibility: it owns the buyer-facing local-first rehearsal/audio path plus high-leverage release, security, persistence, workflow, and shared-contract boundaries. + +The accessible repository set for this capture was: `ContextualWisdomLab/kaefa`, `ContextualWisdomLab/aFIPC`, `ContextualWisdomLab/nonnest2`, `ContextualWisdomLab/html4tree`, `ContextualWisdomLab/mightyETL`, `ContextualWisdomLab/xtrmLLMBatchPython`, `ContextualWisdomLab/pg-erd-cloud`, `ContextualWisdomLab/clearfolio`, `ContextualWisdomLab/bandscope`, `ContextualWisdomLab/newsdom-api`, `ContextualWisdomLab/scopeweave`, `ContextualWisdomLab/naruon`, `ContextualWisdomLab/linux-cluster-ops`, `ContextualWisdomLab/argos`, `ContextualWisdomLab/codec-carver`, `ContextualWisdomLab/appguardrail`, `ContextualWisdomLab/vooster`, `ContextualWisdomLab/.github`, `ContextualWisdomLab/ContextualWisdomLab.github.io`, `ContextualWisdomLab/seedream_evasepic`, `ContextualWisdomLab/contextual-orchestrator`, `ContextualWisdomLab/hyosung-itx-slogan-brief`, `ContextualWisdomLab/fast-mlsirm`, `ContextualWisdomLab/semantic-data-portal`, `ContextualWisdomLab/noema`, `ContextualWisdomLab/wardnet`, `ContextualWisdomLab/feelanet-adfs`, `ContextualWisdomLab/gyeot`, `ContextualWisdomLab/pg-llm-batch`, `ContextualWisdomLab/keyverse`, `ContextualWisdomLab/inkspan`, `ContextualWisdomLab/disksage`, `ContextualWisdomLab/free-router`, `ContextualWisdomLab/RankWeave`, `ContextualWisdomLab/ThreadWeave`, `ContextualWisdomLab/EgressWeave`, `ContextualWisdomLab/IRT-bibliography-set`, `ContextualWisdomLab/g7`, `ContextualWisdomLab/saju-caldav`, `ContextualWisdomLab/xtrm-lead-pi-outbound`, `ContextualWisdomLab/ccube-jco-potential-customer`, `ContextualWisdomLab/9drive`, `ContextualWisdomLab/macos_utility_packs`, `ContextualWisdomLab/OmniRoute`, `ContextualWisdomLab/graphify`, `ContextualWisdomLab/life-os`, `ContextualWisdomLab/four-pillars`, `ContextualWisdomLab/DiagramWeave`, `ContextualWisdomLab/trivy-sarif-repro`, `ContextualWisdomLab/TEPP`, `ContextualWisdomLab/OriginWeave`, `ContextualWisdomLab/EmbedRelay`, `ContextualWisdomLab/mhtml-etl-gateway`, `ContextualWisdomLab/psychometrics-commons`, `ContextualWisdomLab/LineageWeave`, `ContextualWisdomLab/Orgmetra`, `ContextualWisdomLab/enterprise-architecture-core`, `ContextualWisdomLab/context-graph-contracts`, `ContextualWisdomLab/metering-billing-platform`, `ContextualWisdomLab/accounting-information-platform`, `ContextualWisdomLab/quarantine-sandbox-runtime`, `ContextualWisdomLab/governance-risk-compliance`, `ContextualWisdomLab/CalendarWeave`, `ContextualWisdomLab/j-planner`, `ContextualWisdomLab/learning-interoperability-contracts`, `ContextualWisdomLab/learning-record-store`, `ContextualWisdomLab/learning-management-platform`, `ContextualWisdomLab/learning-content-studio`, `ContextualWisdomLab/ELUNVERA`, `ContextualWisdomLab/PolicyWeave`, `ContextualWisdomLab/litellm-patched-proxy`, `ContextualWisdomLab/pingora-gateway`, `ContextualWisdomLab/ConceptWeave`, and `ContextualWisdomLab/supply-chain-control-plane`. + +Volatile queue counts are dated evidence, not product truth. Every branch advance prevents predecessor checks and approvals from transferring to the successor head while preserving the original results as historical evidence, and every later census must preserve non-simultaneous movement rather than manufacture a false simultaneous total. + +## Canonical baseline recovery + +A source-integrity defect was verified on predecessor #1116 head `f6207ef2cadadb5d3852e0595ab2f0b62e20a06b`. That census-only commit unintentionally removed 83 lines from `docs/product-technical-gap-baseline.md` and left the canonical product/technical contract ending immediately after §7.4. The deleted material included the identifier-policy migration boundary, Rust compute ownership, real-audio scientific acceptance, security/privacy, UI/UX evidence, quality/operability, release-gate, and traceability sections. + +The parent `adbd9df394957ee1a2c68893b8a6025cdcf058c9` was inspected as recovery evidence before editing. The canonical branch then advanced through ordinary non-force history to `ec67371791c653eed21705600775c06ecd531cc7`, restoring the lost contract. Historical 18:30 KST evidence recorded #1116 at `docs/gap-baseline-2026-08-31@cdc9d2b27ed7c9c81a49bd7dd6279d79de7f73a9` before subsequent repairs. A prior census correction advanced the canonical baseline through ordinary non-force commit `e156730ed5370fd579c3a8813493c67c5191b054` with exactly three additions and three deletions for the 74-repository/2,934-PR capture, high-backlog peer counts, and stale #968 stack evidence. The current 21:56 KST census was then applied directly to the unchanged canonical source in ordinary non-force commit `2958dab046a2bf6bc5fc752d29ae4206fc67e094`, preserving the complete durable contract while updating only live delivery evidence. A document cannot truthfully self-embed the SHA of the commit that contains that self-reference, so successor head identity is always fetched from GitHub immediately after each write rather than inferred from prose. + +The restored baseline carries the buyer PRD, end-to-end stories, DDD bounded contexts/context map/ubiquitous language/domain events, TRD topology and transport diagrams, persistence/versioning rules, organization naming and database migration rules, Rust-first compute ownership, persistence ERD discipline, rights-safe real-audio scientific acceptance, security/privacy, Storybook/Figma/shipped accessibility evidence, the 100% quality floor, release acceptance, and APA traceability. The current repair preserved that complete contract while refreshing the census, protected-branch evidence, merge-train identities, and organization queue RCA. It also preserves the project-recovery origin state model: recovery begun without a source fails back to `NoSource`, while recovery begun with an admitted source fails back to `Ready` without manufacturing successful recovery. + +## Organization naming-contract evidence + +The organization-owned naming rule is semantic, not casing-based. Multiword names such as `section_id`, `sectionId`, `SectionId`, `firstGrooveChange`, and `SectionRoadmap` are valid. Generic single-word organization-owned names are repaired where bounded-context meaning is available. Persisted, released, IPC, vendor, or protocol spellings do not change in place merely to satisfy style; they cross explicit migration/version/anti-corruption boundaries. + +### Workspace role vocabulary — #1130 + +`ContextualWisdomLab/bandscope#1130` owns the **active-PR** workspace role projection; it is not protected shipped truth until normally integrated. On that owner branch the semantic vocabulary is `RehearsalRoleOption.roleId`, `roleName`, and primary `roleOptions`, while the previous component projection `{ id, name }[]` is retained only as an explicitly deprecated `LegacyRehearsalRoleOption` adapter input translated by `normalizeLegacyRoleOptions`. Protected `develop` must not be described as already containing that projection until #1130 or its semantic successor lands. No persisted project, IPC, database, vendor, or shared-types wire contract is intended to change in that slice. + +### Score attachment compatibility boundary — #1092 + +`ContextualWisdomLab/bandscope#1092` exposed another material naming defect in a buyer-visible workspace path. The persisted project format already uses `scoreAttachments` entries with compatibility keys `id` and `fileName`; changing those keys in place would silently break stored projects. The safe repair therefore keeps the wire shape and moves semantic naming immediately behind an anti-corruption boundary. + +The focused RED commit `35dc521f03711d749771751ecf39b904f193057d` changed the regression to require `{ scoreId, scoreFileName }` while production still returned `{ id, fileName }`. The GREEN production commit `8cd6756ef242d99fc323181b21b58f96fe24c731` introduced `TrustedScoreAttachment`, validates only the compatibility wire keys at `trustedScoreAttachment`, returns semantic `scoreId`/`scoreFileName`, and renamed touched workspace-owned locals to bounded score/range vocabulary. No database table, column, index, constraint, sequence, migration, foreign key, ORM/query mapping, UPSERT path, lock topology, or persisted project wire key changed. + +A CodeRabbit review also identified a truthful-documentation defect: `ARCHITECTURE.md`, `AGENTS.md`, `CHANGELOG.md`, and `CLAUDE.md` could be read as promising that any persisted score attachment is openable. Production actually requires both validated attachment metadata and a live Score workspace; reopened metadata-only projects or untrusted metadata fall back to adding a score or checking the range by ear. The same canonical branch was directly repaired in commits `5af64f5c3ddc85b237a4426678de0233ee4f5fdf`, `5a2abb1aa404eb0df133cbaeade44439621e56d6`, `893b87a53faaa08f3f972a4dc264c47ff9c83511`, and `8099e3b2525723474aca09db4d669167035263b3` so product guidance and production now express one invariant. + +The recorded #1092 check observation belongs to historical exact head `8099e3b2525723474aca09db4d669167035263b3`: 27 check runs were observed, with required/security lanes including `dependency-review`, `scorecard`, and `trivy-fs` still queued at that capture. It is historical evidence, not current merge-readiness evidence. A skipped manual-evidence helper is not a substitute for required evidence, and no predecessor success is promoted. + +### Release identity — #1126 + +`ContextualWisdomLab/bandscope#1126` remains a separate release-identity naming lane. Its repository-owned helper/test vocabulary uses names such as `repository_root`, `release_version`, `workflow_text`, `job_marker`, `workflow_lines`, `job_start_index`, `job_end_index`, `release_guard`, `expected_version`, `package_document`, and `publication_job`. External Pytest fixture names and package/Tauri JSON keys remain unchanged where their contracts own those spellings. This is an internal naming boundary and does not itself require a persistence migration. + +## Database discipline + +BandScope's current project authority is file/project-format based rather than an organization-owned relational production schema, so the #1092 repair required no DDL. The canonical baseline nevertheless records the database rule for future owned schemas: use semantic multiword snake_case for tables, columns, indexes, constraints, sequences, views, materialized views, functions, and related objects; normalize to 3NF where relevant; and verify migration ordering, foreign keys, indexes, constraints, ORM/query mappings, UPSERT semantics, hot-partition risk, locking/read-write separation, compatibility, rollback, and recovery before integration. + +The protected `.bscope` documentation currently describes structural schema validation but only proposes introducing a format-version field if future structural changes require one. Therefore `project_format_version` is a **target migration contract**, not current protected persisted behavior. Any future rename of a persisted generic field must first introduce a compatible versioned reader/migration/writer path with previous-version fixtures, deterministic repeated migration, rollback/recovery, and no dual writable truth. + +## Queue and causal-owner evidence + +Issue #966 remains the dependency-aware merge-train control plane, while PR #968 retains unique executable queue machinery: bounded pagination, exact active-head capture, independently resolved target tips, deterministic ordering, malformed/incomplete/duplicate rejection, network-independent validation, and symlink-safe atomic publication. Immediately before the current baseline write, #968 was `docs/bandscope-product-readiness-baseline@9f25cf669eaaad7e1e2296463a73eb2c5620dc66` with base branch `docs/gap-baseline-2026-08-31` and recorded base SHA `cdc9d2b27ed7c9c81a49bd7dd6279d79de7f73a9`, while #1116 had already advanced to `0335ba3d6d13086ab64dbf4af54d177f841fa39d`; GitHub still reported #968 mergeable. The 20:30 census repair advanced #1116 to `e156730ed5370fd579c3a8813493c67c5191b054`, and the 21:56 census repair advanced it again to `2958dab046a2bf6bc5fc752d29ae4206fc67e094`. Therefore #968 requires fresh ordinary non-force reconciliation to the canonical base while preserving its unique queue-control/test tree. Predecessor checks and reviews do not transfer merely because the stack remains mergeable. + +The baseline owner #1116 and temporal-analysis PR #1117 are separate evidence lanes. PR #1117's previously recorded `refactor/temporal-features-api@b98f266d2356d56be624fb617580b5252e85baaa` metadata and review state are historical in this cycle; that evidence never constitutes #1116 or #968 readiness. + +Repository-local Trivy PR-head configuration remains owned by open BandScope #1119. Its freshly audited exact head is `fix/trivy-pr-code-scanning@bb3a9735a00a64347e8a5d0e3f2d92243bdbc585`. Its PR-body `current head` text still names predecessor `b005ae91cb0e41753554c2cea7627c7063207656`, so that metadata must be repaired separately without pretending predecessor checks transfer. Its stale push-only policy test and intended Trivy `pull_request` contract have already been repaired on the canonical branch; visible review threads were resolved at audit, while queued/non-terminal exact-head jobs remain non-passing and are not spam-rerun. + +The latest protected central control-plane evidence revalidated in this cycle is `ContextualWisdomLab/.github@f610598c585d8dfdabe6fd82204173e23ad09841`. Issue `.github#712` remains the organization-wide runner-admission/queue-health owner. Cross-repository evidence shows jobs waiting before checkout with no runner assignment on both `ubuntu-latest` and explicit `ubuntu-24.04`, including the same Wardnet exact head that previously completed successfully on the same explicit label. That falsifies a simple leaf runner-label or source-code defect but does not by itself identify hosted-runner capacity, organization concurrency/admission policy, billing/quota, or provider scheduling as the final cause. Recent protected scheduler fixes, including #1712's rejected-cancellation accounting repair, reduce avoidable duplicate-dispatch ambiguity but do not convert queued exact-head evidence into success. + +A current review suggestion named `.github#1567` as an unresolved central coverage prerequisite. Fresh revalidation in this cycle shows `ContextualWisdomLab/.github#1567` is **closed and unmerged** (`merged_at=null`), so it is not represented as a live prerequisite. Its historical body remains useful evidence that merged-tree coverage must reach 100% and that predecessor checks do not transfer, but any current coverage blocker must be re-established on the actual protected owner rather than inferred from that retired PR. + +The connected repository write surface permits ordinary source/workflow/PR changes but does not expose organization runner-pool, Actions quota/billing, or equivalent admission-setting mutation. A fresh protected `develop` read succeeded in this cycle and confirmed these 16 required contexts: `ci / build-and-test`, `dependency-review`, `security-audit`, `sbom`, `release-preflight`, `gate / build / windows`, `gate / build / macos`, `trivy-fs`, `coverage-evidence`, `opencode-review`, `strix`, `scan-pr-queue`, `osv-scan`, `scorecard`, `Analyze (javascript-typescript)`, and `Analyze (python)`. Unchanged-head reruns and runner-label churn are not substitutes for causal evidence. Fresh #1009 audit also confirmed its source-selection authority is already repaired: local, demo, YouTube, and Open Project intake share one synchronous `workspaceIntakeInFlightRef`; failed or cancelled replacement preserves the prior valid selection, and conflicting source/import/analysis controls respect the same pending boundary. The baseline state model mirrors those semantics instead of leaving source replacement undefined. + +Canonical product ownership remains explicit: #961 owns active rehearsal player/transport, #962 owns crash-safe project persistence, **#963 owns diagnostics/support bundles**, and #960 owns trusted release/distribution. These scopes are distinct even when one leaf PR exercises more than one acceptance gate. + +## Security Notes + +This documentation change introduces no new runtime authority. The durable security contract remains: untrusted file/project/codec/model/update/subprocess inputs cross typed validation boundaries; ordinary local analysis uses allowlisted Tauri IPC, bounded stdin/stdout, or loopback strictly limited to `127.0.0.1` where a loopback adapter is explicitly required, and does not depend on public HTTP or another network path. Structured inputs are schema-validated before domain use. Subprocess execution uses argument arrays and `shell=False`-equivalent non-shell authority. Logs and support bundles redact credentials, raw audio/project payloads, and absolute local paths. Release artifacts require signature/checksum/SBOM/provenance verification at the owning distribution boundary. Queued, pending, neutral, skipped-required, stale, or predecessor evidence is non-passing. + +## Historical observations and RCA + +Historical queue observations remain useful only as dated evidence. On 2026-09-01 10:31 KST BandScope had 190 open pull requests. At 2026-09-01 13:29 KST, 72 repositories were visible and an organization recount reported 2,697 open pull requests, with BandScope at 188. Later 2026-09-02 sweeps observed 2,827/2,834 and 185 BandScope, 2,856/2,855 and 194 BandScope, then 2,865/2,866 and 196 BandScope, then 2,889/2,889 and 196 BandScope, then 2,894/2,894 and 196 BandScope, then 2,894/2,894 and 193 BandScope, then 2,907/2,908 and 193 BandScope, then 2,914/2,914 and 193 BandScope, then 2,934/2,934 and 193 BandScope, before the current **2,940 sequential / 2,941 aggregate and 194 BandScope** capture. None may be reused as an undated permanent count. + +Review findings previously validated on #1116 included stale PR evidence, a false repository-wide Mermaid-absence claim, stale product-owner issue numbers, and prose-inherited live Noema/PR claims. In this cycle a fresh reviewer also reported that the documentation gate lacked four project-recovery transitions. Exact-head revalidation showed the finding had already become stale: `scripts/checks/verify_docs.py` requires the four origin-preserving transitions and the canonical baseline contains all four exactly. The stale thread was answered with exact-head evidence and resolved without weakening the checker or churning correct source. + +A historical review-gate example remains instructive. PR #956 once had a predecessor exact-head Strix failure unrelated to its articulation privacy code. The central workflow exhausted the NVIDIA primary, encountered an EOL NVIDIA fallback, then used GPT-5.4 through `/v1/chat/completions` with function tools plus non-none reasoning effort; the provider rejected that contract. `ContextualWisdomLab/.github#1350` repaired the GPT-5.4 tool/reasoning contract in commit `f655a901f7ccdfef0d62694c818ad2896a2f5da1`. At that historical capture, `.github/main@1186a9f4e5eda7683b23ae63d2c806831743432a` contained that fix. PR #956 was then advanced through ordinary history to `e46a7aa3121c902ebcf9ea9d256a199659a482df` using the identical tree so fresh workflows could be created. This evidence remains historical and must be re-fetched before any current action. + +PR #1117 similarly demonstrated that the queue cannot be truthfully summarized as “all code checks fail”: at its historical capture, exact head `b98f266d2356d56be624fb617580b5252e85baaa` had successful repository CI/release/security/SBOM workflows while `opencode-review` remained in progress. Pending was still non-passing, but it had a different cause from older blanket claims. + +## Research / standards review + +The baseline uses current authoritative standards/research as acceptance anchors rather than decorative citations: + +- ISO/IEC 25010:2023 defines the current SQuaRE product-quality model and supports requirements, design objectives, testing objectives, acceptance criteria, and product-quality evaluation. +- NIST SP 800-218 SSDF v1.1 emphasizes tracked security requirements/design decisions, provenance, and root-cause-oriented secure development. +- WCAG 2.2 is a W3C Recommendation covering focus visibility, dragging alternatives, target size, consistent help, redundant entry, accessible authentication, and the broader accessibility baseline required by the product. +- MIREX real-recording evaluation practice supports rights-safe production-path MIR evidence rather than synthetic-only accuracy claims. + +### APA 7th references + +International Organization for Standardization, & International Electrotechnical Commission. (2023). *ISO/IEC 25010:2023 Systems and software engineering—Systems and software Quality Requirements and Evaluation (SQuaRE)—Product quality model* (2nd ed.). ISO. + +Music Information Retrieval Evaluation eXchange. (2025). *Audio beat tracking*. MIREX Wiki. https://music-ir.org/mirex/wiki/2025:Audio_Beat_Tracking + +Souppaya, M., Scarfone, K., & Dodson, D. (2022). *Secure Software Development Framework (SSDF) Version 1.1: Recommendations for mitigating the risk of software vulnerabilities* (NIST Special Publication 800-218). National Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-218 + +World Wide Web Consortium. (2023). *Web Content Accessibility Guidelines (WCAG) 2.2*. https://www.w3.org/TR/WCAG22/ + +## Decision + +PR #1116 remains the canonical baseline owner. Its source contains the complete recovered PRD/TRD/DDD/naming/Rust/science/security/UI/quality/release/traceability contract plus current delivery evidence. PR #1025 is an older competing owner of the same path; it may only be closed as superseded when every unique semantic requirement remains executable or represented in the canonical source and its discussion history is preserved. + +Future loops should refresh live counts and exact-head evidence when they materially change prioritization or causal ownership. They must not rewrite stable product/architecture sections merely to chase a volatile PR number, and they must never repeat the predecessor truncation failure by replacing a complete canonical document with a partial census fragment. \ No newline at end of file diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md new file mode 100644 index 000000000..5f47f6566 --- /dev/null +++ b/docs/product-technical-gap-baseline.md @@ -0,0 +1,346 @@ +# BandScope Product-Technical Gap Baseline + +Last updated: 2026-09-07 +Evidence capture: live GitHub state is dated at observation; protected refs are revalidated before merge/release claims +Protected product truth: `develop@314ddeae7b775a4957594b599358c8255617eb2e` + +## Purpose + +This document is the canonical live product/technical gap synthesis for BandScope. `AGENTS.md`, `CLAUDE.md`, `ARCHITECTURE.md`, owning ADR/PRD/TRD/security/test/release documents, protected source, and live GitHub state remain the detailed authorities. If this synthesis conflicts with an owning source, the owning source wins and this file must be repaired. + +Mutable Draft heads are deliberately not embedded as long-lived truth in this source. The live PR/Issue state is the exact-head authority for active work; this baseline records the semantic contract and ownership. This avoids making the canonical baseline stale whenever a correctly progressing Draft gains an ordinary descendant commit. + +BandScope is a local-first rehearsal decision product. Commercial completion means a musician can admit an authorized real recording, obtain reproducible evidence-backed rehearsal guidance, move directly into audible rehearsal, preserve and recover the project without silent data loss, hand off only bounded intended data, diagnose failures without leaking private media, and install/update/rollback a verifiable signed build. + +BandScope is not a DAW, notation editor, mandatory cloud service, or an authority that presents uncertain machine analysis as unquestionable musical truth. + +## 1. Product requirements baseline (PRD) + +### 1.1 Buyer jobs and outcomes + +The product must let a working musician or band member: + +1. select an authorized local recording and reach useful rehearsal guidance without first exporting media to a cloud service; +2. understand form, section boundaries, harmony, groove/timing, entries/dropouts, range, overlap, handoffs, setup cues, and role-specific preparation with uncertainty visible where evidence does not justify certainty; +3. move from an insight to audible rehearsal through one transport authority supporting play/pause/seek/stop, section/range loop, count-in, playback rate, cue navigation, and source-backed stem controls where admitted stems actually exist; +4. correct machine evidence without erasing the original estimate, confidence, model identity, source identity, or user-confirmed provenance; +5. close and reopen work, survive interrupted writes and migrations, and recover the last known-good project without a partial write replacing it; +6. export a bounded collaboration handoff without creating a second authoritative project store; +7. inspect redacted diagnostics and a user-previewable offline support bundle without ordinary logs containing raw audio, project payloads, credentials, or absolute paths; +8. install and update a build whose version, signature, checksum, SBOM, provenance, rollout state, model/dependency inventory, and rollback/repair path can be verified. + +Representative end-to-end stories remain deliberately broader than micro-features: + +- As a player, I can open my local song, see the first high-value rehearsal action, start the relevant passage, count it in, and loop it without rebuilding transport elsewhere. +- As a returning user, I can reopen the same project after a crash or interrupted save and recover the last known-good rehearsal state and durable source intent without silently manufacturing new source authority. +- As a user of keyboard or assistive technology, I can perform the same primary rehearsal actions and obtain exact-value alternatives to visual-only maps, timelines, or waveforms. +- As an installer, I can distinguish an unsigned validation artifact from a verifiable production release and roll back a bad staged update without app/model/dependency identity drifting silently. + +### 1.2 Commercial acceptance boundary + +A buyer-visible capability is complete only when its production path, negative/error states, persistence/recovery behavior where applicable, security boundary, accessibility contract, real-audio/scientific evidence where applicable, and release evidence are integrated on one protected identity. Storybook/Figma-only states, generated arrays, synthetic audio, direct feature matrices, predecessor-head checks, model reviews, or screenshots cannot substitute for the relevant production acceptance path. + +Near-term order remains: merge-train convergence; trusted distribution; active rehearsal player; crash-safe project; real-audio science/resource admission; diagnostics; activation; accessibility/design parity; 100% repository-owned production statement/branch/edge coverage and public API documentation. + +## 2. Live delivery authority + +A complete accessible-repository census begun 2026-09-02 21:56 KST observed 74 `ContextualWisdomLab` repositories. Sequential counts summed to 2,940 open pull requests and the subsequent organization aggregate returned 2,941 with `incomplete_results=false`; the one-PR difference is non-atomic observation, not attribution. BandScope had 194 open PRs and 19 open issues in that dated capture. Later counts are not inferred from it. + +The current protected BandScope product source is `develop@314ddeae7b775a4957594b599358c8255617eb2e`. The recorded protection contract contains 14 required contexts, including retired producer names `Analyze (javascript-typescript)` and `Analyze (python)`. Issue #1172 owns migration to the central producer names `CodeQL compatibility analysis (javascript-typescript)` and `CodeQL compatibility analysis (python)`. Restoring a duplicate repository scanner or weakening/removing CodeQL coverage is not an acceptable workaround. + +Operational evidence rule: queued, pending, skipped-required, cancelled, neutral, failed, absent, stale, predecessor-head, protected-base, model-only, status-only, self/author, or administrative-bypass evidence is non-passing. A head change invalidates predecessor review/check receipts for readiness. Force-push, destructive rebase, self-approval, gate weakening, fabricated evidence, and unrelated rollback are prohibited. + +## 3. Shipped protected truth + +Only behavior reachable from protected `develop@314ddeae7b775a4957594b599358c8255617eb2e` is shipped truth. + +- BandScope is a React/Vite desktop workspace hosted by Tauri with local orchestration, a Python analysis service, and Rust/PyO3 numerical/native kernels. +- Typed Tauri IPC and bounded local process/stdin-stdout boundaries are the intended local execution model; ordinary rehearsal analysis does not require a public cloud service. +- Protected workflow consolidation #1165 removes duplicate repository PR scanners while central required workflows own PR evidence. Product branches must adopt that result rather than recreate removed security writers locally. +- Protected truth still does not satisfy the complete active-player, crash-recovery, rights-cleared real-audio, diagnostics, activation, accessibility-parity, or trusted-distribution contracts below. +- The latest immutable public GitHub release revalidated in the current delivery lineage remains `v0.1.3`, published 2026-04-28 UTC. It is historical release evidence, not proof that the current protected head is commercially release-ready. + +## 4. Canonical active workstreams + +Active work is Draft/unshipped until normally integrated into protected `develop` with current-head gates and qualifying independent review. Exact mutable heads below are intentionally delegated to the named live PR/Issue rather than copied into this source. + +| Boundary | Canonical live owner / evidence | Current status | +|---|---|---| +| Merge-train control plane | Issue #966; queue lane PR #968 | #968 is Draft on #1116 and owns exactly 22 queue-control workflow/ADR/reference/manifest/script/test files. Every #1116 source move requires ordinary non-force reconciliation preserving those files and a non-divergent baseline blob. Live #968 state plus fresh #1116→#968 compare is exact-head authority. | +| Canonical baseline | PR #1116, this file | Draft. This source is the single writer for `docs/product-technical-gap-baseline.md`; active PR behavior is described as Draft evidence, never promoted into shipped truth. | +| Trusted distribution | Issue #960; release-identity lane #1126; dependency/model blockers #1129/#1180/#1181 | Windows signing, macOS signing/notarization, checksums, SBOM/provenance, signature-verified updater, staged rollout, rollback/repair, `libsndfile` removal, and a commercially admissible immutable separation model are not yet one integrated protected-head receipt. | +| Active rehearsal player | Issue #961; #971 with source stack #1159 → #1160 | #1160 remains Draft and has not yet adopted current #970. Native stem admission/playback/source switching exists on that branch, but persisted source intent must be reconciled with fresh Full mix/current-stem audible authority after reopen. Missing preferred stems must fail closed to Full mix. | +| Crash-safe project | Issue #962; PR #970 | #970 is Draft and has ordinarily adopted Resource Admission #866. It implements v3 Save/load, path-free source evidence, restart exact-content re-admission, analysis-time source revalidation and snapshot-bound decode, local Demucs compatibility admission, mounted Open→Save preservation of native project selection plus `selectedPlaybackSource`, and bounded PyTorch weights-only incompatibility handling. Autosave/global recovery UX, broader fault injection, descriptor-bound higher-parent authority, and Active Player audible-authority reconstruction remain open. | +| Real-audio science | Issue #770 and active benchmark lanes | Rights-cleared decoded-audio MIR acceptance, recognized task metrics, uncertainty and reproducibility remain incomplete. Synthetic/generated audio remains unit-test evidence only. | +| Resource admission/decode | Issue #781; PR #866; commercial dependency defect #1129 | #866 owns app-owned audio materialization/publication and `LocalAudioPublicationIdentity`; #970 consumes it through typed persistence/re-admission ACLs. #1129 still owns removal of the `soundfile`/`libsndfile` LGPL runtime path with equivalent supported-platform real-audio/SBOM evidence. | +| Commercial separation model | Issue #1180; rights blocker #1181 | #970's local Demucs compatibility admission is technical Draft evidence only. Distribution still requires an immutable commercially admissible exact artifact with full provenance/size/digest-or-signature, explicit serialization/loader policy, release inventory, updater/rollback behavior, and rights-cleared Windows/macOS real-audio evidence. #1181 independently blocks upstream pretrained weights absent explicit commercial-use/redistribution rights. | +| Diagnostics/supportability | Issue #963 | Typed redacted crash/hang evidence and a user-previewable offline support bundle remain incomplete. | +| Activation | Issue #964 | A measured production-path first rehearsal remains incomplete. | +| Accessibility/design parity | Issue #965 and active component/player lanes | WCAG 2.2 AA, keyboard/screen-reader parity, KO/EN/JA/ZH/VI/ES/DE/FR expansion, CJK/text expansion/font fallback, exact-value alternatives, and current-head material-UI evidence remain incomplete. | +| Quality floor | PR #1057 and successors | Repository-owned production Docstring/rustdoc, Test, and Edge Case Coverage targets remain 100%; denominator reduction, skip/xfail, generated-code relabeling, or source-text-only success cannot manufacture compliance. | + +The product boundary, tests, contracts, and unique behavior decide succession, not PR number or title. Duplicate closure requires a technical succession receipt naming the unique behavior/tests preserved in the successor. Checks, approvals, and model output do not transfer to a changed successor head. + +## 5. Merge-train and succession contract + +Backlog convergence is an engineering risk because micro-PR fan-out creates duplicate writers, stale evidence, dependency ambiguity, competing local state, and review/check churn. + +PR #968 owns the executable #966 queue machinery: bounded GitHub pagination, exact active-head capture, independent base-tip resolution, deterministic ordering, malformed/incomplete/duplicate rejection, symlink-safe atomic publication, dependency/succession metadata, network-independent validation, deterministic human projection/parity, and exact-head artifact preservation. It must not be discarded as stale documentation. + +The canonical baseline branch must remain an ordinary descendant of current protected `develop`. PR #968 targets #1116 rather than protected `develop` directly. Every #1116 advance therefore changes #968's target tip and requires another ordinary non-force descendant on #968 that preserves its queue-owned files. The baseline deliberately avoids embedding the descendant #968 SHA because doing so would make the source self-invalidating at the moment the required adoption commit is created. The same principle applies to other moving Draft heads: their live PR state is exact-head authority while this document owns stable semantic status. Historical SHAs remain audit evidence only. + +Review/check waiting is lane-local rather than a global blocker: while one head waits for hosted evidence, other independent canonical work may proceed. Failed checks are RCA/fix/rerun work, not justification to weaken gates. + +## 6. Domain model and ownership + +For the musician the flow is simple: pick a song, understand what matters tonight, rehearse it, save it safely, and share only what was intended. The technical split exists so those actions do not fight over authority or expose private media. + +BandScope bounded contexts remain: + +1. **Audio Ingestion** — user-selected source authority and intake intent. +2. **Resource Admission & Decode** — codec/MIME/path/resource/cancellation boundaries and admitted bytes. +3. **Signal/MIR Analysis** — decoded-audio evidence, model identity, uncertainty, reproducibility. +4. **Rehearsal Insight** — section × role decisions, cues, confidence and correction provenance. +5. **Active Player** — one authoritative transport state machine and fresh audible source/stem authority. +6. **Project Persistence** — versioned project format, atomic publication, migration, backup/recovery and portable export. +7. **Collaboration Handoff** — bounded share/export contracts, never a second project source of truth. +8. **Diagnostics/Support** — typed redacted evidence and support-bundle lifecycle. +9. **Distribution/Update** — signed identity, SBOM/provenance, model/dependency inventory, updater verification, rollout and rollback. +10. **UI/Interaction** — accessible localized rendering of domain state; no duplicated transport/project stores. + +Generic `utils`, `helpers`, `common`, `services`, `shared`, `core`, or `models` dumping that erases responsibility is a defect. Cross-context SQL, mutable sibling PR dependencies, source copying from canonical sibling owners, or parallel writable project/transport truth is prohibited. Released/versioned contracts and narrow anti-corruption layers are the integration mechanism. + +### 6.1 Ubiquitous language and invariants + +| Term | Meaning | Invariant / transaction boundary | +|---|---|---| +| `RehearsalProject` | durable work for one admitted rehearsal source | one published format version; a partial write never silently replaces last known-good truth | +| `LocalAudioPublicationIdentity` | path-free native receipt for app-owned admitted audio | project id, fixed artifact name, extension, exact byte count and SHA-256 remain validated; renderer does not mint it | +| `ProjectSourceReference` | durable Project Persistence projection of admitted source identity | evidence only, not a filesystem capability; restart must re-admit current bytes before runtime authority returns | +| `AnalysisEvidence` | versioned machine estimate | confidence/model/source provenance survives correction | +| `ManualOverride` | user-confirmed correction | original machine evidence remains auditable | +| `RehearsalTransport` | count-in/loop/playback/navigation state | one authoritative state machine; no competing mounted/local stores | +| `SelectedPlaybackSource` | durable `full_mix | vocals | bass | drums | other` intent | never itself grants audible authority; current media must be freshly admitted after reopen | +| `PlaybackAuthority` | revocable runtime authority over an admitted audible source | stale/replaced/missing media cannot retain authority merely because prior analysis or persistence succeeded | +| `ReleaseIdentity` | app/model/artifact/signature/checksum/provenance tuple | updater accepts only policy-valid signed compatible identity and preserves rollback target | + +Candidate domain events include `AudioSourceAdmitted`, `AnalysisCompleted`, `CueConfirmed`, `SectionBoundaryCorrected`, `LoopActivated`, `ProjectSnapshotPublished`, `ProjectRecovered`, `PlaybackSourceReadmitted`, `SupportBundlePrepared`, `UpdateStaged`, and `UpdateRollbackCompleted`. + +### 6.2 Context map + +```mermaid +flowchart LR + M[Musician / band member] + UI[UI / Interaction] + ING[Audio Ingestion] + DEC[Resource Admission & Decode] + MIR[Signal/MIR Analysis] + RI[Rehearsal Insight] + PLAYER[Active Player] + PROJ[Project Persistence] + HANDOFF[Collaboration Handoff] + DIAG[Diagnostics / Support] + DIST[Distribution / Update] + SK[Released Shared Contracts] + ACL[Codec / model / OS / accelerator ACLs] + + M --> UI + UI --> ING + ING --> DEC + DEC --> MIR + MIR --> RI + RI --> UI + UI --> PLAYER + PLAYER --> PROJ + RI --> PROJ + PROJ --> HANDOFF + UI --> DIAG + DIST --> UI + DEC --> ACL + MIR --> ACL + PROJ --> SK + HANDOFF --> SK +``` + +`context-graph-contracts` remains the contract-only shared kernel for canonical refs, authority/truth status, bitemporal/provenance Context Assertions, CloudEvents, schemas and conformance. `enterprise-architecture-core` remains the EA Decision Plane. BandScope does not copy rehearsal audio/analysis/user truth into sibling authoritative storage. + +## 7. Technical design contract (TRD) + +### 7.1 Production topology and ports + +Principal surfaces are: + +- `apps/desktop`: React/Vite UI inside Tauri; +- `apps/desktop/src-tauri`: native command/orchestration and platform boundary; +- `apps/desktop/core`: Rust-owned local authority/input-validation helpers where implemented; +- `packages/shared-types`: versioned cross-layer request/response/domain contracts; +- `services/analysis-engine`: Python orchestration/compatibility during Rust-first migration; +- `services/analysis-engine/rust`: Rust/PyO3 numerical kernels. + +Typed allowlisted Tauri IPC and bounded local process/stdin-stdout are the normal orchestration ports. Public HTTP is not ordinary local-analysis authority. Codec/model/platform/accelerator/update services remain behind owning-context ports. + +### 7.2 End-to-end rehearsal sequence + +```mermaid +sequenceDiagram + actor User + participant UI as UI/Interaction + participant Ingest as Audio Ingestion + participant Decode as Admission & Decode + participant MIR as Signal/MIR + participant Insight as Rehearsal Insight + participant Player as Active Player + participant Project as Project Persistence + User->>UI: choose authorized local audio + UI->>Ingest: admit source intent + Ingest->>Decode: validate path/MIME/codec/resource budget + Decode->>MIR: bounded decoded audio + MIR->>Insight: evidence + uncertainty + provenance + Insight-->>UI: section/role/cue decisions + User->>Player: play/seek/count-in/loop/rate/cue/source + Player->>Project: persist accepted intent/state + Project-->>UI: published snapshot or recoverable failure +``` + +Decode, analysis, persistence, and playback failures remain typed and bounded. Production never substitutes a synthetic analysis object or stale playback source as success. + +### 7.3 Project Persistence / Resource Admission truth + +Current Draft #970 has ordinarily adopted #866 rather than duplicating its audio-publication policy. Live PR state is the exact-head authority for both moving Drafts. + +#866 owns selected-local-audio copy/admission/publication. It stages selected bytes, synchronizes and publishes the app-owned `source.`, reopens the published object, verifies exact size + SHA-256 receipt equality, then creates a path-free `LocalAudioPublicationIdentity`. Native state retains that verified identity keyed by BandScope project id. + +#970 consumes that identity. Draft `projectFormatVersion: 3` stores `song`, `preferences.selectedPlaybackSource`, and optional path-free `sourceReference = projectId + artifactName + extension + fileSizeBytes + contentSha256`. Legacy/v1/v2 input is migrated deterministically and never invents missing source evidence. Renderer-authored path, artifact name, byte count, digest, or `sourceReference` is rejected; the renderer may return only an already-minted project selector and durable playback-source intent to native Save. + +On restart, production `load_project` resolves only an existing app-local aggregate, opens the fixed source through the canonical native opener, re-verifies exact bounded bytes, and restores native publication/bootstrap state only after that reverse admission succeeds. A persisted source reference is evidence, not authority. + +Before `start_analysis_job` queue admission, retained publication identity is revalidated again. The child process receives exact admitted byte count and SHA-256 through its bounded process contract. The analysis process copies the opened source into a private spooled snapshot, verifies exact size and SHA-256, and decodes that same snapshot. The earlier admitted-audio pathname replacement gap between verification and analysis decode is therefore closed for this Draft path. + +Mounted Open→Save previously dropped the reopened source selector and reset non-default `selectedPlaybackSource`. The current #970 lineage makes `App` retain the validated path-free project selector plus versioned playback intent and return them through native-authoritative Save. It still cannot mint source evidence. + +Residual persistence work includes global/startup recovery policy, autosave/backup rotation and Restore/Compare/Discard UX, broader power-loss/disk-full/interrupted-migration fault injection, application downgrade/rollback policy, and descriptor-bound protection against concurrent replacement of higher parent directories. + +### 7.4 Active Player authority + +Project Persistence and analysis authority do not imply audible authority. On reopen, persisted `selectedPlaybackSource` is intent only. #1160 must ordinarily adopt current #970/#866 ancestry, remove its private duplicate SHA-256 implementation in favor of the canonical desktop-core reader, re-admit current Full mix and current stem artifacts, and only then mint fresh `PlaybackAuthority`. If the preferred persisted stem no longer exists or fails admission, the product falls back to Full mix without preserving stale prior authority. + +The material UI must prove source selection, play/pause/seek/stop/loop/count-in/rate/cue navigation, source replacement, stale async/media events, persistence/reload, and exact accessible alternatives with actual admitted media. + +### 7.5 Signal/MIR model admission and distribution boundary + +#970's Draft compatibility path for Demucs local model loading is not release provenance. It rejects missing/non-regular/symlinked/empty/oversized/checksum-mismatched cache objects before resolution, materializes only the preflight descriptor size into a private temporary `LocalRepo`, rejects early EOF or any extra post-`fstat` byte, and resolves locally so mutation/deletion of the original cache pathname cannot change bytes for that load or reactivate `RemoteRepo`. + +The current analysis lock resolves `torch==2.12.1`. PyTorch releases from 2.6 changed `torch.load` to `weights_only=True` by default when a custom pickle module is not supplied, while native Demucs packages carry class/constructor metadata rather than only a plain tensor state dictionary. #970 therefore treats `pickle.UnpicklingError` from the admitted local `get_model` call as bounded model unavailability. It deliberately does not switch to `weights_only=False`, expose serialized class/global details, or re-enable a network fallback. This is compatibility/security behavior only; it does not prove the real checkpoint is runnable or scientifically accepted under the locked stack. + +The 128 MiB model ceiling and Demucs eight-hex filename checksum remain compatibility/integrity controls only. They are not exact release size, full digest/signature, provenance, or rights evidence. Native Demucs/PyTorch deserialization remains a trusted code-bearing boundary. + +Issue #1180 therefore owns an immutable commercially admissible model artifact: exact identity/version/size/full digest or signed manifest, provenance/NOTICE/SBOM inventory, supported-platform placement, local-only loading, explicit serialization/loader choice and removal condition, updater compatibility/rollback, and rights-cleared real-audio acceptance. #1181 separately owns the commercial-use/redistribution rights prerequisite for upstream pretrained weights; mirrors, conversions, renamed files, or loader flags do not create rights. + +### 7.6 Rust compute ownership + +Repository-owned DSP, mathematical, vector/matrix, ranking/data-science and performance/security hot paths are Rust-first. Python remains bounded orchestration/compatibility/fixture/reporting only where no practical Rust replacement exists and must have documented rationale/removal conditions. Deterministic CPU reference behavior comes first; configured CPU multithreading/MLX/CUDA/OpenCL paths require actual backend execution, parity and resource evidence. Hidden Python numerical fallback is not the target architecture. + +## 8. Persistence ERD and database discipline + +Current durable project authority is file/project-format based; BandScope does not currently require a separate organization-owned relational authoritative store. + +```mermaid +erDiagram + REHEARSAL_PROJECT ||--o{ SONG_SECTION : contains + SONG_SECTION ||--o{ REHEARSAL_ROLE : guides + REHEARSAL_PROJECT ||--o{ SCORE_ATTACHMENT : references + REHEARSAL_PROJECT ||--o{ ANALYSIS_EVIDENCE : records + ANALYSIS_EVIDENCE ||--o{ MANUAL_OVERRIDE : corrected_by + REHEARSAL_PROJECT ||--|| REHEARSAL_TRANSPORT : persists +``` + +If relational persistence is introduced, objects use specific multiword snake_case names, normalize to at least 3NF where relevant, and retain one authoritative write path. Any SQL migration must verify foreign keys, indexes, constraints, sequences, ORM/query mappings, UPSERT/idempotency semantics, hot-partition risk, lock duration, read/write separation, backward compatibility, rollback and recovery. Cross-service SQL remains prohibited. + +## 9. Real-audio scientific acceptance + +Synthetic arrays, generated/mock audio, mocked UI journeys, direct feature matrices, or source-text assertions may support unit tests but cannot prove product accuracy. + +Commercial scientific acceptance requires rights-cleared real audio through production intake → decode → analysis → UI/playback with exact fixture identity, annotation, integrity and license provenance. Metrics remain task-specific: chord/harmony uses a recognized chord metric such as benchmark-defined weighted chord recall; beat/timing uses recognized event metrics; separation uses SI-SDR plus task-appropriate perceptual/robustness evidence; range/pitch/transcription uses declared note/frame/event metrics; section/cue boundaries use tolerances tied to annotation uncertainty and rehearsal cost rather than an invented constant. + +Acceptance criteria are preregistered before tuning and report uncertainty across tracks. Candidate-vs-baseline comparisons disclose sample count, aggregation, confidence interval or another justified uncertainty method, exclusions, and missing-data handling. Configured accelerator lanes must actually execute and report parity/peak-resource evidence. + +## 10. Security and privacy baseline + +Local files, URLs, MIME/codec claims, decoder outputs, model artifacts, project files, updater manifests, subprocess output, and support exports are untrusted. + +Owning contexts fail closed on traversal/symlink/reparse substitution, oversized/decompression/resource exhaustion, stale descriptor/path races, unsafe subprocess authority, credential/secret propagation, and prompt-injection crossings where an LLM boundary exists. Valid GHAS/CodeQL/Semgrep/Strix/AppGuardrail findings are deduplicated by root cause and repaired in the canonical lane. Scanner/control-plane defects remain with their owning repository; BandScope does not blanket-mask findings or weaken gates. + +Ordinary logs/support bundles exclude raw audio/project payloads, credentials and absolute local paths. Authorization is purpose-bound and least-privilege with field minimization, retention and access/export audit where relevant. + +### Security Notes + +#### Attack surface + +Audio/model/project acquisition, filesystem lookup/publication/recovery, decoder/model loading, IPC/subprocess boundaries, playback media authority, diagnostics export, installer/updater and rollback. + +#### Trust boundary + +Audio Ingestion owns user source intent; Resource Admission owns admitted app-local bytes; Project Persistence stores only versioned path-free evidence; Signal/MIR consumes admitted snapshots; Active Player separately owns fresh audible authority; Distribution owns remotely acquired/shipped artifact provenance. No lower layer may treat a persisted string, renderer payload, previous analysis result, mutable sibling branch, or compatibility model cache as release authority. + +#### Mitigations + +Strict type/schema/size/path validation, regular/no-link or descriptor-bound acquisition where implemented, exact byte receipts, private immutable-for-use snapshots, no-shell subprocess invocation, local-only model resolution, bounded PyTorch incompatibility without unsafe pickle downgrade, redacted diagnostics, signed release/update manifests, exact model/dependency inventory, fail-closed stale-source handling, and ordinary protected-branch gates. + +#### Realistic threats + +A moved/replaced local source or model is consumed after validation; an interrupted save publishes candidate bytes without recoverable ordering; a persisted source preference is mistaken for current playback authority; a malformed/corrupt/oversized artifact reaches decoder/deserializer; an implicit network model fetch occurs; a legacy serialized model triggers a loader compatibility failure and an operator bypasses the safer loader policy; release rights are inferred from code licensing; a stale updater/model combination changes rehearsal output; logs expose private local state. + +#### Safe failure + +Invalid/stale/missing/incompatible authority is rejected with bounded buyer-facing diagnostics. The product does not manufacture synthetic analysis, reuse stale audible authority, silently downgrade to an unverified model/provider or unsafe loader mode, or weaken required checks to make a run pass. + +#### Test points + +Moved/replaced/truncated/growing audio and model files; symlink/reparse and linked-parent cases; exact-size/hash mismatch; disk-full/interrupted publication/recovery; process-restart source re-admission; stale preferred stem fallback; malformed IPC/project data; PyTorch weights-only/object-graph incompatibility; updater interruption/rollback; redacted support bundles; supported-platform real-audio execution. + +#### Remaining risk + +Higher-parent directory authority is not yet descriptor-bound against every concurrent replacement. Commercial model/dependency rights and release provenance remain unresolved. Active Player still needs fresh audible Full mix/stem authority on current #970 ancestry. Global autosave/recovery UX and broad fault injection remain incomplete. + +## 11. UI/UX evidence gate + +Figma is the reviewed interaction/visual specification, Storybook the executable component/state inventory, and the shipped Tauri application the final acceptance target. The canonical Figma identity must be rediscovered from current protected docs/source before a material UI merge rather than treated as a permanent remembered constant. + +Material UI work must verify actual pointer/touch/keyboard interaction, section/time-axis identity, playback cursor, persistence/reload, stale-response/media races, normal/loading/empty/error/permission/unsupported-codec/missing-stem states, responsive window sizes, visible focus, reduced motion, non-color-only status, screen-reader names/states, KO/EN/JA/ZH/VI/ES/DE/FR expansion, CJK/text expansion/font fallback, and exact-value/list/table alternatives for graph/timeline/waveform content. + +Current #970 preserves reopened project id and `selectedPlaybackSource` through mounted Open→Save, but that does not prove Active Player delivery. #1160 must still compose persisted intent with fresh native audible availability on the current Project Persistence/Resource Admission ancestry. Wider locale/accessibility/browser/screen-reader and rights-cleared desktop audible evidence remain open. + +Anti-Slop is a delivery filter rather than a replacement visual style: components, copy, cards, decoration and motion must exist for actual rehearsal tasks/information hierarchy, not template completion. Displayed controls must work; generic marketing copy, decorative fake interactions, unverifiable metrics, and repetitive AI-default visual treatments do not pass material UI acceptance. + +**UI Delivery Gate: FAIL** until the material rehearsal player has current-head browser/Tauri evidence for real admitted audio, persistence/reload, stale authority, responsive states, keyboard/touch/pointer/screen-reader parity and required locales. + +## 12. Quality and operability floor + +Repository-owned production Docstring/rustdoc, Test, and Edge Case Coverage targets are each 100%. Lower configured thresholds are gaps, not equivalent evidence. Denominator reduction, skip/xfail, source-text matching, generated-code relabeling, mocked production success, or shrinking performance samples cannot manufacture compliance. + +Production-path tests include supported sample rates/channels, short/long recordings, pickup before bar one, odd meter/tempo change where supported, silence near boundaries, unsupported codecs, moved/replaced files, cancellation, memory/CPU/disk bounds, corrupted project state, stale async/media responses, missing stems, device changes, keyboard/screen-reader operation, locale expansion, updater rollback and redacted support export. + +Applicable buyer-facing web/API paths target measured p95 ≤20 ms where that budget is meaningful. Measurements exclude unrealistic warm-cache-only claims and are profiled before optimization. JS bundle/heap/DOM/hydration/main-thread/GC and native/process cleanup remain part of operability review. + +## 13. Release gate + +A release may be created only from one exact integrated protected head where all applicable CI/security/SAST/dependency/coverage/documentation/real-audio/build/package gates, Windows signing, macOS signing/notarization, checksums, SBOM/provenance, reproducibility, independent review, project migration/recovery, accessibility/supportability, updater rollback, model/dependency rights and operability evidence are terminal-success on that same identity. + +Unsigned validation artifacts are not releases. Queued evidence, stale Figma states, mock-only audio journeys, predecessor check receipts, developer model caches, scientific-use-only pretrained weights, permissive legacy-deserialization flags, or package-name-only dependency substitutions cannot establish release readiness. + +Commercial blockers currently include #1129 (`libsndfile` LGPL runtime path) and #1181 (upstream pretrained Demucs weight rights); #1180 owns the resulting immutable commercially admissible model artifact contract. No immutable release beyond historical `v0.1.3` is claimed by current Draft work. + +## 14. Traceability + +Primary normative/research anchors include: + +- World Wide Web Consortium. (2023). *Web Content Accessibility Guidelines (WCAG) 2.2*. https://www.w3.org/TR/WCAG22/ +- National Institute of Standards and Technology. (2022). *Secure Software Development Framework (SSDF) Version 1.1 (NIST SP 800-218)*. https://csrc.nist.gov/pubs/sp/800/218/final +- National Institute of Standards and Technology. (2015). *Secure Hash Standard (SHS) (FIPS PUB 180-4)*. https://doi.org/10.6028/NIST.FIPS.180-4 +- Music Information Retrieval Evaluation eXchange. (n.d.). *MIREX*. https://www.music-ir.org/mirex/ +- Raffel, C., McFee, B., Humphrey, E. J., Salamon, J., Nieto, O., Liang, D., Ellis, D. P. W., & Raffel, C. C. (2014). mir_eval: A transparent implementation of common MIR metrics. *Proceedings of the 15th International Society for Music Information Retrieval Conference*, 367–372. +- Défossez, A., Usunier, N., Bottou, L., & Bach, F. (2021). Music source separation in the waveform domain. *Transactions of the International Society for Music Information Retrieval, 4*(1), 197–208. https://doi.org/10.5334/tismir.76 +- Rouard, S., Massa, F., & Défossez, A. (2023). Hybrid transformers for music source separation. *Proceedings of the IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP)*. https://doi.org/10.1109/ICASSP49357.2023.10097003 +- Gawarecki, M. (2024, November 4). BC-breaking change: `torch.load` is being flipped to use `weights_only=True` by default in the nightlies after #137602. *PyTorch Developer Mailing List*. https://dev-discuss.pytorch.org/t/bc-breaking-change-torch-load-is-being-flipped-to-use-weights-only-true-by-default-in-the-nightlies-after-137602/2573 + +Repository ADRs, PRD/TRD, architecture/context-map documents, security/threat-model material, test strategy, operability/recovery guidance, UI/Storybook inventory, doctoring traceability and release documentation must remain code-current. Active PRs, planned work and research results are never promoted into shipped truth before protected integration. diff --git a/scripts/checks/test_verify_docs.py b/scripts/checks/test_verify_docs.py new file mode 100644 index 000000000..d188f5dd5 --- /dev/null +++ b/scripts/checks/test_verify_docs.py @@ -0,0 +1,108 @@ +"""Regression tests for structured documentation verification.""" + +import importlib.util +from pathlib import Path +import unittest + +MODULE_PATH = Path(__file__).with_name("verify_docs.py") +SPEC = importlib.util.spec_from_file_location("verify_docs", MODULE_PATH) +if SPEC is None or SPEC.loader is None: + raise RuntimeError(f"Unable to load {MODULE_PATH}") +VERIFY_DOCS = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(VERIFY_DOCS) + +RECOVERY_TRANSITIONS = ( + "NoSource --> RecoveringWithoutSource: project recovery requested", + "Ready --> RecoveringWithSource: project recovery requested", + "RecoveryFailedWithoutSource --> NoSource: recovery failure acknowledged", + "RecoveryFailedWithSource --> Ready: recovery failure acknowledged / keep prior source", +) + + +class StateDiagramReferenceTests(unittest.TestCase): + """Keep recovery transitions inside the executable Mermaid state model.""" + + def test_rejects_transition_text_that_only_exists_in_prose(self) -> None: + """Prose copies must not satisfy state-diagram structural requirements.""" + prose_only = "\n".join(RECOVERY_TRANSITIONS) + + missing = VERIFY_DOCS.missing_state_diagram_references( + prose_only, + RECOVERY_TRANSITIONS, + ) + + self.assertEqual(missing, list(RECOVERY_TRANSITIONS)) + + def test_rejects_required_transition_that_only_exists_in_mermaid_comment(self) -> None: + """Commented-out transitions must not satisfy the executable diagram gate.""" + diagram = "\n".join( + ( + "```mermaid", + "stateDiagram-v2", + *(f" {transition}" for transition in RECOVERY_TRANSITIONS[:-1]), + f" %% {RECOVERY_TRANSITIONS[-1]}", + "```", + ) + ) + + missing = VERIFY_DOCS.missing_state_diagram_references( + diagram, + RECOVERY_TRANSITIONS, + ) + + self.assertEqual(missing, list(RECOVERY_TRANSITIONS)) + + def test_rejects_required_transition_embedded_in_another_statement(self) -> None: + """A required transition must be a complete statement, not label text.""" + diagram = "\n".join( + ( + "```mermaid", + "stateDiagram-v2", + *(f" {transition}" for transition in RECOVERY_TRANSITIONS[:-1]), + f" OtherState --> Ready: notes {RECOVERY_TRANSITIONS[-1]}", + "```", + ) + ) + + missing = VERIFY_DOCS.missing_state_diagram_references( + diagram, + RECOVERY_TRANSITIONS, + ) + + self.assertEqual(missing, list(RECOVERY_TRANSITIONS)) + + def test_ignores_note_text_with_colon_and_arrow(self) -> None: + """Mermaid notes containing arrow-like text must not crash transition parsing.""" + diagram = "\n".join( + ( + "stateDiagram-v2", + " note right of Ready: keep source --> after cancel", + *(f" {transition}" for transition in RECOVERY_TRANSITIONS), + ) + ) + + transitions = VERIFY_DOCS.mermaid_transition_statements(diagram) + + self.assertEqual(transitions, set(RECOVERY_TRANSITIONS)) + + def test_accepts_transitions_in_state_diagram(self) -> None: + """A Mermaid stateDiagram-v2 containing every transition satisfies the gate.""" + diagram = "\n".join( + ( + "```mermaid", + "stateDiagram-v2", + *(f" {transition}" for transition in RECOVERY_TRANSITIONS), + "```", + ) + ) + + missing = VERIFY_DOCS.missing_state_diagram_references( + diagram, + RECOVERY_TRANSITIONS, + ) + + self.assertEqual(missing, []) + + +if __name__ == "__main__": + unittest.main() diff --git a/scripts/checks/verify_docs.py b/scripts/checks/verify_docs.py index 850921591..46bf7b092 100644 --- a/scripts/checks/verify_docs.py +++ b/scripts/checks/verify_docs.py @@ -1,5 +1,6 @@ """Verify that required repository documentation files and references exist.""" +from collections.abc import Sequence from pathlib import Path REQUIRED_PATHS = [ @@ -17,6 +18,7 @@ Path("docs/architecture/overview.md"), Path("docs/i18n/i18n-policy.md"), Path("docs/release/release-policy.md"), + Path("docs/product-technical-gap-baseline.md"), Path(".github/CODEOWNERS"), Path(".github/PULL_REQUEST_TEMPLATE.md"), Path(".github/ISSUE_TEMPLATE/bug_report.yml"), @@ -60,6 +62,92 @@ ], } +REQUIRED_STATE_DIAGRAM_REFERENCES = { + Path("docs/product-technical-gap-baseline.md"): ( + "NoSource --> RecoveringWithoutSource: project recovery requested", + "Ready --> RecoveringWithSource: project recovery requested", + "RecoveryFailedWithoutSource --> NoSource: recovery failure acknowledged", + "RecoveryFailedWithSource --> Ready: recovery failure acknowledged / keep prior source", + ), +} + + +def mermaid_state_diagrams(content: str) -> list[str]: + """Return only closed Mermaid fences whose diagram type is stateDiagram-v2.""" + diagrams: list[str] = [] + lines = content.splitlines() + index = 0 + + while index < len(lines): + if lines[index].strip() != "```mermaid": + index += 1 + continue + + index += 1 + block: list[str] = [] + closed = False + while index < len(lines): + if lines[index].strip() == "```": + closed = True + break + block.append(lines[index]) + index += 1 + + if closed: + first_content_line = next( + (line.strip() for line in block if line.strip()), + "", + ) + if first_content_line == "stateDiagram-v2": + diagrams.append("\n".join(block)) + + index += 1 + + return diagrams + + +def mermaid_transition_statements(diagram: str) -> set[str]: + """Return normalized executable transition statements from one state diagram.""" + transitions: set[str] = set() + + for raw_line in diagram.splitlines(): + line = raw_line.strip() + if not line or line == "stateDiagram-v2" or line.startswith("%%"): + continue + if "%%" in line: + line = line.split("%%", maxsplit=1)[0].rstrip() + if ":" not in line: + continue + + transition_path, transition_label = line.split(":", maxsplit=1) + if "-->" not in transition_path: + continue + source_state, target_state = transition_path.split("-->", maxsplit=1) + source_state = " ".join(source_state.split()) + target_state = " ".join(target_state.split()) + transition_label = " ".join(transition_label.split()) + if not source_state or not target_state or not transition_label: + continue + + transitions.add(f"{source_state} --> {target_state}: {transition_label}") + + return transitions + + +def missing_state_diagram_references( + content: str, + required_texts: Sequence[str], +) -> list[str]: + """Require exact related transitions to coexist in one Mermaid state diagram.""" + diagrams = mermaid_state_diagrams(content) + required_transitions = set(required_texts) + if any( + required_transitions.issubset(mermaid_transition_statements(diagram)) + for diagram in diagrams + ): + return [] + return list(required_texts) + def main() -> int: """Return a failing exit code when required docs or references are missing.""" @@ -69,6 +157,7 @@ def main() -> int: for path in missing: print(f"- {path}") return 1 + broken_refs: list[str] = [] for path, required_texts in REQUIRED_REFERENCES.items(): content = path.read_text(encoding="utf-8") @@ -76,6 +165,15 @@ def main() -> int: if required_text not in content: broken_refs.append(f"{path} missing reference: {required_text}") + for path, required_texts in REQUIRED_STATE_DIAGRAM_REFERENCES.items(): + content = path.read_text(encoding="utf-8") + missing_transitions = missing_state_diagram_references(content, required_texts) + if missing_transitions: + broken_refs.append( + f"{path} missing required transitions from one Mermaid stateDiagram-v2: " + + "; ".join(missing_transitions) + ) + if broken_refs: print("Missing required doc references:") for item in broken_refs: diff --git a/scripts/harness/quickcheck.sh b/scripts/harness/quickcheck.sh index f2b87e4e8..185fe7aba 100755 --- a/scripts/harness/quickcheck.sh +++ b/scripts/harness/quickcheck.sh @@ -4,6 +4,7 @@ set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" cd "$REPO_ROOT" +python3 scripts/checks/test_verify_docs.py python3 scripts/checks/verify_docs.py python3 scripts/checks/verify_security_notes.py python3 scripts/checks/security_gates.py