test(e2e-chain): orchestrator + end-to-end fixes (Task 7)

Full-chain orchestrator (run_chain_e2e.sh) now runs the starter set green
(3 pass). Fixes found bringing the chain up end-to-end:

- client: gorilla/websocket cannot survive a read deadline (next ReadMessage
  panics "repeated read on failed connection"); replace the poll-with-deadline
  loop with a background reader goroutine + mutex-guarded state.
- orchestrator: guard env.sh's unbound LD_LIBRARY_PATH under set -u.
- scenarios/gen_data: centralize NUM_ROWS/ROW_DT and enforce sine freq to be a
  multiple of the buffer fundamental (LOOP_HZ=5 Hz) so the looped FileReader
  buffer is a seamless waveform; align starter freqs (5/5/10 Hz).
- gen_cfg: FileReader allows exactly one consuming Function, so route tapped
  (oracle=fed/both) sources through the DDB (ReaderGAM->DDB, then StreamGAM and
  TapGAM both read DDB) instead of a second FileReader consumer.
- validate_waveform: fidelity gates correctness (bit-exact / within one quant
  level); sine shape becomes a gross frequency-sanity gate (corr>=0.5) plus a
  tracked corr/nRMSE quality metric, since per-sample wall-clock calibration
  (Phase-A) and FULL_ARRAY packed timestamps (Phase-A4) are still pending.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino Ferrari
2026-06-25 13:11:35 +02:00
parent d4fa84d482
commit f256a4def5
6 changed files with 400 additions and 40 deletions
+4 -2
View File
@@ -45,8 +45,10 @@ import numpy as np
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import scenarios as S # noqa: E402 (TYPE_CODES / NP_DTYPE / SCENARIOS)
NUM_ROWS = 200 # producer cycles written to the FileReader input
ROW_DT = 1.0e-3 # seconds per producer cycle (row); 1 kHz producer
# Buffer geometry lives in scenarios.py so the seamless-loop constraint
# (validate_scenario) and the data layout cannot drift apart.
NUM_ROWS = S.NUM_ROWS # producer cycles written to the FileReader input
ROW_DT = S.ROW_DT # seconds per producer cycle (row); 1 kHz producer
def _sample_dt(sig):