NeuralAmpModeler-rs 0.6.0

High-performance Neural Amp Modeler DSP core: WaveNet/LSTM/ConvNet inference, SIMD math (x86-64-v3), .nam/.namb loader, cabinet IR, resampling and noise gate.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
<!--
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2026 Fábio Henrique de Lima Silva (fhl.bsb@gmail.com) All rights reserved.
-->

# Fixture Governance & Golden Vector Reference — NeuralAmpModelerCore ↔ NAM-rs

## Source of Truth

All golden vectors in `tests/fixtures/` are generated by **NeuralAmpModelerCore** (Steven Atkinson) — the canonical implementation that trains and generates `.nam` models.

## Repo-Local Third-Party Area

The upstream C++ mirrors used for cross-reference validation are **not
committed** to git. They live under the gitignored `third-party/` directory
inside this repository, populated by `utils/setup-third-party.sh`:

| Directory                             | Size    | Purpose                                                                          |
| ------------------------------------- | ------- | -------------------------------------------------------------------------------- |
| `third-party/NeuralAmpModelerCore/`   | ~143 MB | Upstream C++ reference (`render` tool for ALL goldens)                           |
| `third-party/NeuralAmpModelerPlugin/` | ~164 MB | Upstream C++ IR reference (`dsp::ImpulseResponse`, cabsim cross-validation only) |
| `third-party/community_models/`       | varies  | Optional symlink/dir of non-distributable community test models                  |
| `build/namcore_render/`               | ~6 MB   | CMake build artifacts from NeuralAmpModelerCore (repo-local, gitignored)         |

> [!NOTE]
> The third-party base directory defaults to `third-party/` at this repo root
> and can be overridden via `NAM_THIRD_PARTY_DIR` (or `NAM_CORE_DIR` /
> `NAM_PLUGIN_DIR`) when the layout differs.
>
> **`utils/setup-third-party.sh` syncs both `NeuralAmpModelerCore` and
> `NeuralAmpModelerPlugin`** (including their submodules) into `third-party/`,
> and optionally links `community_models` when `NAM_COMMUNITY_MODELS_SRC` is set.
> Run it after a fresh clone (or when pins change) to match
> [`variables.env`](../variables.env).

### To regenerate all fixtures from scratch

```bash
# Populate / refresh vendor mirrors (pins from variables.env)
./utils/setup-third-party.sh

# Optional: wipe prior C++ build + Core mirror for a clean regenerate
rm -rf third-party/NeuralAmpModelerCore build/namcore_render
./utils/setup-third-party.sh

# Run full regeneration (builds render tool, generates goldens except known gaps)
./tests/fixtures/golden_gen_build.sh

# Full audit suite (includes long-duration C++ cross-validation)
./utils/tests-long.sh
```

> [!NOTE]
> `utils/tests-long.sh` no longer carries bash golden lists or auto-regeneration:
> golden/fixture presence is gated fail-closed by the Rust
> `catalog_preflight` (V1 + V2 golden catalogs in `src/testing/catalog.rs`) and
> `check_freshness` (nam_freshness manifest). To regenerate missing vectors,
> run `./tests/fixtures/golden_gen_build.sh` (C++ toolchain + local
> NeuralAmpModelerCore dependencies required). The former
> `NAM_AUTO_BUILD_GOLDENS` / `NAM_SKIP_GOLDEN_BUILD` knobs were removed.

When the pinned upstream commits are updated (after re-baselining goldens),
update the values in [`variables.env`](../variables.env)
(sourced by both `golden_gen_build.sh` and `setup-third-party.sh`). All goldens
generated from the new version must pass both Layer 1 and Layer 2 validation
before committing.

## Golden Vector Catalog & Fixtures Inventory

| Golden File                                  | `.nam` Model                          | Nature                                                                        | Topology                                                                |
| -------------------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `golden_wavenet_standard.bin`                | `BossWN-standard.nam`                 | Community real (Boss Waza, trained)                                           | CH=16, K=3, HEAD=8, 20 layers                                           |
| `golden_wavenet_lite.bin`                    | `EVH-5150-Lite.nam`                   | **Community real** (CH=12 WaveNet Lite, non-distributable)                    | CH=12, K=3, HEAD=6, 20 layers                                           |
| `golden_wavenet_feather.bin`                 | `BossWN-feather.nam`                  | Community real (Boss Waza, trained)                                           | CH=8, K=3, HEAD=4, 20 layers                                            |
| `golden_wavenet_nano.bin`                    | `BossWN-nano.nam`                     | Community real (Boss Waza, trained)                                           | CH=4, K=3, HEAD=2, 20 layers                                            |
| `golden_wavenet_a1_standard.bin`             | `wavenet_a1_standard.nam`             | **Official real** (trained model, 407 KB, md5 `1c540f40…`)                    | CH=16, K=3, HEAD=8, 20 layers                                           |
| `golden_lstm_1x16.bin`                       | `BossLSTM-1x16.nam`                   | Community real (Boss Waza, trained)                                           | 1 layer, H=16                                                           |
| `golden_lstm_2x8.bin`                        | `BossLSTM-2x8.nam`                    | Community real (Boss Waza, trained)                                           | 2 layers, H=8                                                           |
| `golden_lstm_official.bin`                   | `lstm.nam`                            | **Official real** (NAM example model, 1 layer H=3)                            | 1 layer, H=3                                                            |
| `golden_wavenet_a2_full.bin`                 | `wavenet_a2_full.nam`                 | **Synthetic** (weights calibrated for fast-path parity; not FiLM/official)    | CH=8, K=6/15, 23 layers — cross-reference vs C++ v0.5.4                 |
| `golden_wavenet_a2_lite.bin`                 | `wavenet_a2_lite.nam`                 | **Synthetic** (weights calibrated for fast-path parity; not FiLM/official)    | CH=3, K=6/15, 23 layers — cross-reference vs C++ v0.5.4                 |
| `golden_wavenet_a2_film_full.bin`            | `wavenet_a2_film_full.nam`            | **Synthetic** (FiLM — PM-05 conformism, RF1)                                  | CH=8, K=6/15, 23 layers, FiLM post-mod — cross-reference vs C++ generic |
| `golden_wavenet_a2_film_lite.bin`            | `wavenet_a2_film_lite.nam`            | **Synthetic** (FiLM — PM-05 conformism, RF1)                                  | CH=3, K=6/15, 23 layers, FiLM post-mod — cross-reference vs C++ generic |
| `golden_a2_dynamic_gated_ch8.bin`            | `a2_dynamic_gated_ch8.nam`            | **Synthetic** (dynamic gating engine parity)                                  | CH=8, 3 gated layers — cross-reference vs C++ generic                   |
| `golden_a2_dynamic_blended_ch3.bin`          | `a2_dynamic_blended_ch3.nam`          | **Synthetic** (dynamic blending engine parity)                                | CH=3, 2 blended layers — cross-reference vs C++ generic                 |
| `golden_linear_fft_rf320.bin`                | `linear_fft_rf320.nam`                | **Synthetic** (functional parity, partitioned convolution)                    | RF=320, 2 channels, block=128                                           |
| `golden_linear_fft_rf2048.bin`               | `linear_fft_rf2048.nam`               | **Synthetic** (functional parity, partitioned convolution)                    | RF=2048, 1 channel, block=1024                                          |
| `golden_linear_fft_rf4096.bin`               | `linear_fft_rf4096.nam`               | **Synthetic** (functional parity, partitioned convolution)                    | RF=4096, 1 channel, block=2048                                          |
| `golden_linear_fft_rf8192.bin`               | `linear_fft_rf8192.nam`               | **Synthetic** (functional parity, partitioned convolution)                    | RF=8192, 1 channel, block=4096                                          |
| `golden_a2_example.bin`                      | `a2_example.nam`                      | **Synthetic** (SlimmableContainer with A2 submodels)                          | CH=3→6, 23 layers                                                       |
| `golden_convnet_test.bin`                    | `convnet_test.nam`                    | **Synthetic** (ConvNet parity)                                                | CH=8, 6 blocks                                                          |
| `golden_lstm_dyn_test.bin`                   | `lstm_dyn_test.nam`                   | **Synthetic** (LSTM dynamic path parity)                                      | 1 layer, H=7                                                            |
| `golden_wavenet_a2_film_chaos_stress.bin`    | `wavenet_a2_film_chaos_stress.nam`    | **Synthetic** (FiLM, pre-fix chaos stress snapshot)                           | CH=3, bottleneck=3, FiLM conv/input_mixin/activation/layer1x1           |
| `golden_wavenet_a2_film_input_mixin_pre.bin` | `wavenet_a2_film_input_mixin_pre.nam` | **Synthetic** (FiLM, isolated input_mixin_pre regression — Bug C1)            | CH=3, bottleneck=3, FiLM input_mixin_pre only                           |
| `golden_wavenet_a2_max.bin`                  | `wavenet_a2_max.nam`                  | **Official real** — KB-A2-MAX known bug (guard TR1.1; meter ~0.23 dB; §4.4.3) | CH=4, cond=8 FiLM; retained for future reopen diagnostics               |
| `golden_wavenet_app_evh.bin`                 | (non-distributable)                   | Community real (EVH Stealth 100)                                              | —                                                                       |
| `golden_wavenet_boss_bd2.bin`                | (non-distributable)                   | Community real (Boss BD-2 H2O Mod)                                            | —                                                                       |
| `golden_wavenet_condition_dsp.bin`           | `wavenet_condition_dsp.nam`           | **Official real** (FiLM+condition_dsp, near-bit-exact)                        | CH=3, cond=3 FiLM, post-FiLM DSP                                        |
| `golden_wavenet_dyn_free.bin`                | `wavenet_dyn_free.nam`                | **Synthetic** (WaveNet free-shape dynamic path)                               | CH=7/4, free geometry                                                   |
| `golden_wavenet_official.bin`                | `wavenet_official.nam`                | **Official real** (CH=3 free geom, dynamic path)                              | CH=3, K=3                                                               |
| `golden_wavenet_slammin_marshall.bin`        | (non-distributable)                   | Community real (Slammin Marshall J45)                                         | —                                                                       |
| `golden_lstm_1x10.bin`                       | `lstm_1x10.nam`                       | **Synthetic** (Uncatalogued LSTM hidden size)                                 | 1 layer, H=10                                                           |
| `golden_lstm_2x24.bin`                       | `lstm_2x24.nam`                       | **Synthetic** (Uncatalogued LSTM hidden size)                                 | 2 layers, H=24                                                          |
| `golden_lstm_3x8.bin`                        | `lstm_3x8.nam`                        | **Synthetic** (3-layer LSTM topology)                                         | 3 layers, H=8                                                           |
| `golden_convnet_nobn.bin`                    | `convnet_nobn.nam`                    | **Synthetic** (ConvNet without BatchNorm)                                     | CH=8, 6 blocks                                                          |
| `golden_convnet_relu.bin`                    | `convnet_relu.nam`                    | **Synthetic** (ConvNet with ReLU activation)                                  | CH=8, 6 blocks                                                          |
| `golden_convnet_silu.bin`                    | `convnet_silu.nam`                    | **Synthetic** (ConvNet with SiLU activation)                                  | CH=8, 6 blocks                                                          |
| `golden_linear_nobias.bin`                   | `linear_nobias.nam`                   | **Synthetic** (Linear without bias)                                           | RF=4, bias=0.0                                                          |
| `golden_wavenet_a1_secondary_act.bin`        | `wavenet_a1_secondary_act.nam`        | **Synthetic** (Non-null secondary activation rejection fixture)               | CH=16, non-null secondary activation                                    |
| `golden_wavenet_condition_lstm.bin`          | `wavenet_condition_lstm.nam`          | **Synthetic** (WaveNet + LSTM condition_dsp; skip_reason)                     | CH=3, cond=3, LSTM 1×3                                                  |
| `golden_cabsim_cpp_short.bin`                | N/A                                   | C++ reference (synthetic IR)                                                  | Cabsim Short IR (64 samples) C++ dsp::ImpulseResponse                   |
| `golden_cabsim_cpp_medium.bin`               | N/A                                   | C++ reference (synthetic IR)                                                  | Cabsim Medium IR (512 samples) C++ dsp::ImpulseResponse                 |
| `golden_cabsim_cpp_long.bin`                 | N/A                                   | C++ reference (synthetic IR)                                                  | Cabsim Long IR (8192 samples) C++ dsp::ImpulseResponse                  |

