fix(h3d): Toby r3 — restore _CV_KEY_TIME to screen.js, fix test-16 regex vacuity

F1 (HIGH): _CV_KEY_TIME_MUL / _CV_KEY_TIME_SLOT were moved into the
renderer.js closure at 06e4fe3 but _encodeChordVerdictKey (defined in
screen.js IIFE scope, DI'd as fn-ref) still reads them from screen.js
scope → ReferenceError on first chord-template chart frame. Fix:
restore both consts to screen.js (declared before _encodeChordVerdictKey),
add them as DI shorthands in renderer.js, remove closure copies. Single
source of truth — no dual definitions.

Kill test 23: asserts _CV_KEY_TIME_MUL / _SLOT are declared in screen.js
before _encodeChordVerdictKey. RED at 06e4fe3, GREEN here.

F2 (MED): test #16 createRenderer regex /const \{ update \} = .../ did not
match after F1-prewarm added _prewarmStatic/_prewarmChart to the destructure
→ vacuous pass (wiring block never extracted, 0 shorthands checked). Fix:
updated regex to /const \{[^}]*update[^}]*\} = createRenderer\({...}\)/.
Added anti-vacuity floor: assert extracted Set.size >= 150 so a future
regex break fails loudly.

P3 (LOW): added ⚠ comment on smoke tests 23-25 documenting the new Function
sloppy-mode hole and naming eslint no-undef as the compensating layer.

DI count: 313 → 315 (+2 shorthands for _CV_KEY_TIME_MUL / _CV_KEY_TIME_SLOT).
Suite: 1406/1407 (test 46 pre-existing).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014uZ169yfoFYArXz962g7KW
This commit is contained in:
byrongamatos
2026-09-06 01:16:13 +02:00
co-authored by Claude Sonnet 4.6
parent 06e4fe335a
commit a55dca7893
3 changed files with 58 additions and 8 deletions
+5
View File
@@ -3570,6 +3570,10 @@ import { createRenderer } from './src/renderer.js'; // h3d-carve-15
// ``time * 1e4`` keeps a 0.1 ms resolution — more than enough
// to disambiguate distinct chord onsets — and stays under the
// safe-integer limit for any realistic song length.
// Key-encoding constants — also DI'd to renderer.js as shorthands so the
// pruning pass in update() shares the same resolution without a dual definition.
const _CV_KEY_TIME_MUL = 1e4;
const _CV_KEY_TIME_SLOT = 1e6;
function _encodeChordVerdictKey(ch) {
const tSlot = Math.round(ch.t * _CV_KEY_TIME_MUL) * _CV_KEY_TIME_SLOT;
const idSlot = ch.id != null ? ((Number(ch.id) | 0) + 1) : 0;
@@ -6975,6 +6979,7 @@ import { createRenderer } from './src/renderer.js'; // h3d-carve-15
FRET_WIRE_HIT_OP, FRET_WIRE_IDLE_HEX, FRET_WIRE_IDLE_OP,
HWY_LANE_STRIPE_OP_BASE, HWY_LANE_STRIPE_OP_INT, HWY_LANE_TIME_SLICES,
NEXT_ON_STRING_T_EPS, _ND_UNMATCHED_LATCH_AFTER, VENUE_LANE_OP_BOOST,
_CV_KEY_TIME_MUL, _CV_KEY_TIME_SLOT,
MAX_RENDER_STRINGS,
// ── Category C — fn-refs / let-vars ────────────────────────────────
activePalette, anchorLaneBoundsAt, anchorPlayedFretSpanAt,
+4 -2
View File
@@ -107,6 +107,7 @@ export function createRenderer({
FRET_WIRE_HIT_OP, FRET_WIRE_IDLE_HEX, FRET_WIRE_IDLE_OP,
HWY_LANE_STRIPE_OP_BASE, HWY_LANE_STRIPE_OP_INT, HWY_LANE_TIME_SLICES,
NEXT_ON_STRING_T_EPS, _ND_UNMATCHED_LATCH_AFTER, VENUE_LANE_OP_BOOST,
_CV_KEY_TIME_MUL, _CV_KEY_TIME_SLOT,
MAX_RENDER_STRINGS,
// ── Category C — fn-refs / let-vars ──────────────────────────────────
activePalette, anchorLaneBoundsAt, anchorPlayedFretSpanAt,
@@ -195,8 +196,9 @@ export function createRenderer({
const _scrStrGlow = new Array(MAX_RENDER_STRINGS).fill(0.5);
const _scrStringAnticipation = new Array(MAX_RENDER_STRINGS).fill(0);
const _scrStringSustain = new Array(MAX_RENDER_STRINGS).fill(false);
const _CV_KEY_TIME_MUL = 1e4;
const _CV_KEY_TIME_SLOT = 1e6;
// _CV_KEY_TIME_MUL / _CV_KEY_TIME_SLOT live in screen.js scope so that
// _encodeChordVerdictKey (defined and DI'd from there) can read them.
// renderer.js receives them as DI shorthands.
function lookaheadSmoothCamStep(dtSec, tgtXWorld, tgtSpanInt) {
const d = Math.min(0.2, Math.max(1e-4, dtSec));