Closes the SDD-120 §11 verification-engineer follow-up and refreshes the
traceability matrix to incorporate the full benchmark-infrastructure
chain landed in commits 3a7750a / 8e95972 / 75b04f0.
swe4-unit-verification-plan.md v0.9.14 → v0.9.15:
- SWE4-UV-058: bench_capture_alloc_count (SDD-120 §3; SRS-216 metric 1;
SRS-219 clause a zero-tolerance).
- SWE4-UV-059: bench_capture_callback_wall_clock (metric 2; SRS-219 b
+20% p95).
- SWE4-UV-060: bench_opus_encode_latency (metric 3; SRS-219 c +15% mean).
- SWE4-UV-061: bench_opus_decode_latency (metric 4; SRS-219 c +15% mean).
- SWE4-UV-062: bench_resampler_throughput (metric 5; SRS-219 d -10%
samples/sec).
All five status PENDING_BASELINE until the first manual
bench-baseline-update.yml dispatch establishes baselines.
traceability-matrix.md v0.9.9 → v0.9.10:
- 9 new chain rows binding SysRS-307..309 → SysDes-156..158 →
SRS-216..219 → SAD-088..091 → SDD-120 sections → code anchors →
SWE4-UV-058..062.
- 10 new code-anchor rows for the benchmark files (benches/{common,
realtime_capture,opus_codec,resampler}.rs + examples/{emit,compare}
_baseline.rs + Cargo.toml + bench-advisory.yml +
bench-baseline-update.yml + .gitignore).
- 5 §A markers reconciled to PENDING_BASELINE (the SWE.4 IDs are now
authored; what remains pending is the baseline measurement).
- DEC-032 (abiFilters reduction) status unchanged; exit criteria
pending.
- All 5 prior open issues from earlier wave audits confirmed closed.
Verdict: TRACEABILITY_OK (engineering chain closed end-to-end). Only
remaining gap: PENDING_BASELINE, gated on CI minutes return + manual
workflow_dispatch on bench-baseline-update.yml.
710 lines
45 KiB
Markdown
710 lines
45 KiB
Markdown
|
||
# Chanora SWE.4 Software Unit Verification Plan
|
||
|
||
**Document type:** Software Unit Verification Plan
|
||
**Process alignment:** ASPICE SWE.4 Software Unit Verification
|
||
**Version:** 0.9.14
|
||
**Status:** Baseline Candidate
|
||
**Language:** English
|
||
**Product:** Chanora
|
||
**Verification object:** Software units defined by SDD
|
||
**Direct source layer:** SDD only
|
||
|
||
**Repo path:** `docs/verification/swe4-unit-verification-plan.md` ---
|
||
|
||
## 1. Purpose
|
||
|
||
This document defines the software unit verification strategy for Chanora. It verifies that software units implement the Software Detailed Design.
|
||
|
||
This document is downstream of SDD and shall not bypass the document hierarchy.
|
||
|
||
```text
|
||
SysRS -> SysDes -> SRS -> SAD -> SDD -> SWE.4 Unit Verification
|
||
```
|
||
|
||
Direct source rule:
|
||
|
||
```text
|
||
SWE.4 unit verification items shall link directly to SDD only.
|
||
```
|
||
|
||
## 2. Verification Scope
|
||
|
||
In scope:
|
||
|
||
- Flutter unit tests
|
||
- Flutter widget-level unit verification where a widget is treated as a software unit
|
||
- Dart static analysis
|
||
- Dart code review
|
||
- Rust unit tests
|
||
- Rust static analysis
|
||
- Rust code review
|
||
- Unit-level regression verification
|
||
- Unit-level interface boundary tests
|
||
- Unit-level localization, Unicode, design-token, and diagnostics verification
|
||
|
||
Out of scope:
|
||
|
||
- Software integration verification across components; handled by SWE.5.
|
||
- Fully integrated software verification against SRS; handled by SWE.6.
|
||
- System integration verification against SysDes; handled by SYS.4.
|
||
|
||
## 3. Unit Verification Strategy
|
||
|
||
| Verification type | Applies to | Purpose |
|
||
|---|---|---|
|
||
| Static analysis | Dart, Rust | Detect structural, lint, safety, style, and maintainability issues |
|
||
| Code review | Dart, Rust, build scripts | Confirm design compliance and maintainability |
|
||
| Unit tests | Dart, Rust | Verify individual units against SDD behavior |
|
||
| Widget tests | Flutter widgets | Verify component rendering, semantics, and state behavior |
|
||
| Golden tests | Design-system components | Verify stable UI rendering where appropriate |
|
||
| Localization tests | Localization service and accessibility labels | Verify fallback, keys, and localized display strings |
|
||
| Unicode tests | Protocol/bridge/text-boundary units | Verify UTF-8 and multilingual content handling |
|
||
| Regression tests | Changed units | Confirm unchanged behavior remains valid after modifications |
|
||
|
||
## 4. Entry Criteria
|
||
|
||
| Criterion | Description |
|
||
|---|---|
|
||
| SDD baseline available | Unit design items and source SAD links are available. |
|
||
| Unit implementation available | The unit exists in source code or executable test double form. |
|
||
| Unit test environment available | Flutter and/or Rust test infrastructure is configured. |
|
||
| Verification measure defined | Test, review, or static analysis objective is defined. |
|
||
| Pass/fail criteria defined | Expected result is objective and reviewable. |
|
||
|
||
## 5. Exit Criteria
|
||
|
||
| Criterion | Description |
|
||
|---|---|
|
||
| Selected unit verification measures executed | Tests, reviews, and analyses required for the release scope are complete. |
|
||
| Results recorded | Verification results are stored in test reports or review records. |
|
||
| Nonconformances recorded | Failures are recorded for problem resolution. |
|
||
| Traceability complete | Each unit verification item traces to SDD and result evidence. |
|
||
| Regression scope complete | Changed units have selected regression measures executed. |
|
||
|
||
## 6. Unit Verification Measures
|
||
|
||
**SWE4-UV-001**: Verify `ChanoraApp` initialization order.
|
||
|
||
- Source SDD: SDD-001, SDD-045
|
||
- Verification method: Flutter unit/integration test
|
||
- Pass criteria: Theme, localization, platform services, routing, and adaptive shell initialize before feature rendering.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-002**: Verify `ChanoraThemeFactory` Material 3 theme creation.
|
||
|
||
- Source SDD: SDD-002, SDD-003
|
||
- Verification method: Dart unit test
|
||
- Pass criteria: Light and dark Material 3 ThemeData objects are created with valid ColorScheme and TextTheme values.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-003**: Verify `ChanoraSemanticColors` connection token behavior.
|
||
|
||
- Source SDD: SDD-004, SDD-006
|
||
- Verification method: Dart unit test
|
||
- Pass criteria: All connection semantic roles are present and do not require feature-screen hardcoding.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-004**: Verify voice semantic token behavior.
|
||
|
||
- Source SDD: SDD-005, SDD-006
|
||
- Verification method: Dart unit test
|
||
- Pass criteria: Speaking, muted, deafened, and push-to-talk active states are available through semantic tokens.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-005**: Verify feature widgets use theme accessors rather than hardcoded semantic values.
|
||
|
||
- Source SDD: SDD-010
|
||
- Verification method: Static inspection
|
||
- Pass criteria: Feature widgets do not construct product semantic token values directly.
|
||
- Evidence: Review record
|
||
|
||
**SWE4-UV-006**: Verify adaptive shell window classification.
|
||
|
||
- Source SDD: SDD-011, SDD-012
|
||
- Verification method: Dart unit test
|
||
- Pass criteria: Compact, medium, and expanded classes are selected deterministically.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-007**: Verify `CompactShell` layout behavior.
|
||
|
||
- Source SDD: SDD-013
|
||
- Verification method: Flutter widget test
|
||
- Pass criteria: Compact shell renders a single-column layout and mobile navigation entry points.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-008**: Verify `MediumShell` layout behavior.
|
||
|
||
- Source SDD: SDD-014
|
||
- Verification method: Flutter widget test
|
||
- Pass criteria: Medium shell renders side navigation or navigation rail behavior.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-009**: Verify `ExpandedShell` persistent pane behavior.
|
||
|
||
- Source SDD: SDD-015
|
||
- Verification method: Flutter widget test
|
||
- Pass criteria: Expanded shell renders persistent side pane and VoiceBar slot.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-010**: Verify connection status presentation uses non-color-only cues.
|
||
|
||
- Source SDD: SDD-016, SDD-022
|
||
- Verification method: Dart unit test, widget test
|
||
- Pass criteria: The presenter exposes label, icon, semantic label, and severity token.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-011**: Verify `ChanoraVoiceBar` exposed properties.
|
||
|
||
- Source SDD: SDD-017, SDD-018
|
||
- Verification method: Flutter widget test
|
||
- Pass criteria: Mute, deaf, push-to-talk, input meter, current channel, and latency properties render correctly.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-012**: Verify `ChanoraChannelTree` data and interaction behavior.
|
||
|
||
- Source SDD: SDD-019, SDD-020
|
||
- Verification method: Flutter widget test
|
||
- Pass criteria: Channel hierarchy, selected state, expansion state, join intent, and context-menu intent operate as designed.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-013**: Verify `ChanoraClientTile` state semantics.
|
||
|
||
- Source SDD: SDD-021
|
||
- Verification method: Widget test, accessibility test
|
||
- Pass criteria: Client status is available through text/icon/semantic cues and not color alone.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-014**: Verify localized semantic labels for icon-only buttons.
|
||
|
||
- Source SDD: SDD-024, SDD-031, SDD-032
|
||
- Verification method: Accessibility test, localization unit test
|
||
- Pass criteria: Icon-only controls expose localized semantic labels with fallback.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-015**: Verify keyboard focus traversal.
|
||
|
||
- Source SDD: SDD-025
|
||
- Verification method: Widget test
|
||
- Pass criteria: Primary interactive controls can be traversed in a logical order.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-016**: Verify text-scale resilience of critical controls.
|
||
|
||
- Source SDD: SDD-026
|
||
- Verification method: Accessibility widget test
|
||
- Pass criteria: Critical controls remain reachable under increased text scale.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-017**: Verify platform inset service unit behavior.
|
||
|
||
- Source SDD: SDD-027, SDD-030
|
||
- Verification method: Unit test with platform test doubles
|
||
- Pass criteria: Insets are normalized and exposed to the shell.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-018**: Verify back intent service behavior.
|
||
|
||
- Source SDD: SDD-028
|
||
- Verification method: Unit test with platform test doubles
|
||
- Pass criteria: Platform back events map to expected route-level intents.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-019**: Verify localization fallback.
|
||
|
||
- Source SDD: SDD-031, SDD-032, SDD-033
|
||
- Verification method: Unit test
|
||
- Pass criteria: Missing localized strings fall back deterministically.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-020**: Verify server-content pass-through.
|
||
|
||
- Source SDD: SDD-034
|
||
- Verification method: Unit test
|
||
- Pass criteria: Server-provided content is not translated by product localization.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-021**: Verify Unicode text boundary behavior.
|
||
|
||
- Source SDD: SDD-035, SDD-036, SDD-037
|
||
- Verification method: Unit test
|
||
- Pass criteria: Valid multilingual Unicode content is preserved; invalid external encodings are handled at boundaries.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-022**: Verify diagnostic Unicode preservation and redaction behavior.
|
||
|
||
- Source SDD: SDD-038, SDD-041, SDD-050, SDD-054
|
||
- Verification method: Unit test, security review
|
||
- Pass criteria: Secrets are redacted while multilingual content is preserved.
|
||
- Evidence: Test result, review record
|
||
|
||
**SWE4-UV-023**: Verify locale-aware formatting.
|
||
|
||
- Source SDD: SDD-040
|
||
- Verification method: Unit test
|
||
- Pass criteria: Dates, times, numbers, and timestamps format through localization utilities.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-024**: Verify traceability checker behavior.
|
||
|
||
- Source SDD: SDD-043, SDD-044, SDD-055, SDD-056, SDD-066, SDD-067
|
||
- Verification method: Unit test / script test
|
||
- Pass criteria: Invalid direct-layer references are detected.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-025**: Verify bridge DTO safety.
|
||
|
||
- Source SDD: SDD-046
|
||
- Verification method: Unit test, static inspection
|
||
- Pass criteria: Bridge DTOs do not expose internal Rust implementation types.
|
||
- Evidence: Test result, review record
|
||
|
||
**SWE4-UV-026**: Verify Rust core event mapping.
|
||
|
||
- Source SDD: SDD-047
|
||
- Verification method: Rust unit test
|
||
- Pass criteria: Core events map deterministically to view model deltas.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-027**: Verify voice view model separation from DSP.
|
||
|
||
- Source SDD: SDD-048
|
||
- Verification method: Code review, unit test
|
||
- Pass criteria: Voice UI receives status values and does not perform audio DSP.
|
||
- Evidence: Review record, test result
|
||
|
||
**SWE4-UV-028**: Verify storage facade isolation.
|
||
|
||
- Source SDD: SDD-049
|
||
- Verification method: Static inspection, unit test
|
||
- Pass criteria: Feature widgets do not directly call database APIs.
|
||
- Evidence: Review record, test result
|
||
|
||
**SWE4-UV-029**: Verify interface detail catalog completeness.
|
||
|
||
- Source SDD: SDD-059, SDD-060
|
||
- Verification method: Review
|
||
- Pass criteria: Unit-level interface entries include required details where applicable.
|
||
- Evidence: Review record
|
||
|
||
**SWE4-UV-030**: Verify unit construction and review records.
|
||
|
||
- Source SDD: SDD-064, SDD-065, SDD-068, SDD-069, SDD-070
|
||
- Verification method: Review
|
||
- Pass criteria: Unit construction, review, verification handoff, and registry records exist for release scope units.
|
||
- Evidence: Review record
|
||
|
||
## 7. Traceability Matrix
|
||
|
||
| SDD Range | SWE.4 Coverage |
|
||
|---|---|
|
||
| SDD-001 through SDD-010 | SWE4-UV-001 through SWE4-UV-005 |
|
||
| SDD-011 through SDD-018 | SWE4-UV-006 through SWE4-UV-011 |
|
||
| SDD-019 through SDD-026 | SWE4-UV-012 through SWE4-UV-016 |
|
||
| SDD-027 through SDD-037 | SWE4-UV-017 through SWE4-UV-021 |
|
||
| SDD-038 through SDD-050 | SWE4-UV-022 through SWE4-UV-028 |
|
||
| SDD-051 through SDD-070 | SWE4-UV-029 through SWE4-UV-030 |
|
||
|
||
## 8. Result Reporting
|
||
|
||
Unit verification results shall be summarized in a unit verification summary report including:
|
||
|
||
- verification scope
|
||
- selected verification measures
|
||
- skipped measures and rationale
|
||
- pass/fail result
|
||
- nonconformances
|
||
- regression scope
|
||
- residual risks
|
||
- release recommendation
|
||
|
||
## 9. Change History
|
||
|
||
| Version | Date | Description |
|
||
|---|---|---|
|
||
| 0.1.0 | 2026-05-14 | Initial SWE.4 unit verification plan derived from SDD v0.3. |
|
||
|
||
---
|
||
|
||
## 10. Platform Decision Unit Verification Addendum
|
||
|
||
**SWE4-UV-031**: Verify iOS and Android build configuration units.
|
||
|
||
- Source SDD: SDD-071, SDD-072, SDD-073
|
||
- Verification method: Static inspection, platform test
|
||
- Pass criteria: iOS minimum runtime, Apple SDK gate, Android minimum runtime, and Android target SDK configuration are inspectable and match release policy.
|
||
- Evidence: Test result, release inspection
|
||
|
||
**SWE4-UV-032**: Verify single active connection enforcement.
|
||
|
||
- Source SDD: SDD-074
|
||
- Verification method: Unit test
|
||
- Pass criteria: Attempting to create a second active MVP connection is rejected or routed through a controlled disconnect/switch policy.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-033**: Verify audio processing defaults and backend selection.
|
||
|
||
- Source SDD: SDD-075, SDD-076
|
||
- Verification method: Unit test, audio test
|
||
- Pass criteria: AEC, AGC, Noise Suppression, and High-Pass Filter default to enabled where supported and stable; backend selector prefers platform-native processing.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-034**: Verify local database, secret storage, bridge, and diagnostics privacy gate units.
|
||
|
||
- Source SDD: SDD-077, SDD-078, SDD-079, SDD-080
|
||
- Verification method: Unit test, security inspection
|
||
- Pass criteria: Non-secret storage, secret storage, typed bridge DTOs, and disabled automatic upload/crash behavior match detailed design.
|
||
- Evidence: Test result, security review
|
||
|
||
**SWE4-UV-035**: Verify `DesktopPttBackend` trait + `PttCapabilityLevel` enum + `FocusedPttBackend` units.
|
||
|
||
- Source SDD: SDD-081, SDD-082, SDD-087
|
||
- Verification method: Unit test
|
||
- Pass criteria: Trait surface compiles for every implementation; enum `as_str()` mapping is unambiguous; `FocusedPttBackend` reports `L0Focused` and forwards `set_ptt` events into `AudioTransmitGate` unchanged.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-036**: Verify Windows / macOS / Linux platform backend units in isolation.
|
||
|
||
- Source SDD: SDD-083, SDD-084, SDD-085, SDD-086
|
||
- Verification method: Unit test (with mocked OS surfaces), Platform Test (Windows / macOS / GNOME-Wayland reference hosts)
|
||
- Pass criteria: Each backend reports the expected `PttCapabilityLevel` for the current host configuration; the ladder falls through to `FocusedPttBackend` when its preferred OS API is unavailable.
|
||
- Evidence: Test result, platform-test trace
|
||
|
||
**SWE4-UV-037**: Verify `PttController` + `AudioTransmitGate` units.
|
||
|
||
- Source SDD: SDD-088, SDD-089
|
||
- Verification method: Unit test
|
||
- Pass criteria: `PttController::set_binding` rebinds the active backend without dropping `AudioTransmitGate`; `AudioTransmitGate::subscribe()` returns a `watch::Receiver` that delivers every transition the gate observes.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-038**: Verify `PttSanitizer` and `PttCapabilityBadge` units.
|
||
|
||
- Source SDD: SDD-090, SDD-091
|
||
- Verification method: Unit test, UI review
|
||
- Pass criteria: `PttSanitizer` drops records whose field names match the banned list (`key_code`, `scan_code`, `virtual_key`, `vk`, `keysym`, `keysym_string`, `key_sequence`); `PttCapabilityBadge` renders the correct label and explanation sheet for each `PttCapabilityLevel`.
|
||
- Evidence: Test result, UI screenshot
|
||
|
||
**SWE4-UV-039**: Verify `MissedKeyUpWatchdog` unit.
|
||
|
||
- Source SDD: SDD-092
|
||
- Verification method: Unit test (tokio time-paused)
|
||
- Pass criteria: After a simulated `false -> true -> (timeout elapsed)` sequence the watchdog calls `AudioTransmitGate::set(false)` exactly once and emits a sanitised diagnostic record naming only `capability_level` and `backend_id`.
|
||
- Evidence: Test result
|
||
|
||
| SDD Range | SWE.4 Coverage |
|
||
|---|---|
|
||
| SDD-071 through SDD-080 | SWE4-UV-031 through SWE4-UV-034 |
|
||
| SDD-081 through SDD-092 | SWE4-UV-035 through SWE4-UV-039 |
|
||
|
||
|
||
## Baseline Candidate 0.9.1 Update
|
||
|
||
| Version | Date | Description |
|
||
|---|---|---|
|
||
| 0.9.1 | 2026-05-14 | Updated baseline after product decision closure: Apple App Store SDK gate uses Xcode 26+ and iOS 26 / iPadOS 26 SDK+ since 2026-04-28, platform baselines and decision traceability propagated across the document set. |
|
||
|
||
|
||
## Baseline Candidate 0.9.2 Update
|
||
|
||
| Version | Date | Description |
|
||
|---|---|---|
|
||
| 0.9.2 | 2026-05-14 | Corrected Apple App Store Connect upload gate to 2026-04-28 and checked full-package naming, references, and coverage. |
|
||
|
||
|
||
## Baseline Candidate 0.9.3 Update
|
||
|
||
| Version | Date | Description |
|
||
|---|---|---|
|
||
| 0.9.3 | 2026-05-15 | Added desktop PTT unit-verification items SWE4-UV-035 through SWE4-UV-039: `DesktopPttBackend` trait + `PttCapabilityLevel`, platform backends, `PttController` + `AudioTransmitGate`, `PttSanitizer` + `PttCapabilityBadge`, `MissedKeyUpWatchdog`. |
|
||
|
||
|
||
## 11. Android P0 Unit Verification Addendum
|
||
|
||
**SWE4-UV-040**: Verify Android build configuration unit (`SDD-073` expanded).
|
||
|
||
- Source SDD: SDD-073
|
||
- Verification method: Gradle task assertion + static inspection of `android/app/build.gradle.kts`
|
||
- Pass criteria: `minSdk` literal equals `28` (DEC-004); `ndk.abiFilters` set equals `{arm64-v8a, armeabi-v7a, x86_64}` (per SDD-073 item 4 and SDD-118 item 3, `x86` 32-bit is explicitly out of scope and shall not be in the set); release `signingConfig` references the CI signing key reference (not debug); R8/ProGuard `minifyEnabled = true` on release; `bundle { abi.enableSplit = true }`; assemble target produces an AAB artifact at `app/build/outputs/bundle/release/app-release.aab`.
|
||
- Evidence: Gradle log + manifest dump
|
||
|
||
**SWE4-UV-041**: Verify `AndroidPermissionRequester` state machine (`SDD-106`).
|
||
|
||
- Source SDD: SDD-106
|
||
- Source SRS: SRS-209
|
||
- Verification method: Dart/Kotlin unit test with a permission-platform test double
|
||
- Pass criteria: State transitions are exhaustive for `{granted, denied, permanently_denied, revoked_mid_session}`; transitioning out of `granted` clamps `AudioTransmitGate::set(false)`; re-entering `granted` does NOT auto-transmit (requires explicit user gesture); permanently-denied surfaces a settings-deep-link intent rather than re-prompting.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-042**: Verify `BackIntentService` Android branches (`SDD-028` expanded).
|
||
|
||
- Source SDD: SDD-028
|
||
- Source SRS: SRS-163
|
||
- Verification method: Dart unit test with platform-channel test double for both `OnBackInvokedCallback` (API 33+) and `OnBackPressedDispatcher` (API ≤ 32) paths.
|
||
- Pass criteria: Modal-first rule — if a modal is open, back closes the modal and does not pop the route. PTT-active-ignore — while `transmit_active == true` the back event is consumed without effect. Route-pop ordering — otherwise the topmost non-modal route pops. The API 33+ branch registers a `OnBackInvokedCallback` at `PRIORITY_DEFAULT`; the pre-33 branch registers an `OnBackPressedCallback`. Switching API level in the test double switches the active branch deterministically.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-043**: Verify `AndroidJniBootstrap` library load and init ordering (`SDD-105`).
|
||
|
||
- Source SDD: SDD-105
|
||
- Verification method: Instrumented unit test on Android (or Robolectric where applicable)
|
||
- Pass criteria: `System.loadLibrary("chanora_bridge")` is invoked from the `Application` subclass `onCreate` (not from an Activity); `JNI_OnLoad` runs exactly once per process and captures the `JavaVM*`; bridge init occurs before any FFI call from Dart; double-init is a no-op.
|
||
- Evidence: Test result + logcat trace
|
||
|
||
**SWE4-UV-044**: Verify `AndroidVoiceForegroundService` lifecycle unit (`SDD-107`).
|
||
|
||
- Source SDD: SDD-107
|
||
- Source SRS: SRS-111
|
||
- Verification method: Kotlin unit test + Robolectric `ServiceController`
|
||
- Pass criteria: `startForeground` is called within 5 s of `onStartCommand` (API 26+ requirement); notification channel exists with `IMPORTANCE_LOW`; `foregroundServiceType` includes `microphone` on API 30+; service stops cleanly on disconnect intent and does not leak its wakelock; restart policy is `START_NOT_STICKY` (no auto-respawn after force-stop).
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-045**: Verify `AndroidAudioModeController` snapshot/restore + refcount (`SDD-108`).
|
||
|
||
- Source SDD: SDD-108
|
||
- Source SRS: SRS-208
|
||
- Source SysRS: SysRS-305
|
||
- Verification method: Kotlin unit test with `AudioManager` test double
|
||
- Pass criteria: First acquire snapshots prior `AudioManager.getMode()` and sets `MODE_IN_COMMUNICATION`; nested acquires increment refcount without re-snapshotting; matched release decrements; final release restores the snapshotted prior mode exactly once; when `AudioManager` is unavailable (e.g. injected null), controller logs a sanitized warning and degrades to no-op without throwing.
|
||
- Evidence: Test result
|
||
|
||
**SWE4-UV-046**: Verify `AndroidPttCapability` reports `L0Focused` and pins `FocusedPttBackend` (`SDD-110`).
|
||
|
||
- Source SDD: SDD-110
|
||
- Verification method: Rust + Dart unit test
|
||
- Pass criteria: On `target_os = "android"` the `DesktopPttBackend` factory returns `FocusedPttBackend` unconditionally (no ladder evaluation); `PttCapabilityBadge` renders the localized `L0Focused` label with the Android-specific explanation string; no Android branch attempts to bind global hotkeys.
|
||
- Evidence: Test result + UI screenshot
|
||
|
||
| SDD Range | SWE.4 Coverage |
|
||
|---|---|
|
||
| SDD-028 (expanded) | SWE4-UV-042 |
|
||
| SDD-073 (refreshed) | SWE4-UV-040 |
|
||
| SDD-105 | SWE4-UV-043 |
|
||
| SDD-106 | SWE4-UV-041 |
|
||
| SDD-107 | SWE4-UV-044 |
|
||
| SDD-108 | SWE4-UV-045 |
|
||
| SDD-110 | SWE4-UV-046 |
|
||
|
||
|
||
### Android voice audio backend unit-verification items (SDD-111..SDD-116 wave)
|
||
|
||
**SWE4-UV-047**: Verify `AndroidVoiceStreamConfig` builder records requested vs. achieved fields.
|
||
|
||
- Source SDD: SDD-112 (config struct), SDD-111 (trait surface)
|
||
- Source SRS: SRS-210, SRS-211, SRS-213, SRS-214
|
||
- Source SAD: SAD-077, SAD-081
|
||
- Verification method: Rust unit test with a fake Oboe builder return path (no device)
|
||
- Pass criteria: Given a `MobileVoiceStreamConfig` requesting `PERFORMANCE_MODE_LOW_LATENCY`, input preset `VoiceCommunication`, output usage `VoiceCommunication`, content type `Speech`, and sharing mode `Exclusive`, the resulting `AndroidVoiceStreamConfig` records the requested values verbatim AND exposes `achieved_*` accessors populated from the fake builder's grant values. Mismatch between requested and achieved is observable via the accessors with no panics. Both input and output stream configs are independently recorded.
|
||
- Evidence: Rust unit test result
|
||
- SDD-116 matrix row satisfied: none directly (unit-level; matrix consumes the accessors per-device)
|
||
|
||
**SWE4-UV-048**: Verify input preset fallback ladder is observable at each step.
|
||
|
||
- Source SDD: SDD-111 (trait surface, open() error pathway), SDD-112 (preset field)
|
||
- Source SRS: SRS-211
|
||
- Source SAD: SAD-077
|
||
- Verification method: Rust unit test with a scripted Oboe builder mock that returns `ErrorIllegalArgument` for successive presets
|
||
- Pass criteria: With the mock denying `VoiceCommunication`, `open()` retries with `VoicePerformance`; with the mock denying both, `open()` retries with `Generic` (`Unprocessed`/default). Each retry is recorded in a structured field (e.g. `attempted_presets: Vec<InputPreset>`) and the final `achieved_input_preset()` returns the preset that was granted. If all presets fail, `open()` returns `BackendError::InputPresetUnavailable` (or the SDD-111 equivalent). No silent fallback.
|
||
- Evidence: Rust unit test result
|
||
- SDD-116 matrix row satisfied: none directly (matrix records `achieved_input_preset` per device)
|
||
|
||
**SWE4-UV-049**: Verify sharing-mode fallback Exclusive→Shared is observable.
|
||
|
||
- Source SDD: SDD-111, SDD-112 (sharing mode field)
|
||
- Source SRS: SRS-214
|
||
- Source SAD: SAD-077
|
||
- Verification method: Rust unit test with a fake Oboe builder return path
|
||
- Pass criteria: When the fake builder accepts `SharingMode::Exclusive`, `achieved_sharing_mode()` returns `Exclusive` and no retry occurs. When the fake builder rejects `Exclusive` (returns the documented Oboe error path for exclusive denial), the unit retries with `Shared`, and `achieved_sharing_mode()` returns `Shared`. The original request (`Exclusive`) is still recorded for diagnostics.
|
||
- Evidence: Rust unit test result
|
||
- SDD-116 matrix row satisfied: none directly (matrix records `achieved_sharing_mode` per device)
|
||
|
||
**SWE4-UV-050**: Verify hardware effects per-effect success/failure logic with software-AEC fallback.
|
||
|
||
- Source SDD: SDD-113 (per-effect construction + software fallback signal)
|
||
- Source SRS: SRS-212
|
||
- Source SAD: SAD-077, SAD-081
|
||
- Verification method: Rust unit test with a mocked JNI surface (`new_object`-style indirection) representing `AcousticEchoCanceler.create`, `NoiseSuppressor.create`, `AutomaticGainControl.create`
|
||
- Pass criteria: For each of AEC, NS, AGC: (a) success path — mock returns a non-null `GlobalRef`, effect is recorded as engaged, `setEnabled(true)` is invoked once; (b) failure path — mock returns null OR throws, the unit records the per-effect failure, does NOT abort the other two, and signals the engine to engage the software equivalent (per SDD-113 item 5 — for AEC failure the engine's software AEC must be flagged on). Order of effect construction does not affect outcome (no cross-effect coupling). `release()` is called on every engaged `GlobalRef` exactly once when the unit is torn down.
|
||
- Evidence: Rust unit test result
|
||
- SDD-116 matrix row satisfied: per-device AEC/NS/AGC availability column
|
||
|
||
**SWE4-UV-051**: Verify performance-mode achieved recording feeds SRS-210 latency tier classification.
|
||
|
||
- Source SDD: SDD-111 (`achieved_performance_mode`), SDD-112 (mode field)
|
||
- Source SRS: SRS-210
|
||
- Source SAD: SAD-077
|
||
- Verification method: Rust unit test
|
||
- Pass criteria: When the fake builder grants `PERFORMANCE_MODE_LOW_LATENCY`, `achieved_performance_mode()` returns `LowLatency` and the SRS-210 tier classifier (the unit-level pure function that maps achieved mode → latency target) returns the 150 ms tier. When the fake builder grants `PERFORMANCE_MODE_NONE` or `POWER_SAVING`, the classifier returns the 250 ms tier. The classifier is a pure function reachable from the engine without a device.
|
||
- Evidence: Rust unit test result
|
||
- SDD-116 matrix row satisfied: per-device `achieved_performance_mode` column
|
||
|
||
**SWE4-UV-052**: Verify output stream usage and content type are set correctly.
|
||
|
||
- Source SDD: SDD-112 (output config fields)
|
||
- Source SRS: SRS-213
|
||
- Source SAD: SAD-077
|
||
- Verification method: Rust unit test inspecting the builder calls captured by a mock Oboe builder
|
||
- Pass criteria: The output stream-construction path invokes `setUsage(VoiceCommunication)` and `setContentType(Speech)` exactly once on the builder before `openStream`. No other usage / content-type combination is reachable from the production path (the test asserts there is no code path that constructs the output stream with `Media` / `Music` defaults). `achieved_output_usage()` returns `VoiceCommunication` and `achieved_output_content_type()` returns `Speech` on a successful open.
|
||
- Evidence: Rust unit test result
|
||
- SDD-116 matrix row satisfied: per-device `achieved_output_usage` / `achieved_output_content_type` column
|
||
|
||
| SDD Range | SWE.4 Coverage |
|
||
|---|---|
|
||
| SDD-111 | SWE4-UV-047, SWE4-UV-048, SWE4-UV-049, SWE4-UV-051 |
|
||
| SDD-112 | SWE4-UV-047, SWE4-UV-048, SWE4-UV-049, SWE4-UV-051, SWE4-UV-052 |
|
||
| SDD-113 | SWE4-UV-050 |
|
||
| SDD-115 | (lifecycle sequencing — see SWE.5 integration items) |
|
||
| SDD-116 | (device matrix — see SWE.6 + android-p0-acceptance TC-14..TC-18) |
|
||
|
||
|
||
## Baseline Candidate 0.9.4 Update
|
||
|
||
| Version | Date | Description |
|
||
|---|---|---|
|
||
| 0.9.4 | 2026-05-18 | Added Android P0 unit-verification items SWE4-UV-040 through SWE4-UV-046 covering SDD-028 (expanded back-intent branches), SDD-073 (refreshed build config + AAB), SDD-105 (JNI bootstrap), SDD-106 (permission state machine + transmit clamp), SDD-107 (foreground service lifecycle), SDD-108 (audio mode controller refcount + restore), SDD-110 (PTT capability pin). |
|
||
| 0.9.5 | 2026-05-18 | Added Android voice audio backend unit-verification items SWE4-UV-047 through SWE4-UV-052 covering SDD-111 (trait surface), SDD-112 (config requested vs achieved), SDD-113 (per-effect hardware engagement + software fallback) and feeding SRS-210/211/213/214 unit-level classification. |
|
||
| 0.9.14 | 2026-05-18 | Wave 3 reviewer follow-up: allocated real SWE.4 IDs for two test sets that had been cited under provisional `SWE4-UV-NNN` placeholders. SWE4-UV-053..055 anchor the three `TransmitModeSelector` permission-state clamp tests in `crates/chanora_audio/src/transmit_selector.rs` (commit 635d160 was cited under the "SWE4-UV-026 family" without real anchors). SWE4-UV-056..057 anchor the two missing `DiagnosticExport::with_android_audio` rendering tests in `crates/chanora_diagnostics/src/lib.rs` (commit aea50a1 introduced the field/builder/`to_text` branch but the unit-test pair was queued for the commit-8 amend). Closes the Wave 3 traceability gap; downstream test cites in commits 4 and 8 are amended to reference these IDs. |
|
||
| 0.9.15 | 2026-05-18 | Closed SDD-120 §11 verification-engineer follow-up: allocated SWE4-UV-058 through SWE4-UV-062 anchoring the five realtime-audio bench functions landed in commit 3a7750a (`bench_capture_alloc_count` and `bench_capture_callback_wall_clock` in `crates/chanora_audio/benches/realtime_capture.rs`; `bench_opus_encode_latency` and `bench_opus_decode_latency` in `crates/chanora_audio/benches/opus_codec.rs`; `bench_resampler_throughput` in `crates/chanora_audio/benches/resampler.rs`) and feeding the SRS-216 metric families under the SRS-219 per-metric tolerance windows. Status PENDING_BASELINE: pass/fail evaluation cannot proceed until the first `bench-baseline-update.yml` `workflow_dispatch` invocation lands the SAD-089 baseline JSON; once landed, the SDD-120 §6 `bench-advisory.yml` workflow plus `examples/compare_baseline` perform automated 🔴/🟡/🟢 evaluation against the merge-base baseline snapshot. Strict-layered sourcing preserved (`SWE.4 -> SDD/SRS` only); no SDD, SRS, SAD, SysDes, or SysRS edits performed. |
|
||
|
||
## 12. Android Permission Clamp + Diagnostics Android-Audio Unit Verification Addendum (Wave 3 — v0.9.14)
|
||
|
||
**Background.** Wave 3 reviewer audit flagged two newly-landed test groups whose source comments cited verification IDs as `SWE4-UV-NNN` placeholders rather than real allocated anchors:
|
||
|
||
1. Three `TransmitModeSelector` permission-state tests at `crates/chanora_audio/src/transmit_selector.rs:343-435` (introduced by commit 635d160). The reviewer noted at `transmit_selector.rs:343` that these tests cite "SWE4-UV-026 family" without real IDs.
|
||
2. Two missing unit tests for the new `chanora_diagnostics` Android-audio surface (`android_audio: Option<String>` field, `with_android_audio` builder, `[audio.android]` `to_text` branch) introduced by commit aea50a1; queued for the commit-8 amend.
|
||
|
||
This addendum allocates the five required anchors. SWE4-UV-052 was the prior high-water mark; SWE4-UV-053..057 are the next free contiguous range.
|
||
|
||
**SWE4-UV-053**: Verify `TransmitModeSelector` clamps transmit to `false` when `permission_state == Denied` (or `PermanentlyDenied`/`Unknown`) regardless of PTT, channel, or transmit-mode state.
|
||
|
||
- Source SDD: SDD-106 §6
|
||
- Source SRS: SRS-209 (fail-safe listen-only default)
|
||
- Verification method: Rust unit test
|
||
- Test code path: `crates/chanora_audio/src/transmit_selector.rs::tests::permission_state_denied_clamps_transmit_to_false` (lines 348-384)
|
||
- Pass criteria: With `TransmitMode::Ptt`, `in_channel = true`, `ptt_held = true` and the default `Granted` permission state the gate evaluates `true`. Publishing `PermissionGate::Denied` flips the gate to `false`. `PermanentlyDenied` and `Unknown` likewise clamp `false`. The clamp wins over `TransmitMode::Continuous`.
|
||
- Evidence: `cargo test -p chanora_audio` result
|
||
- Notes: Establishes the fail-safe semantics: cold-launch `Unknown` is listen-only per SRS-209.
|
||
|
||
**SWE4-UV-054**: Verify `TransmitModeSelector` releases the permission clamp on transition back to `Granted` and resumes normal PTT-driven evaluation.
|
||
|
||
- Source SDD: SDD-106 §6
|
||
- Source SRS: SRS-209
|
||
- Verification method: Rust unit test
|
||
- Test code path: `crates/chanora_audio/src/transmit_selector.rs::tests::permission_state_granted_releases_clamp` (lines 389-409)
|
||
- Pass criteria: After `Denied` clamps the gate to `false`, transitioning to `PermissionGate::Granted` (with PTT held + in channel) restores the gate to `true` on the next state tick. Releasing the PTT key then drops the gate per normal PTT semantics — the clamp is no longer in effect.
|
||
- Evidence: `cargo test -p chanora_audio` result
|
||
- Notes: Pairs with SWE4-UV-053; together they cover the clamp on/off edges.
|
||
|
||
**SWE4-UV-055**: Verify `TransmitModeSelector` ignores `PermissionState` events for non-`RECORD_AUDIO` permissions (contract: bridge filters before reaching the selector).
|
||
|
||
- Source SDD: SDD-106 §5
|
||
- Verification method: Rust unit test (contract pin)
|
||
- Test code path: `crates/chanora_audio/src/transmit_selector.rs::tests::permission_state_for_other_permission_does_not_clamp` (lines 418-435)
|
||
- Pass criteria: The selector exposes no setter for non-`RECORD_AUDIO` permissions. With `TransmitMode::Continuous` + `in_channel = true` and no call to `set_permission_state`, the selector remains in its `Granted` default and the gate evaluates `true`. Demonstrates the contract that unrelated permission events (e.g. `POST_NOTIFICATIONS`) cannot reach this code path.
|
||
- Evidence: `cargo test -p chanora_audio` result
|
||
- Notes: This is a negative/contract test; the JNI bridge is responsible for filtering by permission name before invoking `set_permission_state`.
|
||
|
||
**SWE4-UV-056**: Verify `DiagnosticExport::with_android_audio(Some(yaml))` renders the `[audio.android]` section between `[metadata]` and `[recent logs]` in `to_text()`.
|
||
|
||
- Source SDD: SDD-116 item 3 (diagnostics matrix surface), SDD-112 item 10 / SDD-113 item 7 (producing crate)
|
||
- Verification method: Rust unit test
|
||
- Test code path: `crates/chanora_diagnostics/src/lib.rs::tests::android_audio_renders_between_metadata_and_logs` (to be added by commit-8 amend)
|
||
- Pass criteria: Building a `DiagnosticExport::from_sink(...)` and chaining `.with_android_audio(Some("perf: low_latency\n".into()))` produces a `to_text()` output where the substring `[audio.android]` appears (a) after the `[metadata]` header, (b) before the `[recent logs]` header, and (c) is immediately followed by the supplied YAML fragment verbatim. The YAML fragment is not re-redacted by the diagnostics bundle (SDD-090 places sanitisation in the producing crate).
|
||
- Evidence: `cargo test -p chanora_diagnostics` result
|
||
- Notes: Section ordering is part of the SDD-116 matrix contract; downstream tooling parses by header.
|
||
|
||
**SWE4-UV-057**: Verify `DiagnosticExport` with default `android_audio = None` omits the `[audio.android]` header entirely (negative test).
|
||
|
||
- Source SDD: SDD-116 item 3 (negative case — non-Android or pre-session)
|
||
- Verification method: Rust unit test
|
||
- Test code path: `crates/chanora_diagnostics/src/lib.rs::tests::android_audio_absent_omits_section` (to be added by commit-8 amend)
|
||
- Pass criteria: A `DiagnosticExport::from_sink(...)` constructed without `.with_android_audio(...)` (i.e. `android_audio == None`) produces a `to_text()` output that does **not** contain the substring `[audio.android]`. The `[metadata]` and `[recent logs]` sections remain present in order. Calling `.with_android_audio(None)` explicitly is equivalent (idempotent omission).
|
||
- Evidence: `cargo test -p chanora_diagnostics` result
|
||
- Notes: Pairs with SWE4-UV-056; together they cover the conditional-render branch in `DiagnosticExport::to_text`.
|
||
|
||
| SDD Range | SWE.4 Coverage |
|
||
|---|---|
|
||
| SDD-106 §5 | SWE4-UV-055 |
|
||
| SDD-106 §6 | SWE4-UV-053, SWE4-UV-054 |
|
||
| SDD-116 item 3 | SWE4-UV-056, SWE4-UV-057 |
|
||
|
||
## 13. Realtime-Audio Benchmark-Harness Unit Verification Addendum (SDD-120 §11 closure — v0.9.15)
|
||
|
||
**Background.** SDD-120 (`RealtimeAudioBenchmarkHarnessAndAdvisoryCI`, v0.9.16) §11 explicitly defers the SWE.4 allocation for the five bench functions it specifies in §3, noting: "Suggested SWE.4 forward allocation: SWE4-UV-058 through SWE4-UV-062 (verification-engineer follow-up; not authored by this SDD unit)." Commit 3a7750a landed the implementation across three bench files plus two `examples/` post-processor binaries. This addendum closes the §11 follow-up by authoring the five anchors. SWE4-UV-057 was the prior high-water mark; SWE4-UV-058..062 are the next free contiguous range.
|
||
|
||
**Status conventions.** All five items are marked **PENDING_BASELINE**: pass/fail evaluation requires a committed SAD-089 baseline JSON for the active host triple (`x86_64-unknown-linux-gnu`), which is produced only by the SDD-120 §7 `bench-baseline-update.yml` `workflow_dispatch` workflow. Until that workflow has been dispatched at least once and its PR merged, the SDD-120 §6 `bench-advisory.yml` short-circuits on missing baseline (per SRS-218 clause 4 always-success) and these verification items cannot return 🟢/🟡/🔴. Automated comparison thereafter is performed by `crates/chanora_audio/examples/compare_baseline.rs` (invoked via `cargo run --example compare_baseline`) against the merge-base baseline per SRS-219.
|
||
|
||
**SWE4-UV-058**: Verify the realtime capture path performs zero heap allocations per callback after the warmup window.
|
||
|
||
- Source SDD: SDD-120 §3 (bench function `bench_capture_alloc_count` with 100-callback warmup before the dhat measurement window); SDD-120 §8 (zero-tolerance metric collapses to 🔴/🟢 only — no 🟡 band).
|
||
- Source SRS: SRS-216 metric 1 (heap allocation count per realtime callback after warmup); SRS-219 clause a (zero tolerance — "any non-zero allocation count on a PR is flagged 🔴").
|
||
- Verification method: Criterion bench with dhat global allocator. Invocation: `cargo bench --bench realtime_capture -- bench_capture_alloc_count`.
|
||
- Test code path: `crates/chanora_audio/benches/realtime_capture.rs::bench_capture_alloc_count` (line 27).
|
||
- Pass criteria: After a 100-call `CaptureState::ingest` pre-warm (per SDD-120 §3), the dhat `HeapStats.total_blocks` delta across the subsequent 1000 `CaptureState::ingest` calls **SHALL equal zero**. Any non-zero count is a 🔴 regression per SRS-219 clause a (zero tolerance).
|
||
- Acceptance evidence: dhat global-allocator `HeapStats.total_blocks` delta == 0 captured by the bench; criterion `estimates.json` projected into the SRS-217 baseline schema by `examples/emit_baseline`; advisory marker rendered by `examples/compare_baseline` against the merge-base baseline.
|
||
- Cross-trace: SAD-088 (benchmark-instrumentation seam), SDD-094 (audio-engine lifecycle as the bench-seam container).
|
||
- Status: **PENDING_BASELINE** (zero-tolerance metric — first baseline run establishes the binary 🟢/🔴 evaluation; subsequent runs gate on any non-zero allocation regardless of baseline value).
|
||
|
||
**SWE4-UV-059**: Verify the realtime capture callback wall-clock stays within the SRS-219 p95 tolerance.
|
||
|
||
- Source SDD: SDD-120 §3 (bench function `bench_capture_callback_wall_clock` with criterion default warmup; measurement reports p50/p95/p99 as a fraction of the cpal stream period).
|
||
- Source SRS: SRS-216 metric 2 (per-callback wall-clock at p50/p95/p99 as a fraction of cpal stream period); SRS-219 clause b ("per-callback wall-clock duration at p95 — tolerance is +20% relative to the baseline (p50 and p99 are advisory data only and do not drive the 🔴 marker)").
|
||
- Verification method: Criterion timing bench. Invocation: `cargo bench --bench realtime_capture -- bench_capture_callback_wall_clock`.
|
||
- Test code path: `crates/chanora_audio/benches/realtime_capture.rs::bench_capture_callback_wall_clock` (line 95).
|
||
- Pass criteria: p95 wall-clock per callback **SHALL stay within +20% of the baseline-at-merge-base** per SRS-219 clause b. p50 and p99 are reported but **advisory only** (no tolerance gate; cannot drive 🔴). Automated 🟢/🟡/🔴 evaluation by `examples/compare_baseline` per SDD-120 §8 (🔴 if `delta_pct > 20%`, 🟡 if `10% < delta_pct ≤ 20%`, 🟢 otherwise).
|
||
- Acceptance evidence: criterion p95 estimate from `target/criterion/.../estimates.json` projected through `examples/emit_baseline`; advisory marker rendered by `examples/compare_baseline`.
|
||
- Cross-trace: SAD-088, SDD-094.
|
||
- Status: **PENDING_BASELINE**.
|
||
|
||
**SWE4-UV-060**: Verify Opus encode latency on a 960-sample / 20 ms frame stays within the SRS-219 mean tolerance.
|
||
|
||
- Source SDD: SDD-120 §3 (bench function `bench_opus_encode_latency` exercising `audiopus::coder::Encoder::encode_float` **directly**, not through `tsclientlib::AudioHandler`, to isolate encode latency from higher-layer mix/jitter handling).
|
||
- Source SRS: SRS-216 metric 3 (Opus encode latency on 960-sample/20 ms frame); SRS-219 clause c ("Opus encode latency on a 960-sample / 20 ms frame — tolerance is +15% relative to the baseline on the mean").
|
||
- Verification method: Criterion timing bench. Invocation: `cargo bench --bench opus_codec -- bench_opus_encode_latency`.
|
||
- Test code path: `crates/chanora_audio/benches/opus_codec.rs::bench_opus_encode_latency` (line 21).
|
||
- Pass criteria: `encoder.encode_float()` mean latency on a 960-sample (20 ms @ 48 kHz mono) deterministic-sine frame **SHALL stay within +15% of the baseline-at-merge-base** per SRS-219 clause c. Automated 🟢/🟡/🔴 evaluation by `examples/compare_baseline` per SDD-120 §8 (🔴 if `delta_pct > 15%`, 🟡 if `7.5% < delta_pct ≤ 15%`, 🟢 otherwise).
|
||
- Acceptance evidence: criterion mean estimate from `target/criterion/.../estimates.json` projected through `examples/emit_baseline`; advisory marker rendered by `examples/compare_baseline`.
|
||
- Cross-trace: SAD-088, SDD-094.
|
||
- Status: **PENDING_BASELINE**.
|
||
|
||
**SWE4-UV-061**: Verify Opus decode latency on a 20 ms Opus frame stays within the SRS-219 mean tolerance.
|
||
|
||
- Source SDD: SDD-120 §3 (bench function `bench_opus_decode_latency` exercising `audiopus::coder::Decoder::decode_float` **directly**, not `tsclientlib::AudioHandler::fill_buffer`; SDD-120 §3 pinned this explicitly because the `AudioHandler` path conflates Opus decode with jitter-buffer dequeue and PCM mix).
|
||
- Source SRS: SRS-216 metric 4 (Opus decode latency on 960-sample/20 ms frame); SRS-219 clause c ("Opus decode latency on a 960-sample / 20 ms frame — tolerance is +15% relative to the baseline on the mean").
|
||
- Verification method: Criterion timing bench. Invocation: `cargo bench --bench opus_codec -- bench_opus_decode_latency`.
|
||
- Test code path: `crates/chanora_audio/benches/opus_codec.rs::bench_opus_decode_latency` (line 37).
|
||
- Pass criteria: `decoder.decode_float()` mean latency on a single 20 ms (960-sample @ 48 kHz mono) Opus-encoded frame **SHALL stay within +15% of the baseline-at-merge-base** per SRS-219 clause c. Automated 🟢/🟡/🔴 evaluation by `examples/compare_baseline` per SDD-120 §8 (🔴 if `delta_pct > 15%`, 🟡 if `7.5% < delta_pct ≤ 15%`, 🟢 otherwise).
|
||
- Acceptance evidence: criterion mean estimate from `target/criterion/.../estimates.json` projected through `examples/emit_baseline`; advisory marker rendered by `examples/compare_baseline`.
|
||
- Cross-trace: SAD-088, SDD-094.
|
||
- Status: **PENDING_BASELINE**.
|
||
|
||
**SWE4-UV-062**: Verify resampler throughput on the three canonical rate pairs stays within the SRS-219 samples-per-second tolerance.
|
||
|
||
- Source SDD: SDD-120 §3 (bench function `bench_resampler_throughput` structured as a criterion `BenchmarkGroup` with three sub-benches: 44.1 kHz → 48 kHz, 16 kHz → 48 kHz, and 48 kHz → 48 kHz passthrough).
|
||
- Source SRS: SRS-216 metric 5 (resampler throughput on canonical rate pairs); SRS-219 clause d ("resampler throughput on the canonical rate pairs — tolerance is −10% relative to the baseline on samples-per-second (i.e. a throughput drop greater than 10% is flagged 🔴)").
|
||
- Verification method: Criterion throughput bench. Invocation: `cargo bench --bench resampler -- bench_resampler_throughput`.
|
||
- Test code path: `crates/chanora_audio/benches/resampler.rs::bench_resampler_throughput` (line 17).
|
||
- Pass criteria: Each of the three sub-benches (44.1→48, 16→48, 48→48-passthrough) samples-per-second throughput **SHALL stay no worse than −10% of the baseline-at-merge-base** per SRS-219 clause d. A throughput drop greater than 10% on any of the three sub-benches is a 🔴 regression. Automated 🟢/🟡/🔴 evaluation by `examples/compare_baseline` per SDD-120 §8 (🔴 if `delta_pct < −10%`, 🟡 if `−10% ≤ delta_pct < −5%`, 🟢 otherwise; note the sign inversion versus latency metrics — for throughput, a *decrease* is the regression direction).
|
||
- Acceptance evidence: criterion samples-per-second estimates from `target/criterion/.../estimates.json` for each of the three sub-benches projected through `examples/emit_baseline`; advisory marker rendered by `examples/compare_baseline`.
|
||
- Cross-trace: SAD-088, SDD-094.
|
||
- Status: **PENDING_BASELINE**.
|
||
|
||
### 13.1 SDD-120 Coverage Index
|
||
|
||
| SDD Range | SWE.4 Coverage | Tolerance Source |
|
||
|---|---|---|
|
||
| SDD-120 §3 (bench `bench_capture_alloc_count`) | SWE4-UV-058 | SRS-219 clause a (zero-tolerance) |
|
||
| SDD-120 §3 (bench `bench_capture_callback_wall_clock`) | SWE4-UV-059 | SRS-219 clause b (+20% p95) |
|
||
| SDD-120 §3 (bench `bench_opus_encode_latency`) | SWE4-UV-060 | SRS-219 clause c (+15% mean) |
|
||
| SDD-120 §3 (bench `bench_opus_decode_latency`) | SWE4-UV-061 | SRS-219 clause c (+15% mean) |
|
||
| SDD-120 §3 (bench `bench_resampler_throughput`) | SWE4-UV-062 | SRS-219 clause d (−10% samples/sec) |
|
||
|
||
### 13.2 SWE4-UV-058..062 Status Index
|
||
|
||
| SWE.4 ID | Bench function | Bench file | Tolerance | Status |
|
||
|---|---|---|---|---|
|
||
| SWE4-UV-058 | `bench_capture_alloc_count` | `crates/chanora_audio/benches/realtime_capture.rs` | zero | PENDING_BASELINE |
|
||
| SWE4-UV-059 | `bench_capture_callback_wall_clock` | `crates/chanora_audio/benches/realtime_capture.rs` | +20% p95 | PENDING_BASELINE |
|
||
| SWE4-UV-060 | `bench_opus_encode_latency` | `crates/chanora_audio/benches/opus_codec.rs` | +15% mean | PENDING_BASELINE |
|
||
| SWE4-UV-061 | `bench_opus_decode_latency` | `crates/chanora_audio/benches/opus_codec.rs` | +15% mean | PENDING_BASELINE |
|
||
| SWE4-UV-062 | `bench_resampler_throughput` | `crates/chanora_audio/benches/resampler.rs` | −10% samples/sec | PENDING_BASELINE |
|