> [!WARNING]
> **Automation gaps tracked:**
>
> - `golden_wavenet_a2_film_{full,lite}.bin`, `golden_a2_dynamic_gated_ch8.bin`, and
>   `golden_a2_dynamic_blended_ch3.bin` are now **auto-generated** by
>   `golden_gen_build.sh` for v1 (48000 Hz). Their `.nam` source models are built by
>   `tests/fixtures/generate_a2_fixtures.py`, and v1 goldens are rendered by the
>   script's v1 loop. v2 multi-SR goldens are intentionally skipped
>   (`v2_scope=none` in `src/testing/catalog.rs::GOLDEN_GEN_CATALOG`) — see the
>   rationale comment in `golden_gen_build.sh` for the technical explanation.
> - `golden_cabsim_cpp_stress.bin` has been **removed**. `tests/fixtures/render_ir.cpp`
>   only implements 3 scenarios (short, medium, long) because the C++
>   `dsp::ImpulseResponse` engine hard-caps IR length at 8192 samples (`mMaxLength`),
>   so a genuine C++ cross-reference for a 65536-sample IR is not achievable with the
>   vendored engine — see `tests/parity/cabsim_cpp_parity.rs` for the Rust-side rationale.
>
> **Nature classification:**
>
> - **Official real** — modelo `.nam` com pesos treinados, publicado pelo projeto NAM oficial (`sdatkinson/NeuralAmpModelerCore`).
> - **Community real** — modelo `.nam` com pesos treinados, publicado pela comunidade (Boss Waza Tube Amp Expander).
> - **Synthetic** — pesos auto-gerados/calibrados para fins de validação; **não** representam timbres de amplificador reais.
> - **C++ reference** — vetores de referência gerados pelo C++ upstream (`dsp::ImpulseResponse`); não são modelos NAM.
>   [!NOTE]
>   **Resumo rápido:** 5 goldens são **oficial real** (A1-Standard, LSTM Official, A2-Max-disabled,
>   Condition-DSP, Official CH=3).
>   9 são **community real** (WaveNet Standard, Lite CH=12, Feather, Nano,
>   LSTM 1×16/2×8 — todos Boss Waza — mais EVH Stealth 100, Boss BD-2, Slammin Marshall J45,
>   todos não-distributáveis).
>   24 são **synthetic** (A2-Full, A2-Lite, A2-FiLM-Full, A2-FiLM-Lite,
>   A2-Dynamic-Gated-CH8, A2-Dynamic-Blended-CH3, Linear-FFT-RF320/2048/4096/8192,
>   A2-Example, ConvNet-Test, ConvNet-NoBN, ConvNet-ReLU, ConvNet-SiLU, Linear-NoBias,
>   LSTM-Dyn-Test, LSTM 1×10, LSTM 2×24, LSTM 3×8, A2-FiLM-Chaos-Stress,
>   A2-FiLM-InputMixinPre, WaveNet-Dyn-Free, WaveNet A1 Secondary Act, WaveNet Condition LSTM).
>   Os 3 goldens C++ cabsim são vetores de referência do upstream.

### Model Files and Trust Levels Registry

All captures and models in `.nam` and `.json` format located under [`tests/fixtures/models/`](../tests/fixtures/models/) are audited to verify quality, legal provenance, and usefulness in integration tests.

> [!NOTE]
> **Registry completeness:** all models in `tests/fixtures/models/` are accounted for in the
> tables above and have dedicated provenance sections below.

#### 1. High-Quality Real Models (Git Versioned)

These models have real trained weights, excellent fidelity, and are certified for authorship/permissive licensing compatible with `nam-rs` distribution:

| Model / Fixture           | Nature         | Architecture                    | Quality & Confidence                  | License & Provenance                                   | Purpose in Tests                                                                                                                                                         |
| ------------------------- | -------------- | ------------------------------- | ------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `BossLSTM-1x16.nam`       | Community Real | LSTM (1 layer, H=16)            | **High** (Proven)                     | Boss Waza TAE Community. Compatible license.           | Golden vectors v1, v2 multi-SR and zero-allocation checks.                                                                                                               |
| `BossLSTM-2x8.nam`        | Community Real | LSTM (2 layers, H=8)            | **High** (Proven)                     | Boss Waza TAE Community. Compatible license.           | Golden vectors v1, v2 multi-SR and weight layout roundtrip.                                                                                                              |
| `BossWN-standard.nam`     | Community Real | WaveNet (CH=16, K=3, 20 layers) | **High** (Proven)                     | Boss Waza TAE Community. Compatible license.           | E2E SPSC pipeline, golden vectors v1/v2, zero-allocation.                                                                                                                |
| `BossWN-feather.nam`      | Community Real | WaveNet (CH=8, K=3, 20 layers)  | **High** (Proven)                     | Boss Waza TAE Community. Compatible license.           | Golden vectors v1/v2, zero-allocation tests.                                                                                                                             |
| `BossWN-nano.nam`         | Community Real | WaveNet (CH=4, K=3, 20 layers)  | **High** (Proven)                     | Boss Waza TAE Community. Compatible license.           | Golden vectors v1/v2, multi-SR checks.                                                                                                                                   |
| `wavenet_a1_standard.nam` | Official Real  | WaveNet (CH=16, K=3, 20 layers) | **High** (Excellent / Steve Atkinson) | Pinned `sdatkinson/NeuralAmpModelerCore` example. CC0. | Golden vectors v1/v2.                                                                                                                                                    |
| `wavenet_official.nam`    | Official Real  | WaveNet (CH=3, K=3, free geom)  | **High** (Excellent / Steve Atkinson) | Pinned `sdatkinson/NeuralAmpModelerCore` example. CC0. | Permanent clone-protection regression fixture. Golden vectors v1/v2, self-consistency (dynamic path). Heterogeneous clone exact tested in `wavenet_clone_exact_test.rs`. |
| `lstm.nam`                | Official Real  | LSTM (1 layer, H=3)             | **High** (Excellent / Steve Atkinson) | Pinned `sdatkinson/NeuralAmpModelerCore` example. CC0. | Golden vectors v1/v2, C++ live parity.                                                                                                                                   |

#### 2. Synthetic Models and Mocks (Targets for Progressive Replacement)

These files contain synthetic weights or partial/invalid structures. They exist exclusively to validate boundary limits, error detection, and specific numerical regressions, with the goal of being progressively replaced by real, licensed models as they become available:

