Fix 5 confirmed code review issues TDD-style, committing between each one.
- Extract duplicated
requireNumericArg/registerNumericBuiltinsto shared module - Clean up
buildContextdeep copy (remove dead function refs) - Remove duplicated proximity corrections from interpreter
- Add proper error routing for realize failures (issue 6)
- Extract PLSTEP threshold constant (issue 5)
- Status: DONE
- Commit: 121ca74
- New shared module:
src/semantics/register-builtins.ts - Tests: 9/9 passed in
test/register-builtins.test.ts
- Status: DONE
- Commit: 918db5d
- Removed dead function refs from staticContext (standardFunctions, proximity)
- Replaced JSON.parse/stringify with structuredClone
- Extracted buildStaticContext/buildFrameContext as exported testable functions
- Tests: 5/5 passed in
test/build-context-cleanup.test.ts
- Status: DONE
- Commit: 875ba49
- Removed 8 hardcoded proximity lines from buildContext
- KEY FINDING: proximity() was never registered with CEL evaluator! Semantics rules were silently failing, hardcoded values surviving by accident. Fixed by registering proximity in register-builtins.ts.
- Tests: 5/5 passed in
test/proximity-from-semantics.test.ts
- Status: DONE
- Commit: 6e7a777
- evaluate() errors now route through runtime's log() callback
- applyValues() detects bindings affected by failed realize rules, logs summary
- KEY FINDING: the ?? fallthrough in resolveParamValue is effectively dead code (topological evaluator seeds result.values from context.params first)
- Tests: 3/3 passed in
test/realize-error-routing.test.ts
- Status: DONE
- Commit: 70cdb41
- Added plstepThreshold: 49 as semantics constant with PARCOE.FOR citation
- graph.yaml edge-detectors now use { bind: plstepThreshold }
- Interpreter reads threshold from semantics with fallback
- Tests: 5/5 passed in
test/plstep-threshold-consistency.test.ts
Scout report: reports/scout-architecture-review-issues.md
- Status: DONE
- Commit: eff9138
- Moved prevAF/prevAH updates outside if(telemetryHandler)
- Tests: 4/4 passed in
test/klatt-interpreter.test.ts
- Status: DONE
- Commit: faad976
- Pure reorder, no logic changes. 81-line gap closed.
- Status: DONE
- Commit: 23b0ed5
- Replaced 'port' in node with typeof AudioWorkletNode !== 'undefined' && node instanceof AudioWorkletNode
- Environment guard needed because vitest runs in Node.js (no AudioWorkletNode global)
- Tests: 6/6 passed in
test/audio-node-guards.test.ts
- Status: DONE
- Commit: 7acbcca
- Timeout now rejects, handler cleaned up on timeout
- awaitWorkletReady catches rejection, logs warning, continues
- Tests: 4/4 passed in
test/klatt-runtime-worklet.test.ts
- Status: DONE
- Commit: e64d222
- Replaced
as anywithas unknown as Record<string, unknown> - Added warning log to cancelScheduledValues catch block
- Status: DONE
- Commit: be7730c
- Added validation in createKlattRuntime that throws on { expr: "..." } param specs
- Error message directs users to use realize rules in semantics.yaml
- Tests: 3/3 passed in
test/graph-validation.test.ts
- Status: DONE
- Commit: 047ea2d
- Replaced 3 separate lists with single CategorizedBinding[] with 'realized' | 'ramp' | 'passthrough'
- compileSchedule uses switch(binding.type) instead of 3 separate loops
- Net ~25 lines removed
- Tests: 6/6 passed in
test/klatt-interpreter.test.ts
- Status: DONE
- Commit: 895013b
- Removed fallback chain, graph.outputs is now authoritative
- Missing/empty/invalid outputs throws clear error
- Tests: 7/7 passed in
test/graph-validation.test.ts
- Status: DONE
- Commit: 9cf00ee
- Created
src/audio-param-utils.tswith shared getAudioParam/applyParamValue - Removed duplicated implementations from interpreter and runtime
- Tests: 11/11 passed in
test/audio-param-access.test.ts
- Status: DONE
- Commit: dca097c
- Created
src/semantics/evaluator-factory.tswith createConfiguredEvaluator() - Both interpreter and runtime now use the factory
- Tests: 4/4 passed in
test/evaluator-factory.test.ts
- Status: DONE
- Commit: 2ba11bb
- Comment-only change explaining why structuredClone is needed (cel-js context mutation)
- No behavioral change
- Status: DONE
- Commit: f635b17
- Unreachable code removed (load-time validation makes it dead)
- Status: DONE
- Commit: 82358f5
- plstepBurstOffsetDb: 75 added to semantics constants
- plstepAmplitude realize rule updated to reference constant
- Interpreter reads from semantics with fallback
- Tests: 7/7 in plstep-threshold-consistency
- Status: DONE
- Commit: 8e4f68d
- Removed dead ?? fallback (type is number, all callers pass concrete value)
- Status: DONE
- Commit: 39d06e9
- One-word change, never reassigned
- Status: DONE
- Commit: 4f18600
- Exported EvaluationError interface from types.ts
- Runtime duck-typing removed, uses typed access
- Interpreter already had typed access via inference
- Status: DONE
- Commit: b30e396
- BindingInfo → BindingSpec (metadata level)
- Binding → ResolvedBinding (live AudioParam handle level)
- BindingList → ResolvedBindingList
- Updated across runtime, interpreter, and tests