docs(sdd-120): correct post-processor binary placement to examples/ (v0.9.16)
SDD-120 amendment v0.9.15 → v0.9.16 reflecting commit 3a7750a discovery. The two post-processor tools (emit_baseline, compare_baseline) were originally specified in SDD-120 §2 as residing in crates/chanora_audio/benches/, with [[bin]] declarations in Cargo.toml. The implementation discovered that Cargo's dependency resolver only routes [dev-dependencies] to [[test]], [[bench]], and [[example]] targets — NOT to [[bin]] targets under src/bin/ or to ad-hoc paths. Routing serde_json (required by both binaries) as a regular [dependencies] entry to support [[bin]] placement would force it into the production cdylib build, contradicting SDD-120 §10 release-artifact isolation: "no production telemetry export" and "no benchmark surface in shipping artifacts." Confirmed by the user's question about whether benchmark crates ship in the release artifact (they must not). The correct Cargo-idiomatic placement is examples/. Cargo auto-discovers files under examples/ as example targets; they receive [dev-dependencies] routing; and they are excluded from cargo build --release and from flutter build --release artifacts by Cargo design. Amendment scope (SDD-120 only): - §1 item 4: [[bin]] → [[example]]; cargo run --bin → cargo run --example. - §2: added item 5 with the rationale clause + Cargo dependency resolver explanation. - §5 item 1: path benches/ → examples/; invocation flag --bin → --example. - §5 item 4: dev-dependencies routing clause updated. - §6 step 6/8: --bin → --example. - §7 step 5: --bin → --example. - §10 item 1: release-artifact-isolation bullet extended to cite the [dev-dependencies] Cargo design mechanism that enforces it. - §11 verification matrix unchanged. - "Allocated to" line + "Software units" list updated to reference examples/ paths. No semantic change to SDD-120: same harness, same metrics, same workflows, same out-of-scope deferrals. The implementation at 3a7750a already lives at the corrected paths; this amendment brings the SDD text into agreement with the code.
This commit is contained in:
+17
-10
@@ -3,7 +3,7 @@
|
||||
|
||||
**Document type:** SDD / Software Detailed Design
|
||||
**Process alignment:** ASPICE SWE.3 Software Detailed Design and Unit Construction
|
||||
**Version:** 0.9.13
|
||||
**Version:** 0.9.16
|
||||
**Status:** Baseline Candidate
|
||||
**Language:** English
|
||||
**Product:** Chanora
|
||||
@@ -1706,8 +1706,8 @@ Notes:
|
||||
**SDD-120 — Realtime audio benchmark harness and advisory CI infrastructure**
|
||||
|
||||
- Source SAD: SAD-088 (criterion-based bench harness allocated to `chanora_audio` `benches/` directory, extending SAD-034 audio-subsystem allocation), SAD-089 (baseline-JSON on-disk path pinned to `crates/chanora_audio/benches/baselines/x86_64-unknown-linux-gnu.json`), SAD-090 (advisory CI workflow `.github/workflows/bench-advisory.yml` — PR-triggered, non-blocking, comment-posting reader of SAD-089), SAD-091 (baseline-update CI workflow `.github/workflows/bench-baseline-update.yml` — `workflow_dispatch`-only, sole writer of SAD-089).
|
||||
- Allocated to: Audio Subsystem (`crates/chanora_audio/benches/`) + Build/Release/Operations (`.github/workflows/bench-advisory.yml`, `.github/workflows/bench-baseline-update.yml`).
|
||||
- Software units (new): `crates/chanora_audio/benches/realtime_capture.rs`, `crates/chanora_audio/benches/opus_codec.rs`, `crates/chanora_audio/benches/resampler.rs`, `crates/chanora_audio/benches/common.rs` (shared synthetic-input helper module), `crates/chanora_audio/benches/emit_baseline.rs` (post-bench JSON aggregator binary), `crates/chanora_audio/benches/compare_baseline.rs` (PR-vs-baseline comparator binary), `crates/chanora_audio/Cargo.toml` (dev-dependency additions and `[[bench]]` entries), `.github/workflows/bench-advisory.yml`, `.github/workflows/bench-baseline-update.yml`, `crates/chanora_audio/benches/baselines/x86_64-unknown-linux-gnu.json` (seeded SAD-089 baseline file).
|
||||
- Allocated to: Audio Subsystem (`crates/chanora_audio/benches/` for criterion bench targets; `crates/chanora_audio/examples/` for the post-processor binaries — see §2 rationale) + Build/Release/Operations (`.github/workflows/bench-advisory.yml`, `.github/workflows/bench-baseline-update.yml`).
|
||||
- Software units (new): `crates/chanora_audio/benches/realtime_capture.rs`, `crates/chanora_audio/benches/opus_codec.rs`, `crates/chanora_audio/benches/resampler.rs`, `crates/chanora_audio/benches/common.rs` (shared synthetic-input helper module), `crates/chanora_audio/examples/emit_baseline.rs` (post-bench JSON aggregator binary), `crates/chanora_audio/examples/compare_baseline.rs` (PR-vs-baseline comparator binary), `crates/chanora_audio/Cargo.toml` (dev-dependency additions and `[[bench]]` entries), `.github/workflows/bench-advisory.yml`, `.github/workflows/bench-baseline-update.yml`, `crates/chanora_audio/benches/baselines/x86_64-unknown-linux-gnu.json` (seeded SAD-089 baseline file).
|
||||
- Cross-trace: SDD-094 (the `chanora_audio::engine::AudioEngine` capture path that the §3 bench seam exercises is the same audio engine whose `ensure_running` / `shutdown_if_idle` lifecycle is specified by SDD-094; the harness measures the steady-state callback that runs while `ensure_running` has opened the cpal input stream, so the bench seam is part of the engine's verification surface). No cross-trace to SDD-076..SDD-080 / SDD-118: the bench targets the realtime audio path and not the PTT capability surface; the Android-bridge build automation is unrelated to the Linux-host bench workflow.
|
||||
|
||||
§1 — Crate selection and version pin.
|
||||
@@ -1715,7 +1715,7 @@ Notes:
|
||||
1. Add `criterion = "0.5"` to `crates/chanora_audio/Cargo.toml` `[dev-dependencies]`. The `0.5` series is the current stable major and is compatible with the workspace `rust-version = "1.95"` pin. Default features are kept; `html_reports` is left at its default (criterion only emits HTML when invoked with `--save-baseline`/`--load-baseline` against the local user, and CI consumes the per-bench `estimates.json` files directly from `target/criterion/`, so an HTML feature toggle is not load-bearing for the workflow). Rationale: criterion is the de-facto statistical benchmark harness for Rust; it emits a stable JSON estimates file under `target/criterion/<bench>/<group>/estimates.json` that the §5 post-processor parses.
|
||||
2. Add `dhat = "0.3"` to `crates/chanora_audio/Cargo.toml` `[dev-dependencies]`. `dhat` is used inside `bench_capture_alloc_count` to install a `#[global_allocator] static ALLOC: dhat::Alloc = dhat::Alloc;` profiler at bench-binary scope and to compare `dhat::HeapStats::get().total_blocks` (or the equivalent v0.3 API name) before and after the measurement window. Rationale: `dhat` is the de-facto heap profiler for Rust, has zero-cost when disabled, and is the lowest-friction way to obtain a steady-state heap-allocation count for the SRS-219 clause-a zero-allocation invariant (which carries `tolerance = 0`).
|
||||
3. Add three `[[bench]]` entries to `crates/chanora_audio/Cargo.toml`, one per bench file enumerated in §2. Each entry shall set `harness = false` only if the bench file calls `criterion::criterion_main!` directly (criterion's `main!` macro replaces the cargo test harness); the §3 signatures use `criterion_main!` so `harness = false` is required.
|
||||
4. Add two `[[bin]]` entries pointing at `benches/emit_baseline.rs` and `benches/compare_baseline.rs` so that `cargo run --bin emit_baseline` and `cargo run --bin compare_baseline` resolve correctly. The §6 / §7 workflow steps invoke these binaries by name; placing the source files under `benches/` keeps the entire benchmark surface in one directory but requires the `path = "benches/<name>.rs"` field on each `[[bin]]` entry.
|
||||
4. Add two `[[example]]` entries pointing at `examples/emit_baseline.rs` and `examples/compare_baseline.rs` so that `cargo run --example emit_baseline` and `cargo run --example compare_baseline` resolve correctly. The §6 / §7 workflow steps invoke these tools via the `--example` flag (not `--bin`). Cargo auto-discovers files under `examples/` as example targets, so explicit `[[example]]` blocks in `Cargo.toml` are optional; the `path = "examples/<name>.rs"` field is only required if the file lives outside the conventional location.
|
||||
|
||||
§2 — Bench file layout.
|
||||
|
||||
@@ -1723,6 +1723,7 @@ Notes:
|
||||
2. `crates/chanora_audio/benches/opus_codec.rs` — declares `bench_opus_encode_latency` and `bench_opus_decode_latency`. Uses `criterion_group!(opus_codec, bench_opus_encode_latency, bench_opus_decode_latency);` and `criterion_main!(opus_codec);`.
|
||||
3. `crates/chanora_audio/benches/resampler.rs` — declares `bench_resampler_throughput`. Uses `criterion_group!(resampler, bench_resampler_throughput);` and `criterion_main!(resampler);`.
|
||||
4. `crates/chanora_audio/benches/common.rs` — shared synthetic-input helpers per §4. Included from each bench file with `mod common;` (criterion bench files compile as standalone binaries, so `common.rs` is included by relative module declaration in each `realtime_capture.rs` / `opus_codec.rs` / `resampler.rs`; do NOT add it as a fourth `[[bench]]` entry).
|
||||
5. `crates/chanora_audio/examples/emit_baseline.rs` and `crates/chanora_audio/examples/compare_baseline.rs` — the two post-processor tools enumerated in §1 item 4 and detailed in §5 / §8. Placement rationale: emit_baseline and compare_baseline are placed under `examples/` rather than `benches/` or `src/bin/`. Cargo's dependency resolver only routes `[dev-dependencies]` to `[[test]]`, `[[bench]]`, and `[[example]]` targets; binaries under `src/bin/` would force `serde_json` and other CI-only crates into the production `[dependencies]` block, contaminating the release build. The `examples/` placement keeps these tools strictly dev-only — they are excluded from `cargo build --release` and from `flutter build apk/aab/ipa --release`. Co-locating them under `benches/` would also work mechanically for dev-dep routing but conflates the criterion bench-target surface with the auxiliary post-processor surface; `examples/` keeps the two concerns syntactically distinct while preserving the same dev-only isolation property.
|
||||
|
||||
§3 — Bench function signatures and warmup phase.
|
||||
|
||||
@@ -1740,10 +1741,10 @@ Notes:
|
||||
|
||||
§5 — JSON post-processing.
|
||||
|
||||
1. After each bench file runs, criterion writes `target/criterion/<bench-name>/<group-name>/estimates.json` per benchmark group. The §5 binary `crates/chanora_audio/benches/emit_baseline.rs` reads the five expected estimates files (one per §3 bench function, with the resampler bench contributing three sub-bench estimate files that are aggregated into the single SRS-217 `resampler_throughput` record by averaging the three throughput estimates into a per-mode triplet, NOT a single scalar — the SRS-217 schema carries a per-mode record).
|
||||
1. After each bench file runs, criterion writes `target/criterion/<bench-name>/<group-name>/estimates.json` per benchmark group. The §5 binary `crates/chanora_audio/examples/emit_baseline.rs` reads the five expected estimates files (one per §3 bench function, with the resampler bench contributing three sub-bench estimate files that are aggregated into the single SRS-217 `resampler_throughput` record by averaging the three throughput estimates into a per-mode triplet, NOT a single scalar — the SRS-217 schema carries a per-mode record). Invocation pattern: `cargo run --example emit_baseline` (NOT `cargo run --bin emit_baseline`); see §2 item 5 rationale for the `examples/` placement.
|
||||
2. The binary parses each `estimates.json` (a stable criterion-emitted JSON shape: `mean`, `median`, `std_dev`, `confidence_interval`) and projects each metric into an SRS-217 record with fields `{ metric: <name>, value: <f64 or triplet>, unit: <string>, tolerance_pct: <f64 from SRS-219>, host: "x86_64-unknown-linux-gnu", timestamp_utc: <RFC3339> }`. The full output is a single JSON document with one top-level array `metrics`.
|
||||
3. The binary writes the document to `./current.json` in the workspace root (not the SAD-089 path — that path is the comparator's input on advisory runs and the writer's output target on baseline-update runs; §6 step 7 reads SAD-089 from git, §7 step 5 writes SAD-089 by copy).
|
||||
4. Rationale for the Rust-binary approach over a `tools/bench-emit.sh` script: same toolchain as the bench files (no separate `jq` / `python` / `bash` dependency on the runner), same `serde_json` already pulled by the workspace, and the binary can share types with `compare_baseline.rs` (both crates use the same SRS-217 struct definitions).
|
||||
4. Rationale for the Rust-binary approach over a `tools/bench-emit.sh` script: same toolchain as the bench files (no separate `jq` / `python` / `bash` dependency on the runner), same `serde_json` already pulled by the workspace as a `[dev-dependencies]` entry (routed to the `examples/` targets per §2 item 5), and the example can share types with `compare_baseline.rs` via a small shared module under `examples/` (both examples use the same SRS-217 struct definitions).
|
||||
|
||||
§6 — `.github/workflows/bench-advisory.yml` structure (SAD-090 realization).
|
||||
|
||||
@@ -1754,9 +1755,9 @@ Notes:
|
||||
5. Step 3: `Swatinem/rust-cache@v2` (matching existing `.github/workflows/ci.yml`). Reuses the bench target directory across runs.
|
||||
6. Step 4: install the same system audio deps `ci.yml` installs (`libasound2-dev libpulse-dev pkg-config libopus-dev`). Required because the `chanora_audio` crate links `libopus` and the cpal Linux backend pulls ALSA headers at build time.
|
||||
7. Step 5: `cargo bench --bench realtime_capture --bench opus_codec --bench resampler`. (`cargo bench` without `--benches` would build doctests; the explicit `--bench <name>` list bypasses that and matches the three `[[bench]]` entries from §1 item 3.) No `-- --output-format json` flag is required because §5 reads `target/criterion/.../estimates.json` files directly; criterion writes those unconditionally.
|
||||
8. Step 6: `cargo run --bin emit_baseline` → writes `./current.json` to the workspace root.
|
||||
8. Step 6: `cargo run --example emit_baseline` → writes `./current.json` to the workspace root. (Invocation flag is `--example`, not `--bin`; see §2 item 5 rationale.)
|
||||
9. Step 7: `MERGE_BASE=$(git merge-base origin/main HEAD)` and `git show $MERGE_BASE:crates/chanora_audio/benches/baselines/x86_64-unknown-linux-gnu.json > baseline.json`. If the merge-base predates the introduction of SAD-089 (i.e. the file did not exist at that commit), `git show` exits non-zero; the step shall handle the missing-baseline case by writing an empty `baseline.json` placeholder and emitting a single advisory comment `Baseline not yet established at merge-base; first run on default branch will establish.` instead of running the comparator. This is the only branch where the workflow short-circuits before the comparator step. (The `push: branches: [main]` trigger never hits this short-circuit after the first baseline lands.)
|
||||
10. Step 8: `cargo run --bin compare_baseline -- --current ./current.json --baseline ./baseline.json --output ./report.md`. The binary applies the SRS-219 per-metric tolerance table and the §8 marker logic, then writes a markdown table to `./report.md`. The binary shall always exit 0 (per SRS-218 clause 4); regression detection is rendered as a 🔴 marker inside the comment, not as a non-zero exit code.
|
||||
10. Step 8: `cargo run --example compare_baseline -- --current ./current.json --baseline ./baseline.json --output ./report.md`. The example applies the SRS-219 per-metric tolerance table and the §8 marker logic, then writes a markdown table to `./report.md`. The example shall always exit 0 (per SRS-218 clause 4); regression detection is rendered as a 🔴 marker inside the comment, not as a non-zero exit code.
|
||||
11. Step 9: post the markdown as a PR comment via `actions/github-script@v7`, gated on `if: github.event_name == 'pull_request'` (the `push` trigger has no PR to comment on; for `push` runs the workflow still writes `./report.md` as a workflow artifact via `actions/upload-artifact@v4` so the default-branch trend is inspectable from the Actions tab). Comment body is `body: require('fs').readFileSync('report.md', 'utf8')`. The script shall also de-duplicate prior comments by the same `github-actions[bot]` identifier carrying a sentinel marker line (e.g. `<!-- chanora-bench-advisory -->`) at the head of the body — on each run the existing comment is updated in place rather than appended, so a long-lived PR does not accumulate one comment per push. The de-duplication query uses `octokit.rest.issues.listComments` filtered on `user.login === 'github-actions[bot]'` and body-startsWith the sentinel.
|
||||
12. Step 10: `if: always()` and a final `exit 0` — no step in the job sets `continue-on-error: false` against a regression-detecting predicate, so the SRS-218 clause 4 non-blocking property is realized by absence of a failing step rather than by an explicit override.
|
||||
13. Status-check name registered with the branch-protection ruleset (if any): `bench-advisory`. The SDD does not mandate adding this to the required-checks list; SRS-218 clause 4 explicitly prohibits making it required.
|
||||
@@ -1769,7 +1770,7 @@ Notes:
|
||||
4. Step 2: install Rust toolchain (same shape as §6 step 2).
|
||||
5. Step 3: install audio system deps (same shape as §6 step 4).
|
||||
6. Step 4: `cargo bench --bench realtime_capture --bench opus_codec --bench resampler` (same shape as §6 step 5).
|
||||
7. Step 5: `cargo run --bin emit_baseline` (same shape as §6 step 6).
|
||||
7. Step 5: `cargo run --example emit_baseline` (same shape as §6 step 6; invocation flag is `--example`, not `--bin`).
|
||||
8. Step 6: `cp ./current.json crates/chanora_audio/benches/baselines/x86_64-unknown-linux-gnu.json`.
|
||||
9. Step 7: `peter-evans/create-pull-request@v6` with `title: "chore(bench): update baselines on $(date -u +%Y-%m-%d)"`, `branch: bench/baseline-update-$(date -u +%Y%m%d)`, `commit-message: "chore(bench): refresh x86_64-unknown-linux-gnu baseline"`, `body: <generated diff summary>`, and `add-paths: crates/chanora_audio/benches/baselines/x86_64-unknown-linux-gnu.json`. Rationale for opening a PR rather than direct-pushing to `main`: baseline updates should be reviewable in case of accidental triggering (a contributor clicks the dispatch button by mistake), runner pollution (an unrelated process on the GitHub-hosted runner skewed the measurement), or a legitimate regression that should not silently move the floor. The PR is then merged by a reviewer using the normal branch-protection flow; this preserves the SAD-091 invariant that this workflow is the **sole writer** of the SAD-089 file (the PR-merge commit is also written by this workflow's PR, not by a human directly editing the JSON).
|
||||
|
||||
@@ -1793,7 +1794,7 @@ Notes:
|
||||
|
||||
§10 — Out of scope (deferrals preserved through Wave 1.5).
|
||||
|
||||
1. No production telemetry export — the bench is a CI-only artifact; no runtime metric is exported from a shipping `chanora_audio` build.
|
||||
1. No production telemetry export — the bench is a CI-only artifact; no runtime metric is exported from a shipping `chanora_audio` build. The `examples/` placement of the post-processor binaries (per §2 item 5 rationale) is the mechanism that enforces this release-artifact isolation: `[dev-dependencies]` (including `serde_json`, `criterion`, `dhat`) are excluded from `cargo build --release` by Cargo design, so neither the criterion bench targets nor the `emit_baseline` / `compare_baseline` examples — and none of their transitive dev-only deps — can be reached by a release build of the production cdylib or the Flutter `--release` artifacts.
|
||||
2. No hard CI gate — SRS-218 clause 4 is invariant; the advisory workflow never fails a check on regression.
|
||||
3. No multi-host benchmarking — SysDes-157 pins the host to `x86_64-unknown-linux-gnu`; the SAD-089 filename is target-triple-keyed to permit future multi-host expansion without directory restructuring, but adding a second host (e.g. `aarch64-apple-darwin` for macOS measurement) is out of scope at this revision.
|
||||
4. No IDE integration — no VS Code task, no IntelliJ run configuration, no flutter-tool wrapper is authored.
|
||||
@@ -1918,3 +1919,9 @@ Notes:
|
||||
| Version | Date | Description |
|
||||
|---|---|---|
|
||||
| 0.9.10 | 2026-05-18 | Added `chanora_bridge` Rust cdylib build-automation detailed design SDD-118 and SDD-119 (SDD-117 left reserved-but-unauthored for the deferred `ios_voice_unit` trait back-fill noted by SDD-111). SDD-118 (`AndroidBridgeBuildAutomation` — Gradle task set in `apps/chanora_flutter/android/app/build.gradle.kts` driving a single `cargo-ndk -t arm64-v8a -t armeabi-v7a -t x86_64` invocation; `cargo ndk --platform $minSdk` sourced from the `chanora.android.minSdk` Gradle property per SDD-073 default 28 / DEC-004; ABI set derived from `android.defaultConfig.ndk.abiFilters` so the two lists stay in sync; profile mapping Gradle-debug→`cargo build` / Gradle-release→`cargo build --release` — deliberate divergence from the iOS / macOS always-`--release` pattern, with the release-build safety property preserved by the item 10 release-inspection assertion; env `LIBOPUS_STATIC=1 LIBOPUS_NO_PKG=1 CMAKE_POLICY_VERSION_MINIMUM=3.5` plus `ANDROID_NDK_HOME` propagation; per-ABI plain copy to `apps/chanora_flutter/android/app/src/main/jniLibs/<abi>/libchanora_bridge.so` with the explicit Rust-triple ↔ Android-ABI mapping; task-graph wiring via `tasks.matching { ... endsWith("JniLibFolders") }.configureEach { dependsOn(...) }` rather than `preBuild.dependsOn`; Gradle `inputs`/`outputs` declarations for up-to-date semantics; preflight that fails loudly with `cargo install cargo-ndk` / `rustup target add ...` remediation rather than auto-installing; release-inspection assertion that each `.so` exists and is >1 KiB before `bundleRelease` / `bundleDebug`; `target/` lives at repo root and is OUTSIDE `gradle clean` scope; sourced from SAD-063 with cross-trace to SDD-073 / SDD-105 / SDD-109). SDD-119 (`iOSAndMacOSBridgeBuildAutomation` — back-fill of the existing CocoaPods-podspec automation under `apps/chanora_flutter/ios/chanora_bridge.podspec` and `apps/chanora_flutter/macos/chanora_bridge.podspec`; dual-hook `prepare_command` + `script_phase :before_compile`; iOS single-arch `aarch64-apple-ios` flat framework with hand-written Info.plist and `install_name_tool -id @rpath/chanora_bridge.framework/chanora_bridge`; macOS dual-arch `aarch64-apple-darwin` + `x86_64-apple-darwin` joined by `lipo -create` in a `Versions/A` framework layout with `install_name_tool -id @rpath/chanora_bridge.framework/Versions/A/chanora_bridge`; always `--release`; iOS env `IPHONEOS_DEPLOYMENT_TARGET=13.0 CMAKE_POLICY_VERSION_MINIMUM=3.5 CMAKE_OSX_DEPLOYMENT_TARGET=13.0`, macOS env `MACOSX_DEPLOYMENT_TARGET=10.15 LIBOPUS_STATIC=1 LIBOPUS_NO_PKG=1 CMAKE_POLICY_VERSION_MINIMUM=3.5`; CocoaPods `vendored_frameworks` integration; cargo incremental + per-platform timestamp guard caching; sourced from SAD-061 / SAD-062 with macOS-runtime SAD anchor flagged as a follow-up; known doc-drift defect recorded: iOS podspec comment references `aarch64-apple-ios-sim` but the script does not actually build the simulator slice — recorded as a TODO follow-up, NOT fixed in this SDD task; deployment-target single-source-of-truth improvement recorded as open follow-up). Updated §11 SAD-to-SDD coverage matrix to list SDD-118 and SDD-119 with their respective SAD anchors. Strict layered sourcing preserved (`SDD -> SAD` only). |
|
||||
|
||||
## Baseline Candidate 0.9.16 Update
|
||||
|
||||
| Version | Date | Description |
|
||||
| --- | --- | --- |
|
||||
| 0.9.16 | 2026-05-18 | SDD-120 amendment: clarify the post-processor binary placement at `crates/chanora_audio/examples/` rather than `benches/` or `src/bin/`. Rationale: Cargo's dependency resolver only routes `[dev-dependencies]` to `[[test]]`, `[[bench]]`, and `[[example]]` targets; `src/bin/` placement would have forced `serde_json` and other dev-only crates into production builds. Reflects commit 3a7750a discovery. No semantic change to SDD-120 — same harness, same metrics, same workflows, same out-of-scope deferrals; only the path conventions and invocation flags (`--example` not `--bin`) corrected. Edits scoped to SDD-120: (1) "Allocated to" line gains `crates/chanora_audio/examples/` alongside `benches/`; (2) "Software units" list relocates `emit_baseline.rs` and `compare_baseline.rs` from `benches/` to `examples/`; (3) §1 item 4 reworded from `[[bin]]` entries pointing into `benches/` to `[[example]]` entries (auto-discovered under `examples/`) with `cargo run --example` invocation pattern; (4) §2 gains a new item 5 stating the `examples/` rationale and the dev-only isolation property; (5) §5 item 1 path updated and invocation-flag note added; (6) §5 item 4 rationale clause updated to reference the `[dev-dependencies]`-to-examples routing; (7) §6 step 6 and step 8 invocation flags changed `--bin` → `--example`; (8) §7 step 5 invocation flag changed `--bin` → `--example`; (9) §10 item 1 release-artifact-isolation bullet extended with an explicit note that the `examples/` placement is the Cargo-design mechanism enforcing the exclusion of `[dev-dependencies]` (including `serde_json`, `criterion`, `dhat`) from `cargo build --release` and from `flutter build apk/aab/ipa --release`. §11 verification matrix unchanged. Coverage matrix row for SAD-088..SAD-091 unchanged. The SDD-120 spec is otherwise byte-identical to v0.9.15. |
|
||||
|
||||
Reference in New Issue
Block a user