| Model / Fixture                       | Nature           | Architecture                                                             | Quality & Confidence                                                                                                       | License & Provenance                                                                      | Purpose in Tests                                                                                                                                                                                                                 |
| ------------------------------------- | ---------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BossWN-lite.nam`                     | Synthetic        | WaveNet (CH=12, K=3, 20 layers)                                          | **Obsolete** — replaced by `EVH-5150-Lite.nam`                                                                             | Artificially generated.                                                                   | Legacy fixture; no longer used in active tests. Superseded by real community model.                                                                                                                                              |
| `linear_test.nam`                     | Synthetic        | Linear (RF=4, bias=0.1)                                                  | **High** (Functional parity)                                                                                               | Simple weights defined for testing. Apache-2.0.                                           | Linear parity and linear_golden.                                                                                                                                                                                                 |
| `wavenet_a2_full.nam`                 | Synthetic        | WaveNet A2 (CH=8, K=6/15, 23 layers)                                     | **High** (Fast-path parity)                                                                                                | Calibrated weights. Apache-2.0.                                                           | Parity A2 fast-path (Full), container submodel.                                                                                                                                                                                  |
| `wavenet_a2_lite.nam`                 | Synthetic        | WaveNet A2 (CH=3, K=6/15, 23 layers)                                     | **High** (Fast-path parity)                                                                                                | Calibrated weights. Apache-2.0.                                                           | Parity A2 fast-path (Lite), container submodel.                                                                                                                                                                                  |
| `wavenet_a2_container.nam`            | Synthetic        | SlimmableContainer (A2 Lite & Full)                                      | **High** (Functional parity)                                                                                               | Container joining the two submodels above. Apache-2.0.                                    | Golden vectors container (A2 Lite and A2 Full submodel swaps).                                                                                                                                                                   |
| `keras_unsupported.json`              | Mock / Synthetic | Keras Legacy format (H5 Mock)                                            | N/A (Negative mock)                                                                                                        | Clean structure without weights (legal mitigation). Apache-2.0.                           | Tests graceful rejection of legacy Keras format (F13).                                                                                                                                                                           |
| `mock_a2.nam`                         | Mock / Synthetic | WaveNet (ReLU config, zero weights)                                      | N/A (Negative mock)                                                                                                        | Empty model for failure testing. Apache-2.0.                                              | Permanent negative regression fixture. Tests failure transition on the audio thread (`RT_STATUS_MODEL_LOAD_FAILED`).                                                                                                             |
| `slimmable_container.nam`             | Mock / Synthetic | SlimmableContainer (3 submodels: LSTM 1x3 + WaveNetDyn + Nano)           | **High** (Topology routing, ReLU verified)                                                                                 | Container exercising topology dispatch across architectures. Apache-2.0.                  | Permanent regression fixture. Validates robust submodel routing (LSTM fast-path + WaveNetDyn free-geometry + Nano SKU) with ReLU.                                                                                                |
| `slimmable_wavenet.nam`               | Official / Core  | WaveNet slimmable (`slice_channels_uniform`, `allowed_channels=[1,2,3]`) | **Disclaimer** — inference-only; sem claim de paridade multi-size NAMCore                                                  | Upstream-style slimmable single-net fixture. Apache-2.0 / core distribution.              | **Not** a reject mock. `test_loader_gap_slimmable_wavenet` and `test_slimmable_wavenet_inference_and_breakpoints` assert successful build. C++ multi-size parity architecturally infeasible (NAMCore lacks channel-slicing API). |
| `wavenet_a2_max.nam`                  | Official Real    | WaveNet (CH=4, cond=8 FiLM, head1x1)                                     | **Known bug KB-A2-MAX** (fail-closed TR1.1; prod×C++ **SNR ≈ 0.23 dB**; see [cpp_parity_map.md](cpp_parity_map.md) §4.4.3) | Steve Atkinson official example. CC0.                                                     | Permanent known bug. `test_wavenet_a2_max_dispatch_rejected` asserts `Err` (KB-A2-MAX). Golden/meter/live ignored — not CI gates. Unlock: `NAM_A2_MAX_UNLOCK=1` (test/testing only).                                             |
| `wavenet_condition_dsp.nam`           | Official Real    | WaveNet (CH=3, cond=3 FiLM, post-FiLM DSP)                               | **High** (Near-bit-exact — SNR=139.5 dB)                                                                                   | Steve Atkinson official example. CC0.                                                     | Permanent clone-protection regression fixture. Golden vectors v1 (dynamic path with FiLM+condition_dsp, §6 of this doc). Heterogeneous clone exact tested in `wavenet_clone_exact_test.rs`.                                      |
| `wavenet_a2_film_full.nam`            | Synthetic        | WaveNet A2 (CH=8, FiLM active)                                           | **Medium** (FiLM parity — SNR=36.0 dB, RF1)                                                                                | Generated by `generate_a2_fixtures.py`. Apache-2.0.                                       | Golden vectors v1 (A2+FiLM dynamic path, §FiLM Fixtures section).                                                                                                                                                                |
| `wavenet_a2_film_lite.nam`            | Synthetic        | WaveNet A2 (CH=3, FiLM active)                                           | **Medium** (FiLM parity — SNR=18.1 dB, RF1)                                                                                | Generated by `generate_a2_fixtures.py`. Apache-2.0.                                       | Golden vectors v1 (A2+FiLM dynamic path, §FiLM Fixtures section).                                                                                                                                                                |
| `linear_fft_rf320.nam`                | Synthetic        | Linear FFT (RF=320, 2 channels, block=128)                               | **Medium** (Functional parity)                                                                                             | Simple weights defined for testing. Apache-2.0.                                           | Golden vectors v1 (@48k), partitioned convolution cross-validation. Graceful skip if golden absent.                                                                                                                              |
| `linear_fft_rf2048.nam`               | Synthetic        | Linear FFT (RF=2048, 1 channel, block=1024)                              | **Medium** (Functional parity)                                                                                             | Simple weights defined for testing. Apache-2.0.                                           | Golden vectors v1 (@48k), partitioned convolution cross-validation. Graceful skip if golden absent.                                                                                                                              |
| `linear_fft_rf4096.nam`               | Synthetic        | Linear FFT (RF=4096, 1 channel, block=2048)                              | **Medium** (Functional parity)                                                                                             | Simple weights defined for testing. Apache-2.0.                                           | Golden vectors v1 (@48k), partitioned convolution cross-validation. Graceful skip if golden absent.                                                                                                                              |
| `linear_fft_rf8192.nam`               | Synthetic        | Linear FFT (RF=8192, 1 channel, block=4096)                              | **Medium** (Functional parity)                                                                                             | Simple weights defined for testing. Apache-2.0.                                           | Golden vectors v1 (@48k), partitioned convolution cross-validation. Graceful skip if golden absent.                                                                                                                              |
| `a2_example.nam`                      | Synthetic        | SlimmableContainer (A2 submodels)                                        | **Medium** (Container routing)                                                                                             | Generated by `generate_a2_fixtures.py`. Apache-2.0.                                       | Golden vectors v1 (A2 example container, dynamic path).                                                                                                                                                                          |
| `convnet_test.nam`                    | Synthetic        | ConvNet (CH=8, 6 blocks)                                                 | **High** (Functional parity)                                                                                               | Simple weights defined for testing. Apache-2.0.                                           | Golden vectors v1 (@48k), ConvNet topology validation.                                                                                                                                                                           |
| `lstm_dyn_test.nam`                   | Synthetic        | LSTM-Dyn (1 layer, H=7)                                                  | **High** (Functional parity)                                                                                               | Simple weights defined for testing. Apache-2.0.                                           | Golden vectors v1 (@48k), LSTM dynamic path validation.                                                                                                                                                                          |
| `wavenet_a2_film_chaos_stress.nam`    | Synthetic        | WaveNet A2 (CH=3, FiLM 4 slots, non-identity weight scaling)             | **High** (Numerical stress)                                                                                                | Preserved snapshot of pre-fix `wavenet_a2_film_lite.nam` (commit `b96e4c7d`). Apache-2.0. | Golden vectors v1 (FiLM chaos stress, §A2-FiLM Chaos Stress).                                                                                                                                                                    |
| `wavenet_a2_film_input_mixin_pre.nam` | Synthetic        | WaveNet A2 (CH=3, FiLM input_mixin_pre only)                             | **High** (Bug C1 regression)                                                                                               | Generated by `generate_a2_fixtures.py`. Seed 145. Apache-2.0.                             | Golden vectors v1 (isolated input_mixin_pre FiLM, §A2-FiLM InputMixinPre).                                                                                                                                                       |
| `wavenet_condition_lstm.nam`          | Synthetic        | WaveNet + LSTM condition_dsp (CH=3, cond=3, LSTM 1×3)                    | **Medium** (C++ golden blocked — C++ upstream channel mismatch)                                                            | Generated by `generate_a2_fixtures.py`. Apache-2.0.                                       | Golden vectors v1 (WaveNet with LSTM condition_dsp; golden C++ IMPOSSÍVEL — skip_reason).                                                                                                                                        |
| `wavenet_dyn_free.nam`                | Synthetic        | WaveNetDyn (CH=7/4, free geometry)                                       | **High** (Functional parity)                                                                                               | Simple weights defined for testing. Apache-2.0.                                           | Golden vectors v1 (@48k), WaveNet free-shape dynamic path validation.                                                                                                                                                            |
| `lstm_1x10.nam`                       | Synthetic        | LSTM (1 layer, H=10)                                                     | **High** (Functional parity)                                                                                               | Generated by `generate_fixtures.py`. Apache-2.0.                                          | Uncatalogued LSTM hidden size validation.                                                                                                                                                                                        |
| `lstm_2x24.nam`                       | Synthetic        | LSTM (2 layers, H=24)                                                    | **High** (Functional parity)                                                                                               | Generated by `generate_fixtures.py`. Apache-2.0.                                          | Uncatalogued LSTM hidden size validation.                                                                                                                                                                                        |
| `lstm_3x8.nam`                        | Synthetic        | LSTM (3 layers, H=8)                                                     | **High** (Functional parity)                                                                                               | Generated by `generate_fixtures.py`. Apache-2.0.                                          | 3-layer LSTM topology validation.                                                                                                                                                                                                |
| `convnet_nobn.nam`                    | Synthetic        | ConvNet (CH=8, 6 blocks, no BatchNorm)                                   | **High** (Functional parity)                                                                                               | Generated by `generate_fixtures.py`. Apache-2.0.                                          | ConvNet without BatchNorm validation.                                                                                                                                                                                            |
| `convnet_relu.nam`                    | Synthetic        | ConvNet (CH=8, 6 blocks, ReLU)                                           | **High** (Functional parity)                                                                                               | Generated by `generate_fixtures.py`. Apache-2.0.                                          | ConvNet with ReLU activation validation.                                                                                                                                                                                         |
| `convnet_silu.nam`                    | Synthetic        | ConvNet (CH=8, 6 blocks, SiLU)                                           | **High** (Functional parity)                                                                                               | Generated by `generate_fixtures.py`. Apache-2.0.                                          | ConvNet with SiLU activation validation.                                                                                                                                                                                         |
| `linear_nobias.nam`                   | Synthetic        | Linear (RF=4, bias=0.0)                                                  | **High** (Functional parity)                                                                                               | Generated by `generate_fixtures.py`. Apache-2.0.                                          | Linear model without bias validation.                                                                                                                                                                                            |
| `wavenet_a1_secondary_act.nam`        | Mock / Synthetic | WaveNet (non-null secondary_activation)                                  | N/A (Negative mock)                                                                                                        | Generated by `generate_fixtures.py`. Apache-2.0.                                          | Rejection test fixture for non-null secondary activation (F1/F5).                                                                                                                                                                |

#### 3. Non-Distributable Model Management (`third-party/community_models` / `tests/fixtures/models-nondist`)

Due to legal redistribution restrictions on many community captures, they must **not** be
committed to this repository. Local developers working on NeuralAmpModeler-rs can point tests
at a private archive via either `third-party/community_models/` (recommended symlink) or
`tests/fixtures/models-nondist/`:

##### Model Resolution Order (`golden_gen_build.sh`)

`golden_gen_build.sh` resolves every `.nam` model through a shared `resolve_nam_model()` function
that mirrors the search order of `tests/common/io_helpers.rs::model_path`:

| Step | Location                                                              | Environment override  |
|:---- |:--------------------------------------------------------------------- |:--------------------- |
| 1    | `$NAM_MODELS_DIR/<file>`                                              | `NAM_MODELS_DIR`      |
| 2    | `third-party/community_models/<file>` (or `$NAM_THIRD_PARTY_DIR/...`) | `NAM_THIRD_PARTY_DIR` |
| 3    | `tests/fixtures/models-nondist/<file>`                                | —                     |
| 4    | `tests/fixtures/models/<file>` (default, distributed)                 | —                     |

> [!IMPORTANT]
> **Skip rule:** a model is **SKIP**ped only if the file is absent in **all** search paths. If the
> file exists at any path, the gen script **must** either render the golden successfully or
> fail hard — never skip silently. If a model exists in `third-party/community_models/` it will
> be found and rendered.
> [!NOTE]
> **Nondist golden policy:** non-distributable models (EVH-5150-Lite, APP-EVH, Boss BD-2,
> SLAMMIN MARSHALL) live under `third-party/community_models/` or `models-nondist/`. When
> present, the gen script renders their goldens into `tests/fixtures/` as usual. The `.nam`
> files themselves must **not** be committed to git (license restriction). The golden `.bin`
> files follow the project policy:
>
> - **Committed to the repo** when the golden alone does not expose the copyrighted model
>   weights (binary activation outputs are not derivative works of the training corpus).
> - **Gitignored** or kept local if specific legal review requires it.
> - Goldens for models that could not be found at any path are **not** listed as "generated" in
>   the script's final summary — preserving summary honesty.

- Point `third-party/community_models` at your private archive (preferred), or use
  `models-nondist`:

  ```bash
  # After clone / setup-third-party:
  ln -s /path/to/your/nam_models third-party/community_models
  # or:
  NAM_COMMUNITY_MODELS_SRC=/path/to/your/nam_models ./utils/setup-third-party.sh
  # or:
  ln -s /path/to/your/nam_models tests/fixtures/models-nondist
  ```

- The integration test suite (`tests/models/nondist_validation.rs`) automatically detects
  `tests/fixtures/models-nondist` or falls back to `third-party/community_models/`, running a
  comprehensive verification battery (parsing, determinism, block size invariance, and denormal
  silence stability) on all captures found. It skips validation gracefully without failure if
  neither directory is present.

##### Catalog & Model Discovery (`manifest.json`)

`manifest.json` is the machine-readable catalog of all non-distributable models. It enables
`nondist_validation.rs` to discover models and validate expected classification
(e.g., "this CH=32 model should route to WaveNetDyn"). Each entry contains:

```json
{
  "filename": "EVH-5150-Lite.nam",
  "sha256": "4404e56f...",
  "expected_class": "WaveNet A1 Lite (CH=12)",
  "is_goal_target": true,
  "name": "EVH-5150-Lite.nam",
  "author": "Unknown Author"
}
```

Without the manifest, only determinism, block-invariance, and stability are checked (no
classification validation).

##### WaveNet Lite Golden Gate (Non-Distributable)

The cross-parity gate for the WaveNet Lite model in `tests/models/golden_vectors.rs`
(`test_golden_vectors_wavenet_lite`, `test_golden_vectors_v2_wavenet_lite`) is conditioned
on the presence of the local model `EVH-5150-Lite.nam` inside the `models-nondist` directory.
This model is a community-real capture (CH=12, K=3, HEAD=6, 20 layers) and cannot be
redistributed under the project's Apache-2.0 license.

In a clean environment (e.g., third-party CI) where the `models-nondist` directory is absent
and only the `golden_wavenet_lite.bin` golden file is present, the test will **skip**
gracefully with an `eprintln!` message — preserving test honesty (no placebo gate) but
sacrificing coverage of the WaveNet Lite golden cross-reference.

To re-enable full WaveNet Lite golden coverage:

1. Place `EVH-5150-Lite.nam` in your local `tests/fixtures/models-nondist/` directory.

2. Regenerate golden vectors from the C++ reference:

   ```bash
   ./tests/fixtures/golden_gen_build.sh
   ```

3. Run the golden tests:

   ```bash
   cargo test --test models test_golden_vectors_wavenet_lite
   cargo test --test models test_golden_vectors_v2_wavenet_lite -- --ignored
   ```

##### Model Maintenance Tool: `utils/check-model.sh` (`examples/inspect_model.rs`)

`utils/check-model.sh` (backed by the `inspect_model` example) is the canonical tool for inspecting and managing model data (`.nam` and `.namb`). It classifies files by architecture, topology, gain staging, metadata, and engine compatibility status.

**Interactive mode** (colored terminal output):

```bash
utils/check-model.sh tests/fixtures/models-nondist/EVH-5150-Lite.nam
```

Outputs architecture, version, topology classification (`[STANDARD / SUPPORTED]` or `[CUSTOM / TARGET-RESEARCH]`), receptive field, loudness, dBu levels, and file SHA-256.

**(Re)generating the manifest** (machine-readable JSON):

```bash
utils/check-model.sh --manifest tests/fixtures/models-nondist/*.nam \
    > tests/fixtures/models-nondist/manifest.json
```

Regenerate whenever non-distributable models are added, removed, or updated. The `--manifest`
flag produces a clean JSON array suitable for automated consumption by the test suite.

**v2 multi-SR files** (`golden_<model_id>_v2_<sr>.bin`): Stress Signal v2 (5s, 5 categories), generated by `golden_gen_build.sh`. See table below for SR coverage per model.

| SR Coverage                                       | Models                                                                                                                                                                                                                                                                         |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| All 5 SRs (44.1/48/88.2/96/192k)                  | `wavenet_feather`, `wavenet_nano`, `wavenet_lite`, `wavenet_a1_standard`                                                                                                                                                                                                       |
| 4 SRs (44.1/48/88.2/96k, Excl. 192 kHz)           | `lstm_1x16`, `lstm_2x8` — recurrent drift > 18 dB SNR at 192 kHz over 960k samples; `skip_srs=192000`                                                                                                                                                                          |
| 48 kHz only (`48k_only`)                          | `wavenet_standard`, `lstm_official`, `wavenet_a2_full`, `wavenet_a2_lite`, `wavenet_official`, `wavenet_condition_dsp`, `wavenet_dyn_free`, `lstm_dyn_test`, `convnet_test`, `wavenet_a2_max`, `wavenet_app_evh`, `wavenet_boss_bd2`, `wavenet_slammin_marshall`, `a2_example` |
| Uncatalogued synthetic pending build (`48k_only`) | `lstm_1x10`, `lstm_2x24`, `lstm_3x8`, `convnet_nobn`, `convnet_relu`, `convnet_silu`, `linear_nobias`                                                                                                                                                                          |
| No v2 golden (`v2_scope=none`)                    | `a2_dynamic_gated_ch8`, `a2_dynamic_blended_ch3`, `wavenet_a2_film_full`, `wavenet_a2_film_lite`, `wavenet_a2_film_chaos_stress`, `wavenet_a2_film_input_mixin_pre`, `linear_fft_rf{320,2048,4096,8192}`, `wavenet_a1_secondary_act`, `wavenet_condition_lstm`                 |

> [!NOTE]
> `v2_scope=none` entries have **no committed v2 golden binary at all** — not just 48 kHz. This is intentional: the C++ `a2_fast` path rejects FiLM-conditioned models and falls back to the Eigen-based generic WaveNet engine, which does not consistently support multi-SR FiLM renderings. The dynamic engines' coverage is exercised via live C++ cross-validation (`cpp_parity.rs`) instead. Linear FFT and container models have `v2_scope=none` for analogous reasons. See the rationale comment in `golden_gen_build.sh` and `src/testing/catalog.rs::GOLDEN_GEN_CATALOG`, plus [cpp_parity_map.md](cpp_parity_map.md) §3.3.

**v2 files** (`golden_<model_id>_v2_<sr>.bin`): Multi-sample-rate goldens using Stress Signal v2 (5 seconds, multi-component, covering all 5 stimulus categories GA/FRG/P/BA/PA in a single file). Naming schema:

```text
golden_<model_id>_v2_<sr>.bin
```

Examples:

| Golden File                            | Model ID           | SR    |
| -------------------------------------- | ------------------ | ----- |
| `golden_wavenet_standard_v2_48000.bin` | `wavenet_standard` | 48000 |
| `golden_lstm_1x16_v2_88200.bin`        | `lstm_1x16`        | 88200 |
| `golden_wavenet_feather_v2_44100.bin`  | `wavenet_feather`  | 44100 |

**SR coverage varies per model:** Models with an explicit `sample_rate` field in their NAM JSON (WaveNet Standard, LSTM Official, A2-Full, A2-Lite) only generate at 48 kHz due to C++ render tool constraints. Models without `sample_rate` (e.g. WaveNet Feather, Nano, Lite, A1 Standard, LSTM 1×16/2×8) generate at all 5 supported rates (44100/48000/88200/96000/192000).

**Layer-2 soak tests:** The corresponding tests in `tests/models/golden_vectors.rs` are `#[ignore]` because the 5-second v2 signals are ~200× longer than v1 (240k–960k vs 2048 samples), making them impractical for debug-mode CI (~2 min per model). Run with `cargo test -- --include-ignored` for comprehensive multi-SR validation. The committed `.bin` files serve as reproducible C++ reference artifacts for offline/CI-scheduled validation.

**v1 files** (`golden_<model>.bin`): Single-stimulus goldens using Stress Signal v1 (2048 samples @ 48 kHz). Maintained for retro compatibility — v1 goldens use model-only naming without tone_id. See table below.

## Binary format (.golden.bin)

```text
[u32 num_samples LE]
[f32×N input samples LE]       — stress signal (v1: 2048 samples @ 48 kHz; v2: 5s × SR)
[f32×N expected output LE]     — output from NeuralAmpModelerCore (render tool)
```

## Stress Signal v1 (2048 samples @ 48 kHz ≈ 42.7 ms)

Replaces the 440 Hz sine wave with a deterministic multi-component signal:

| Behavior to test                       | Signal component                    |
| -------------------------------------- | ----------------------------------- |
| Frequency response (low → high)        | Chirp sweep 220 Hz → 3520 Hz        |
| Harmonic intermodulation (real guitar) | Low-E harmonics (82/165/330/659 Hz) |
| Transient response (note attack)       | Isolated impulse (+0.9) at 25%      |
| Amplitude dynamics                     | Attack–sustain–release envelope     |
| Near-silence / denormals behavior      | Fade-to-silence (release tail)      |

## Stress Signal v2 (5 seconds, multi-SR: 44.1k/48k/96k/192k)

Comprehensive multi-component signal with 6 segments:

| Segment | Time     | Component                          | Category        |
| ------- | -------- | ---------------------------------- | --------------- |
| GA-1    | 0.0–1.0s | Single note Low-E + bend + vibrato | Guitar Amp      |
| FRG-1   | 1.0–2.0s | Power chord E2+E3+B3 + ADSR        | Full Rig Guitar |
| P-1     | 2.0–2.5s | Palm-mute 16 hits @ 120 BPM        | Pedal/Transient |
| P-2     | 2.5–3.5s | Pinch harmonic train + saw sweep   | Pedal/Transient |
| BA-1    | 3.5–4.5s | Bass amp Low-A 55 Hz + 5 harmonics | Bass Amp        |
| PA-1    | 4.5–5.0s | Chord C-E-G ringing decay (exp)    | Post-Amp        |

## `tone_id` MUSHRA-Aligned Nomenclature

The `tone_id` naming scheme mirrors the category taxonomy of `a2-mushra-data` (the standardized MUSHRA dataset used by the `t3k-mushra` ecosystem). Each tone_id encodes the stimulus category + a variation index `N`, enabling precise cross-project comparison.

### `tone_id` ↔ `a2-mushra-data` Category Mapping

| `tone_id` | Stress v2 Segment | Time Range | Category (`a2-mushra-data`) | Description                                       |
| --------- | ----------------- | ---------- | --------------------------- | ------------------------------------------------- |
| `GA-N`    | GA-N              | 0.0–1.0s   | Guitar Amp                  | Single-note Low-E + bend + vibrato, variation `N` |
| `FRG-N`   | FRG-N             | 1.0–2.0s   | Full Rig Guitar             | Power chord E2+E3+B3 + ADSR, variation `N`        |
| `P-N`     | P-N               | 2.0–2.5s   | Pedal / Transient           | Palm-mute 16 hits @ 120 BPM, variation `N`        |
| `BA-N`    | BA-N              | 3.5–4.5s   | Bass Amp                    | Bass amp Low-A 55 Hz + 5 harmonics, variation `N` |
| `PA-N`    | PA-N              | 4.5–5.0s   | Post-Amp / Ringing Decay    | Chord C-E-G ringing decay (exp), variation `N`    |

**Reserved for future expansion:**

| `tone_id` | Category      | Description                |
| --------- | ------------- | -------------------------- |
| `FRB-N`   | Full Rig Bass | Full rig bass (multi-note) |
| `PB-N`    | Pedal Bass    | Bass pedal/transient       |

> **Canonical MUSHRA testing tool:** [`t3k-mushra`](https://github.com/tone-3000/t3k-mushra) (MIT license) — use for publishing MUSHRA ratings derived from these stimuli.

### Mapping Strategy

- **`N` (variation index):** Labeled as `1`, `2`, … to distinguish different signals within the same category (e.g., `P-1` for palm-mute, `P-2` for pinch harmonic train).
- **Backwards compatibility:** v1 goldens (`golden_<model>.bin`) use Stress Signal v1 (full-signal, single-stimulus) and are maintained as-is.
- **Cross-project alignment:** The `GA`/`FRG`/`P`/`BA`/`PA` prefixes match the category codes used in `a2-mushra-data` (`tone-3000/a2-mushra-data`), enabling direct mapping to MUSHRA categories in `t3k-mushra` tests.

## t3k-mushra Primitives (Ported, MIT-licensed)

The following audio primitives are ported from `t3k-mushra` (`github.com/tone-3000/t3k-mushra`, MIT license):

| Primitive                | Function                          | Source (TS)                 |
| ------------------------ | --------------------------------- | --------------------------- |
| `synth_tone`             | Pluck guitar 6-harmonic + vibrato | `generateSampleAudio.ts:18` |
| `low_pass_1pole`         | 1-pole IIR low-pass               | `generateSampleAudio.ts:37` |
| `soft_clip`              | Symmetric tanh saturation         | `generateSampleAudio.ts:58` |
| `add_noise`              | White noise via Mulberry32        | `generateSampleAudio.ts:50` |
| `apply_gain`             | Linear gain scaling               | `generateSampleAudio.ts:66` |
| `fnv1a32` + `Mulberry32` | Deterministic PRNG                | `internal/prng.ts:9`        |

Attribution: see `NOTICE.txt` and `src/testing/mushra.rs` header.

MUSHRA-compliant variants (from `generateSampleAudio.ts:132-139`):

```text
hidden-ref  → reference bit-identical
excellent   → reference + noise(0.001)
good        → lowpass(9 kHz) + noise(0.002)
fair        → lowpass(5 kHz) + softclip(drive=1.6)
poor        → lowpass(2.5 kHz) + gain(0.9) + noise(0.01)
anchor      → lowpass(3.5 kHz)  [MUSHRA anchor canônico]
```

## Precision Metrics (7+ metrics, single-pass fusion)

Each golden test reports multiple metrics computed in a single pass:

| Metric       | Formula                           | What it detects                            |
| ------------ | --------------------------------- | ------------------------------------------ |
| **MSE**      | `Σ(rᵢ - tᵢ)² / N`                 | Mean error (structural regressions)        |
| **MAE**      | `max \| rᵢ - tᵢ \|`               | Maximum peak absolute error                |
| **SNR**      | `10 · log₁₀(Σrᵢ² / Σ(rᵢ-tᵢ)²)`    | Signal-to-noise ratio (DSP interpretation) |
| **PSNR**     | `10 · log₁₀(peak² / MSE)`         | SNR normalized by peak                     |
| **Bits eq.** | `-0.5 · log₂(MSE / signal_power)` | Precision — how many correct float32 bits  |
| **ESR**      | `Σ(rᵢ-tᵢ)² / Σ rᵢ²`               | Error-to-Signal Ratio (perceptual)         |
| **LUFS**     | ITU-R BS.1770-4 simplified        | Loudness (diagnostic)                      |

ESR baselines from published data (`A2Esr.tsx:19-38`, t3k-mushra):

- A1-Standard median: 0.00623 (−22.1 dB)
- A2-Full median: 0.00334 (−24.8 dB)
- A2-Lite median: 0.00500 (−23.0 dB)

Nam-rs vs C++ parity target: ESR < 1e-3 (−30 dB conservative gate); actual expected < 1e-5.
See [perceptual_validation.md](perceptual_validation.md) for methodology.

## Parity Thresholds

Catalog / headline models (audited 2026-07-02 against `tests/common/validation.rs::topology_thresholds()`
— corrected this pass; the previous revision of this table had drifted from the current, much
tighter calibrated gates on every WaveNet catalog row and two of the three LSTM rows):

| Model                       | SNR threshold | ESR threshold | Measured (comment in `validation.rs`) |
| --------------------------- |:-------------:|:-------------:| ------------------------------------- |
| LSTM 1×3 (Official)         | ≥ 105.0 dB    | < 9.0e-11     | SNR=120.8 dB, ESR=8.30e-13            |
| LSTM 1×16                   | ≥ 93.0 dB     | < 1.5e-9      | SNR=108.5 dB, ESR=1.42e-11            |
| LSTM 2×8                    | ≥ 93.0 dB     | < 1.7e-9      | SNR=107.8 dB, ESR=1.67e-11            |
| WaveNet Feather (CH=8)      | ≥ 100.0 dB    | < 1.0e-10     | SNR=133.1 dB, ESR=1.74e-12            |
| WaveNet Standard (CH=16)    | ≥ 105.0 dB    | < 3.0e-11     | SNR=134.6 dB, ESR=4.99e-13            |
| WaveNet Nano (CH=4)         | ≥ 95.0 dB     | < 3.0e-10     | SNR=132.0 dB, ESR=3.46e-12            |
| WaveNet Lite (CH=12)        | ≥ 105.0 dB    | < 3.5e-11     | SNR=122.3 dB, ESR=5.84e-13            |
| WaveNet A1 Standard (CH=16) | ≥ 85.0 dB     | < 3.0e-9      | SNR=123.4 dB, ESR=6.62e-11            |
| A2-Lite (CH=3)              | ≥ 105.0 dB    | < 3.5e-11     | SNR=132.2 dB, ESR=6.08e-14            |
| A2-Full (CH=8)              | ≥ 105.0 dB    | < 3.0e-11     | SNR=129.5 dB, ESR=1.13e-13            |

> [!IMPORTANT]
> This table is an illustrative subset of the catalog SKUs, not the complete list. Every
> calibrated model — including `wavenet_condition_dsp`, `wavenet_a2_film_{full,lite}`,
> `a2_dynamic_{gated_ch8,blended_ch3}`, `wavenet_dyn_free`, `lstm_dyn_test`, `a2_example`, the
> non-distributable production captures, and the KB-A2-MAX fail-closed `wavenet_a2_max` arm
> (§4.4.3 / §7.1) — is calibrated identically via `topology_thresholds()` in `tests/common/validation.rs`,
> which is the single source of truth. Read that file directly for the full, current, enforced
> list rather than trusting a second hand-copied table — that is exactly how this table drifted
> stale in the first place. `tests/models/threshold_calibration.rs`'s meta-tests
> (`test_all_golden_models_have_calibrated_thresholds`,
> `test_all_calibrated_entries_have_measurement_comments`, `test_all_thresholds_anti_placebo`)
> continuously enforce that every entry in `validation.rs` stays measured, documented, and
> non-placebo — they do **not**, however, enforce that this table stays in sync with
> `validation.rs`; that remains a manual audit responsibility.
>
> WaveNet Lite (CH=12) was migrated from the synthetic `BossWN-lite.nam` (0.9 dB SNR)
> to the real community model `EVH-5150-Lite.nam` (≥ 105 dB SNR).
> See §Non-Distributable Model Management and `tests/common/validation.rs`.

### Principle: "Todo Golden Deve Poder Falhar" (Every Golden Must Be Able to Fail)

A golden test is a **gate** — it exists to catch regressions. Three patterns defeat this purpose:

| Placebo pattern            | Why it's not a gate                                                                                                                      |
|:-------------------------- |:---------------------------------------------------------------------------------------------------------------------------------------- |
| **Self-golden**            | Output validated against itself. Passes by definition, catches nothing.                                                                  |
| **Threshold neutralizado** | SNR ≤ 0 dB, ESR ≥ 1.0, or MSE ≥ 1e29 without rigid SNR+ESR compensation. Metrics that can never fire create a false sense of confidence. |
| **Fallback heurístico**    | Silent fallback to `topology_thresholds()` when no calibrated entry exists.                                                              |

**Meta-tests enforce this principle** in `tests/models/threshold_calibration.rs`:

| Meta-tests                                              | What it catches                                                                         |
|:------------------------------------------------------- |:--------------------------------------------------------------------------------------- |
| `test_all_golden_models_have_calibrated_thresholds`     | Models without explicit calibrated entry                                                |
| `test_all_calibrated_entries_have_measurement_comments` | Entries without `// Measured: SNR=..., ESR=...` provenance                              |
| `test_all_thresholds_anti_placebo`                      | Any single neutralized component: SNR ≤ 0, ESR ≥ 1, or MSE ≥ 1e29 without rigid SNR+ESR |

> [!IMPORTANT]
> **A2 Exception:** The A2 Full/Lite models intentionally use `mse_limit = 1e30` (MSE effectively disabled)
> because their ESR gates are ultra-strict (≤ 8e-8) and SNR gates are ≥ 70 dB. The anti-placebo test
> accepts `mse_limit ≥ 1e29` only when SNR ≥ 40 dB and ESR < 0.1 — ensuring the bypass is compensated
> by rigid remaining gates. A total neutralization (SNR ≤ 0 or ESR ≥ 1) would still fail.

## To regenerate (golden vectors)

See Repo-Local Third-Party Area for the pinned upstream commits and
a complete regeneration walkthrough. Quick commands:

```bash
# v1 goldens only (fast):
cargo run --release --bin gen_stress -- --version v1 --output tests/fixtures/stress_signal.wav

# Full regeneration (v1 + v2, multi-SR):
./tests/fixtures/golden_gen_build.sh
```

## Resampler Reference Fixtures

Resampler correctness test vectors are generated by `tests/fixtures/generate_resampler_reference.py`.

### Files

| File                               | Description                                                                          |
| ---------------------------------- | ------------------------------------------------------------------------------------ |
| `resampler_input_{rate}.f32`       | Multitone test signal (10 tones, log-spaced 100 Hz to 0.45×Nyquist), raw f32 LE mono |
| `resampler_ref_{from}_to_{to}.f32` | Reference output via ffmpeg libsoxr (precision=33 bits, Chebyshev passband)          |

### Rate Pairs

- 44100 → 48000
- 48000 → 44100
- 48000 → 96000
- 96000 → 48000

### Reference Engine

[libsoxr](https://sourceforge.net/projects/soxr/) 0.1.x (SoX Resampler library) via ffmpeg:

- Resampler: soxr
- Precision: 33 bits (~200 dB SNR theoretical)
- Chebyshev passband

### Validation Test

`src/dsp/resampler_test.rs:test_resampler_snr_against_reference` — Measures magnitude at each tone frequency via Goertzel algorithm and computes SNR against the reference. Currently guards at ≥20 dB; the threshold should be tightened toward the aspirational 120 dB as polyphase filter quality improves.

### To regenerate

```bash
python3 tests/fixtures/generate_resampler_reference.py
```

Prerequisites: `ffmpeg` with libsoxr support (`--enable-libsoxr`).

## f64 Reference Anchors

These anchors validate the Rust f64 oracle (`tests/parity/reference_oracle_f64.rs`) against an independent NumPy f64 reference, ensuring the oracle itself is correct (not circular). Generated by `tests/fixtures/scripts/validate_oracle_f64.py`.

### Files f64

| File                                                      | Model Family           | Description                                      |
| --------------------------------------------------------- | ---------------------- | ------------------------------------------------ |
| `f64_anchors/a2_lite_256_f64.bin`                         | A2 (CH=3)              | 256-sample f64 anchor, lite variant              |
| `f64_anchors/a2_max_256_f64.bin`                          | A2 (CH=4, cond=8)      | 256-sample f64 anchor, max variant               |
| `f64_anchors/convnet_256_f64.bin`                         | ConvNet (CH=8)         | 256-sample f64 anchor, 6 blocks                  |
| `f64_anchors/lstm_256_f64.bin`                            | LSTM (1 layer, H=3)    | 256-sample f64 anchor                            |
| `f64_anchors/sweep_256_48k.bin`                           | Sweep signal           | 256-sample @ 48 kHz chirp input                  |
| `f64_anchors/sweep_1024_48k.bin`                          | Sweep signal           | 1024-sample @ 48 kHz chirp input                 |
| `f64_anchors/wavenet_a2_film_full_256_f64.bin`            | A2+FiLM (CH=8)         | 256-sample f64 anchor, FiLM full variant         |
| `f64_anchors/wavenet_a2_film_input_mixin_pre_256_f64.bin` | A2+FiLM (CH=3, slot 2) | 256-sample f64 anchor, input_mixin_pre isolation |
| `f64_anchors/wavenet_a2_film_lite_256_f64.bin`            | A2+FiLM (CH=3)         | 256-sample f64 anchor, FiLM lite variant         |
| `f64_anchors/wavenet_official_256_f64.bin`                | WaveNet (CH=3, K=3)    | 256-sample f64 anchor, official free-geom        |

### Binary Format

```text
[f64×N input samples LE]
[f64×N output samples LE]
```

Input is a deterministic 256-sample chirp sweep signal at 48 kHz (extracted from stress signal v1). Output is the NumPy f64 reference engine forward pass.

### Validation Gate

`tests/parity/reference_oracle_f64.rs` loads each anchor, computes the Rust f64 oracle output, and asserts ESR(anchor vs Rust oracle) < 1e-12 for all model families. This proves the Rust oracle is a correct ground-truth reference before it is used to decompose the f32 production error floor (weight quantization, activation approximation, accumulation precision).

### Regenerate

```bash
python3 tests/fixtures/scripts/validate_oracle_f64.py \
    tests/fixtures/models/lstm.nam \
    tests/fixtures/f64_anchors/sweep_256_48k.bin \
    --architecture LSTM --output tests/fixtures/f64_anchors/lstm_256_f64.bin
```

Repeat for each architecture (WaveNet, A2, A2+FiLM, ConvNet). After any change to the Rust oracle or validation script, regenerate all anchors and confirm ESR < 1e-12 for all families.

Prerequisites: `cmake`, `g++` (or `clang++`, C++20), `cargo` (Rust), `git`.

> Python is no longer required — `gen_stress` and `wav_to_golden` replace the inline Python blocks.

These files are committed to the repository so that the Rust golden vector tests can run without needing to recompile C++. If the golden vectors do not exist, the tests **panic** with instructions to run `golden_gen_build.sh`.

## Generator Scripts

The following scripts produce fixture files tracked by the freshness manifest (`golden_gen_build.sh`). All are deterministic and reproducible.

| Script                                           | Outputs                                                                                                                                             | Prerequisites                                |
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `tests/fixtures/generate_a2_fixtures.py`         | `wavenet_a2_{full,lite,film_full,film_lite,film_chaos_stress,film_input_mixin_pre}.nam`, `a2_{example,dynamic_*}.nam`, `wavenet_condition_lstm.nam` | `python3`                                    |
| `tests/fixtures/generate_b1_2_fixtures.py`       | `convnet_test.nam`, `wavenet_dyn_free.nam`, `lstm_dyn_test.nam`                                                                                     | `python3`                                    |
| `tests/fixtures/generate_ebu_sequences.py`       | `ebu_3341_1_sine_m23.wav`, `ebu_3341_7_sine_m33.wav`, `ebu_3341_sine_m18.wav`, `ebu_3341_dyn_alternating.wav`                                       | `python3`                                    |
| `tests/fixtures/generate_resampler_reference.py` | `resampler_input_{rate}.f32`, `resampler_ref_{from}_to_{to}.f32`                                                                                    | `python3`, `ffmpeg` with libsoxr             |
| `tests/fixtures/scripts/gen_mrstft_golden.py`    | `mrstft_golden.bin`                                                                                                                                 | `python3`, `numpy`                           |
| `tests/fixtures/scripts/validate_oracle_f64.py`  | `f64_anchors/*.bin`                                                                                                                                 | `python3`, `numpy`, `cmake`, `g++`/`clang++` |
| `src/bin/gen_stress.rs`                          | `stress_signal.wav`, `stress_signal_v2_{sr}.wav` (Rust binary `gen_stress`)                                                                         | `cargo`                                      |
| `src/bin/wav_to_golden.rs`                       | `golden_*.bin` (conversion helper; called by `golden_gen_build.sh`)                                                                                 | `cargo`                                      |

> [!IMPORTANT]
> `generate_b1_2_fixtures.py` produces the ConvNet, WaveNetDyn, and LstmDyn `.nam` model files. It must be re-run if those model architectures change (new weight layouts, new activation functions, etc.). The corresponding golden `.bin` files are re-generated by `golden_gen_build.sh` using the updated models.

## Model Provenance

### `BossWN-lite.nam` — Obsolete Synthetic WaveNet Lite (CH=12)

- **Nature:** Synthetic fixture (weights auto-generated, not trained on real data).
- **Metadata:** Round values, no `sample_rate` field in the JSON.
- **Status:** **Obsolete.** Was an active golden test gate with
  a 0 dB SNR threshold (near-noise output). Replaced by the real community model
  `EVH-5150-Lite.nam` (non-distributable, ≥ 105 dB SNR).
  See `tests/common/validation.rs` and §Non-Distributable Model Management.

### `BossWN-standard.nam`, `BossWN-feather.nam`, `BossWN-nano.nam` — Community real (Boss Waza, trained)

Real NAM models trained by the Boss Waza Tube Amp Expander community. See
[cpp_parity_map.md](cpp_parity_map.md) for per-variant channel/layer counts.

### `BossLSTM-1x16.nam` & `BossLSTM-2x8.nam` — Community real (Boss Waza, trained)

- **Nature:** Real NAM models trained by the Boss Waza Tube Amp Expander community. Validam a arquitetura LSTM com pesos de amplificador reais (1 layer × H=16 e 2 layers × H=8).

- **Golden Fixtures:** `golden_lstm_1x16.bin` and `golden_lstm_2x8.bin`.

- **Provenance:** Generated from C++ `NeuralAmpModelerCore` render tool at pinned commit `9c7b185de346fe0725dea537bcee4bc38b5bb6d6` (v0.5.3, canonical).

- **Command used:**

  ```bash
  render tests/fixtures/models/BossLSTM-1x16.nam tests/fixtures/stress_signal.wav output.wav
  wav_to_golden --input output.wav --reference tests/fixtures/stress_signal.wav --output golden_lstm_1x16.bin
  ```

- **Validation Verdict:** The current committed fixtures are byte-identical to those newly rendered with commit `e49c93e` (SHA-256 match). They differ from `nam-rs_v2.0.0` only at floating-point precision levels (SNR > 120 dB) due to dynamic C++ compiler/build configurations in the original unpinned `v2.0.0` build.

### `lstm.nam`

- **Nature:** Official sample model from `sdatkinson/NeuralAmpModelerCore` (example models).

- **Golden Fixtures:** `golden_lstm_official.bin`.

- **Provenance:** Official model representing 1 layer, H=3. Rendered using the canonical C++ pinned commit `9c7b185` (v0.5.3).

- **Command used:**

  ```bash
  render tests/fixtures/models/lstm.nam tests/fixtures/stress_signal.wav output.wav
  wav_to_golden --input output.wav --reference tests/fixtures/stress_signal.wav --output golden_lstm_official.bin
  ```

### `wavenet_a2_full.nam` & `wavenet_a2_lite.nam` — **Synthetic, NOT official FiLM models**

> [!IMPORTANT]
> **Estes goldens A2 usam pesos sintéticos, NÃO pesos de modelo oficial.** O modelo A2 oficial
> `wavenet_a2_max.nam` é **known bug KB-A2-MAX** (fail-closed TR1.1; prod×C++ **SNR ≈ 0.23 dB**;
> [cpp_parity_map.md](cpp_parity_map.md) §4.4.3). Fixture + golden permanecem para investigação futura
> (unlock só `cfg(test)` / feature `testing` + `NAM_A2_MAX_UNLOCK=1`). O **fast-path** A2
> não suporta FiLM — FiLM é exercitado por `WaveNetA2Dyn` com fixtures sintéticas
> `wavenet_a2_film_full/lite.nam`. `slimmable_wavenet.nam` **carrega** — disclaimer:
> inference-only; sem claim de paridade multi-size NAMCore (NAMCore carece de API de slicing).
>
> **O que estes goldens validam:** paridade numérica Rust↔C++ do **fast-path** da arquitetura A2
> (23 camadas, K=6/15, LeakyReLU, head_scale=0.02). **O que NÃO validam:** timbres de amplificador
> reais ou fidelidade perceptual de modelos A2 treinados.
>
> Para detalhes do conformismo PM-05 com capturas reais de FiLM, ver §FiLM Fixtures abaixo.

- **Nature:** Synthetic fixtures generated by `tests/fixtures/generate_a2_fixtures.py` using the canonical A2 skeleton (23 layers, K=6/15, LeakyReLU, head_scale=0.02).

- **Amplitude regime:** Weights scaled per-channel (Full CH=8: weight=0.28, bias=0.065; Lite CH=3: weight=0.45, bias=0.09) to produce C++ output in the realistic audio regime (Full: peak≈0.15, LUFS≈−22.6; Lite: peak≈0.19, LUFS≈−20.0), replacing the previous near-silence regime (peak≈2e−3, LUFS≈−68). This ensures denormals/FTZ, saturation, and accumulation paths are exercised at meaningful levels.

- **Golden Fixtures:** `golden_wavenet_a2_full.bin`, `golden_wavenet_a2_lite.bin` — cross-reference Rust↔C++ rendered using the same canonical commit `9c7b185de346fe0725dea537bcee4bc38b5bb6d6` (v0.5.3).

- **SNR/ESR:** Full = 79.2 dB / 1.21e−8; Lite = 90.7 dB / 8.58e−10. Thresholds calibrated with ≥8 dB SNR margin and ~6–7× ESR multiplier.

- **Command used:**

  ```bash
  # Generate .nam models
  python3 tests/fixtures/generate_a2_fixtures.py

  # Render with C++ v0.5.3
  render tests/fixtures/models/wavenet_a2_full.nam tests/fixtures/stress_signal.wav full.wav
  render tests/fixtures/models/wavenet_a2_lite.nam tests/fixtures/stress_signal.wav lite.wav

  # Convert to golden
  wav_to_golden --input full.wav --reference tests/fixtures/stress_signal.wav --output tests/fixtures/golden_wavenet_a2_full.bin
  wav_to_golden --input lite.wav --reference tests/fixtures/stress_signal.wav --output tests/fixtures/golden_wavenet_a2_lite.bin
  ```

### `wavenet_a2_film_full.nam` & `wavenet_a2_film_lite.nam` — **FiLM Fixtures (PM-05 conformism)**

> [!NOTE]
> **Conformismo PM-05:** O motor `WaveNetA2Dyn` suporta FiLM nativamente. O modelo
> real `wavenet_a2_max.nam` é **KB-A2-MAX** (fail-closed; §4.4.3) — fixture/golden
> permanecem no repo para reopen futuro, não como gate de release. Fixtures sintéticas
> validam o motor FiLM. Ver [cpp_parity_map.md](cpp_parity_map.md) §4.4.3.

- **Nature:** Synthetic FiLM fixtures generated by `tests/fixtures/generate_a2_fixtures.py` using the canonical A2 skeleton (23 layers, K=6/15, LeakyReLU, head_scale=0.02) with FiLM post-modulation on `conv`, `input_mixin`, `activation`, and `layer1x1` keys (`condition_size=1`).

- **Engine:** Routed to `WaveNetA2Dyn` (dynamic engine with native FiLM support). The C++ `a2_fast.cpp` rejects FiLM and falls back to Eigen-based generic WaveNet — the golden cross-reference validates *cross-engine equivalence*, not bit-exact parity.

- **SNR/ESR:** FiLM-Full (CH=8) = 36.0 dB / 2.50e-4; FiLM-Lite (CH=3) = 18.1 dB / 1.54e-2. Thresholds calibrated per `tests/common/validation.rs` with RF1 flag (FiLM vs generic WaveNet divergence capped and tracked).

- **Golden Fixtures:** `golden_wavenet_a2_film_full.bin`, `golden_wavenet_a2_film_lite.bin` — cross-reference Rust↔C++ rendered at canonical commit `9c7b185de346fe0725dea537bcee4bc38b5bb6d6` (v0.5.3).

- **Command used:**

  ```bash
  # Generate .nam models
  python3 tests/fixtures/generate_a2_fixtures.py

  # Render FiLM-Full with C++ v0.5.3 (C++ a2_fast.cpp rejects FiLM → falls back to generic)
  render tests/fixtures/models/wavenet_a2_film_full.nam tests/fixtures/stress_signal.wav film_full.wav
  render tests/fixtures/models/wavenet_a2_film_lite.nam tests/fixtures/stress_signal.wav film_lite.wav

  # Convert to golden
  wav_to_golden --input film_full.wav --reference tests/fixtures/stress_signal.wav --output tests/fixtures/golden_wavenet_a2_film_full.bin
  wav_to_golden --input film_lite.wav --reference tests/fixtures/stress_signal.wav --output tests/fixtures/golden_wavenet_a2_film_lite.bin
  ```

### `keras_unsupported.json` — Unsupported Legacy Keras/H5 Format Mock

- **Nature:** Synthetic/Mock JSON representation of a legacy Keras-format model.
- **Provenance:** Replaces the original third-party model `tw40_blues_deluxe_deerinkstudios.json` (Fender Blues Deluxe capture by Deer Ink Studios) which was distributed under the **Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)** license.
- **Legal Risk Mitigation:** To avoid licensing conflicts with the main Apache-2.0 codebase (specifically regarding the Non-Commercial restriction, which prevents packaging or commercial use of the repository), the 160 KB real weights have been deleted. The mock file preserves only the key-value dictionary structure (`"in_shape"`, `"layers"`) to test that the model loader/dispatcher gracefully rejects the legacy format (by returning an error due to the missing `"architecture"` field) without hosting any copyrighted or restricted weights.

### `wavenet_a2_film_chaos_stress.nam` — **Numerical Stress Fixture (Pre-Fix Snapshot)**

- **Nature:** Synthetic — preserved snapshot of the **original** `wavenet_a2_film_lite.nam` from commit `b96e4c7d` (2026-06-21, blob `e107e48f`), before `generate_a2_fixtures.py` was updated to fix FiLM scale bias (commit `3faa9345`) and FiLM slot activation keys (commits `445b5cb1`, `ca8c22ee`). Preserved as `wavenet_a2_film_chaos_stress.nam` in commit `743710da`.

- **Architecture:** WaveNet A2 (CH=3, bottleneck=3, condition_size=1, 23 layers), FiLM post-modulation on all 4 slots: `conv`, `input_mixin`, `activation`, `layer1x1`. Head_scale=0.02.

- **Why "chaos stress":** The pre-fix generator used FiLM scale biases that were pure noise (NOT `1.0 + noise`), producing more chaotic output than post-fix models. This makes it ideal for detecting numerical regressions in FiLM routing, reordering, or dimension dispatch.

- **Golden Fixture:** `golden_wavenet_a2_film_chaos_stress.bin` — v1 only (48 kHz), `v2_scope=none`. C++ `a2_fast.cpp` rejects FiLM unconditionally; falls back to Eigen-based generic WaveNet.

- **Tests:** `test_golden_vectors_wavenet_a2_film_chaos_stress` (golden_vectors.rs), `live_cross_validation_wavenet_a2_film_chaos_stress` (cpp_parity.rs), f64 oracle family "A2FiLMChaos" (reference_oracle_f64.rs).

- **SNR/ESR:** Calibrated thresholds: SNR≥120 dB, ESR<1.0e-12 (validation.rs).

### `wavenet_a2_film_input_mixin_pre.nam` — **Bug C1 Regression Fixture (Isolated FiLM Slot)**

- **Nature:** Synthetic — isolated FiLM regression fixture generated by `tests/fixtures/generate_a2_fixtures.py` (lines 509–523), introduced in commit `3d921af4`. Seed 145 (42+3+100).

- **Architecture:** WaveNet A2 (CH=3, bottleneck=3, condition_size=1, 23 layers), **single FiLM slot active**: `input_mixin_pre_film` (slot 2) only.

- **Why isolated:** Bug C1 discovered that `input_mixin_pre_film` requires special channel dimensions: `FiLM(cond_size→cond_size)` instead of `FiLM(cond_size→ch)`. The per-slot generator injects `film_ch=1` for slots 2 and 7. This fixture validates the fix in isolation.

- **Golden Fixture:** `golden_wavenet_a2_film_input_mixin_pre.bin` — v1 only, `v2_scope=none`.

- **Tests:** `test_golden_vectors_wavenet_a2_film_input_mixin_pre` (golden_vectors.rs), `live_cross_validation_wavenet_a2_film_input_mixin_pre` (cpp_parity.rs), f64 oracle anchor `wavenet_a2_film_input_mixin_pre_256_f64.bin`.

- **SNR/ESR:** Calibrated thresholds: SNR≥120 dB, ESR<1.0e-11 (validation.rs).

### `wavenet_condition_lstm.nam` — **WaveNet + LSTM Condition DSP (C++ Golden Blocked)**

- **Nature:** Synthetic — hybrid fixture generated by `tests/fixtures/generate_a2_fixtures.py` (lines 526–648), introduced in commit `030f1cb6`.

- **Architecture:** Outer WaveNet (2 arrays, CH=3→2, K=3) with embedded LSTM `condition_dsp` sub-model (1 layer, hidden_size=3, input_size=1). 217 total weights (147 WaveNet + 70 LSTM).

- **C++ golden status:** **BLOCKED.** The NeuralAmpModelerCore C++ render tool has a known limitation where the LSTM `condition_dsp` sub-model mismatches input channels (`input_size=1` vs `hidden_size=3`). The registry entry in `src/testing/catalog.rs::GOLDEN_GEN_CATALOG` has `skip_reason` and the golden binary cannot be generated.

- **Golden Fixture:** `golden_wavenet_condition_lstm.bin` — **not generated** (skip_reason). v1 golden test skipped gracefully when the golden file is absent.

- **Tests:** `test_wavenet_condition_lstm_loads_and_runs` (smoke test), `test_policy_reject_condition_lstm` (SKIP when golden absent), `live_cross_validation_wavenet_condition_lstm` (cpp_parity.rs).

- **SNR/ESR:** Calibrated thresholds: SNR≥70 dB, ESR<1.0e-8 (validation.rs — conservative floor).

### `a2_example.nam` — **SlimmableContainer A2 Example**

- **Nature:** Synthetic — SlimmableContainer bundling A2 submodels (CH=3→6), generated by `tests/fixtures/generate_a2_fixtures.py`.

- **Golden Fixture:** `golden_a2_example.bin` (v1) and `golden_a2_example_v2_48000.bin` (v2@48k, `v2_scope=48k_only` in `src/testing/catalog.rs`).

- **Purpose:** Validates SlimmableContainer routing and dispatch for A2 dynamic paths.

- **Tests:** Golden vectors v1, live cross-validation (cpp_parity.rs).

### `convnet_test.nam` — **ConvNet Topology Parity**

- **Nature:** Synthetic — ConvNet (CH=8, 6 blocks), simple weights defined for testing.

- **Golden Fixture:** `golden_convnet_test.bin` and `golden_convnet_test_v2_48000.bin`.

- **Purpose:** Validates ConvNet architecture parity with C++ reference. v2_scope=48k_only.

- **Tests:** Golden vectors v1/v2.

### `lstm_dyn_test.nam` — **LSTM Dynamic Path**

- **Nature:** Synthetic — LSTM-Dyn (1 layer, H=7), simple weights defined for testing.

- **Golden Fixture:** `golden_lstm_dyn_test.bin` and `golden_lstm_dyn_test_v2_48000.bin`.

- **Purpose:** Validates LSTM dynamic path with free geometry and variable hidden dimensions.

- **Tests:** Golden vectors v1/v2, live cross-validation (cpp_parity.rs).

### `wavenet_dyn_free.nam` — **WaveNet Free-Shape Dynamic Path**

- **Nature:** Synthetic — WaveNetDyn (CH=7/4, free geometry), simple weights defined for testing.

- **Golden Fixture:** `golden_wavenet_dyn_free.bin` and `golden_wavenet_dyn_free_v2_48000.bin`.

- **Purpose:** Validates WaveNet dynamic path with free-shape geometry dispatch. v2_scope=48k_only.

- **Tests:** Golden vectors v1/v2, live cross-validation (cpp_parity.rs).

## Two Layers of Validation

### Layer 1 — Pre-committed goldens (fast, `cargo test`)

Tests in `tests/models/nam_infer_test.rs` load the `.golden.bin` files and compare against Rust inference. Runs on every `cargo test` without C++.

### Layer 2 — Live cross-validation (slow, `utils/tests-long.sh`)

`#[ignore]` tests in `tests/parity/cpp_parity.rs` compile the `render` tool from NeuralAmpModelerCore on-demand and compare C++ vs Rust live. Detects drift if NAMCore is updated and the pre-committed goldens become stale.

### Layer 0 — The Generation Pipeline Itself (audited, gaps tracked)

Both layers above assume `golden_gen_build.sh` faithfully reproduces every golden a test
needs, on a rarely-executed, mostly-unsupervised run. A dedicated audit of that script
(triggered by the `revisor-auditor` skill, Compliance and Parity Auditor role) found and
tracked several concrete gaps:

- **Catalog coverage** — the non-distributable models (`APP-EVH`, `Boss BD-2`, `MARSHALL J45`)
  are silently skipped when the `models-nondist` symlink is absent; coverage is partial in clean-clone environments.
- **`pipefail`/`errexit` interaction** — **resolved** in the current build script via
  `|| render_status=$?` capture + `continue` (lines 396–403). Individual model render failures
  skip that model and proceed, not abort the whole run.
- **`NeuralAmpModelerPlugin` vendor sync** is handled by `utils/setup-third-party.sh` (alongside Core).

None of these gaps invalidate the *already-committed* golden `.bin` files — they affect only the ability to safely and fully *regenerate* the catalog from scratch in constrained environments.

## Technical Decision: Cross-Reference is NOT Bit-Identical (ADR-002)

> **Decision:** The golden vectors validate *functional* parity (MSE + SNR + PSNR + bits within calibrated thresholds) against NeuralAmpModelerCore C++, **not** *bit-for-bit* parity.
>
> **Consequence:** NAM-rs produces audio perceptually equivalent to C++, but with measurable numerical differences. These differences are inaudible in any 16-bit or higher audio pipeline.
>
> **LSTM divergence:** The LSTM goldens show relatively low SNR
> (1×16 ≈ 19.8 dB, 2×8 ≈ 25.7 dB, official ≈ 29.7 dB) vs WaveNet's ≥ 100 dB (see the corrected
> WaveNet divergence note below — the previous revision of this note said "vs WaveNet 52–68 dB",
> which was stale by the same ~2 orders of magnitude). The hypothesis that
> FastMath Padé [5,4] tanh is the cause was **refuted**: using exact `f32::tanh` (libm) yields
> identical SNR (Δ ≈ 0.0 dB). The actual bottleneck is likely BF16 weight quantization or GEMV
> rounding — **not** the activation approximations. FastMath is adequate for LSTM.
>
> **WaveNet divergence — corrected 2026-07-02, the previous revision of this note was
> stale by ~2 orders of magnitude:** WaveNet's `Standard`-precision `tanh`/`sigmoid`
> approximations are a small, bounded, and *intentional* divergence from C++'s exact math (see
> ADR-001, [architecture.md](architecture.md) §2, and [cpp_parity_map.md](cpp_parity_map.md) §2.5/§5) — they do **not**
> degrade SNR anywhere near what an earlier draft of this note claimed. Current measured SNR
> against the C++ golden is **≥ 100 dB across every WaveNet catalog SKU** (Standard 134.6 dB,
> Feather 133.1 dB, Nano 132.0 dB, Lite 122.3 dB, A1 Standard 123.4 dB — see the Parity Thresholds
> table above, sourced from `tests/common/validation.rs`), not the "~10 dB" figure this note used
> to state. Do not resurrect that figure without a fresh, reproducible measurement.

## EBU Tech 3341 / R 128 Compliance Sequences

Four WAV files generated by `tests/fixtures/generate_ebu_sequences.py` for validating the ITU-R BS.1770-4 integrated loudness (LUFS) implementation in `src/testing/perceptual/lufs.rs`. Used exclusively by `tests/models/ebu_lufs_compliance.rs`.

| File                           | Signal                              | Target (LUFS) | Tolerance |
| ------------------------------ | ----------------------------------- |:-------------:|:---------:|
| `ebu_3341_1_sine_m23.wav`      | 1 kHz mono sine, 5 s                | −23.000       | ± 0.1 LU  |
| `ebu_3341_7_sine_m33.wav`      | 1 kHz mono sine, 5 s                | −33.000       | ± 0.1 LU  |
| `ebu_3341_sine_m18.wav`        | 1 kHz mono sine, 5 s                | −18.000       | ± 0.1 LU  |
| `ebu_3341_dyn_alternating.wav` | Alternating −20/−46 dBFS 1 kHz, 5 s | −23.272       | ± 0.2 LU  |

All files: 48 kHz, mono, IEEE float32 WAV. Generated deterministically — amplitudes are binary-searched to produce the exact K-weighted integrated LUFS targets. The dynamic alternating signal exercises the 2-pass BS.1770-4 gate (loud→quiet section). These match EBU Tech 3341 signals 1 and 7 and add two supplemental levels.

### Regenerate EBU Tech 3341 / R 128 Compliance Sequences

```bash
python3 tests/fixtures/generate_ebu_sequences.py
```

## MR-STFT Golden (`mrstft_golden.bin`)

Validates the Multi-Resolution STFT loss computation in `src/testing/perceptual/mod.rs` (`compute_mr_stft`). Generated by `tests/fixtures/scripts/gen_mrstft_golden.py` using a deterministic NumPy reference.

### Binary format

```text
[f64 MR-STFT loss]  (8 bytes, little-endian)
[u32 num_samples]   (4 bytes)
[f32 × N ref]       (N × 4 bytes)
[f32 × N test]      (N × 4 bytes)
```

- **Seed:** 42 (NumPy `RandomState`); **N** = 4800 samples.
- **Windows:** [256, 1024, 4096]; **Hop:** window/4; **Weights:** [0.1, 0.3, 0.5].
- **Floor:** per-frame relative −80 dB below spectral peak (fallback `eps_abs = 1e-8`).
- **Test consumer:** `tests/parity/parity_primitives.rs` (L1+L2 loss, single tolerance gate).

### Regenerate MR-STFT Golden

```bash
python3 tests/fixtures/scripts/gen_mrstft_golden.py
```

Prerequisites: `numpy`.

## Spectral Fidelity Baseline (`spectral_fidelity_baseline.json`)

Machine-readable baseline for `tests/models/spectral_fidelity.rs`. Stores per-model, per-metric spectral fidelity thresholds (multi-resolution STFT analysis).

- **Format:** JSON array of objects, one per catalog model.
- **Generation:** `cargo test --test spectral_fidelity generate_spectral_fidelity_baseline -- --ignored --nocapture`
- **Consumer:** `tests/models/spectral_fidelity.rs` — loads the committed baseline and asserts every current inference run stays within tolerance. Regenerate and re-commit whenever model weights, the DSP engine, or the MR-STFT implementation change.
- **Tracked by:** `golden_gen_build.sh` freshness manifest (SHA-256 gate).

## Cabsim Golden Fixtures (Synthetic IRs)

The IR Cabsim convolution engine (`src/dsp/cabsim/conv.rs`) is validated against **direct convolution** (naive O(N²) reference), which serves as the mathematically-rigorous golden baseline. No C++ golden files are required — the reference is computed inline from the same synthetic IR and input signal processed by the UPOLS engine.

### Test Scenarios

| Test                              | Seed   | IR len | Signal len | Block | ESR threshold | Status      |
| --------------------------------- | ------ | ------ | ---------- | ----- |:-------------:| ----------- |
| `test_cabsim_golden_short`        | 42     | 64     | 256        | 64    | < 1e-5        | Active      |
| `test_cabsim_golden_medium`       | 137    | 512    | 1024       | 64    | < 1e-5        | Active      |
| `test_cabsim_golden_long`         | 31337  | 8192   | 16384      | 64    | < 1e-5        | `#[ignore]` |
| `test_cabsim_golden_stress`       | 999983 | 32768  | 65536      | 256   | < 1e-5        | `#[ignore]` |
| `test_cabsim_bitwise_determinism` | 777    | 128    | 512        | 64    | < 1e-10       | Active      |
| `test_cabsim_passthrough_golden`  | 42     | empty  | 256        | 64    | < 1e-10       | Active      |

### IR Generation

All IRs are synthesized deterministically using a **PCG PRNG** (`SimplePcg`) with fixed seeds. The generation formula is:

```text
IR[n] = sin(2π · freq · t) · exp(−decay · t) + 0.02 · rng.next_f32_signed()
```

| Scenario    | Seed   | freq (Hz) | decay | IR length    |
| ----------- | ------ | --------- | ----- | ------------ |
| Short       | 42     | 600       | 12.0  | 64           |
| Medium      | 137    | 350       | 6.0   | 512          |
| Long        | 31337  | 200       | 2.0   | 8192         |
| Stress      | 999983 | 150       | 1.5   | 32768        |
| Bitwise     | 777    | 440       | 8.0   | 128          |
| Passthrough | 42     | —         | —     | 0 (empty IR) |

### Input Signal

The test signal is a deterministic mixed-sine + noise signal at 48 kHz:

```text
s[n] = 0.7·sin(2π·220·t) + 0.35·sin(2π·554.37·t) + 0.18·sin(2π·880·t) + 0.05·rng.next_f32_signed()
```

### Validation Approach

Each test:

1. Creates a `ConvEngine` with the synthetic IR and configured block size.
2. Processes the input signal through the UPOLS (Uniform Partitioned Overlap-Save) engine.
3. Computes the direct convolution reference (O(N²)) from the same IR and input.
4. Compares UPOLS output against the reference using **ESR < 1e-5** (Error-to-Signal Ratio) and a per-scenario **max sample diff** threshold.

The direct convolution reference eliminates the need for external golden vectors — it is a mathematically-rigorous, self-contained oracle.

### Test File

Source: `tests/models/cabsim_golden.rs` — 6 golden parity tests covering short, medium, long, stress, bitwise determinism, and empty-IR passthrough scenarios.

> **C++ Cross-Validation:** C++ cross-validation golden files (`golden_cabsim_cpp_*.bin`) are generated from `AudioDSPTools/dsp/ImpulseResponse.h` (NeuralAmpModelerPlugin submodule) using a dedicated render tool (`tests/fixtures/render_ir.cpp`), enabling external cross-reference verification against the C++ `dsp::ImpulseResponse` implementation. Parity is validated in `tests/parity/cabsim_cpp_parity.rs` (ESR < 1e-13).

## `.temp_live/` (Auto-Cleaned Per Run)

The `tests/fixtures/.temp_live/` directory holds live-generated WAV artifacts from `tests/parity/cpp_parity.rs` during the long-duration audit suite. It is **automatically cleaned** by `utils/tests-long.sh` before each run and is **never committed** (listed in `.gitignore`). If you run `cargo test --ignored --test parity` outside the script, stale WAVs may accumulate — delete them with `rm -rf tests/fixtures/.temp_live/`.