# Allowlist for scripts/check_phase_conversion_sites.py -- a RATCHET.
#
# One occurrence of the 2^32 scaling constant per line, outside the
# sanctioned home (native/inc/nco/nco_core.h), each with a reason.
#
# THIS LIST MAY ONLY SHRINK. Adding an entry means a new private copy of
# the conversion nco_core.h calls "structural, not stylistic" -- do that
# only for a genuine inverse conversion, and say why here.
#
# Format:  <path>::<normalised source line> | reason
#
# ── SAFE: the INVERSE direction (phase word -> double) ────────────────
# A uint32 widened to double and divided cannot trap: every uint32 is
# exactly representable and the quotient is finite. C99 6.3.1.4 has
# nothing to say about it. These are not conversions the rule is about.

native/inc/adc/adc_core.h::* (1.0 / 4294967296.0); | inverse: scales a u32 down to the unit interval
native/inc/dll/dll_core.h::return ((double)mid / 4294967296.0) * (double)s->sf; | inverse: phase word -> chips
native/inc/dll/dll_core.h::s->chip_pos = ((double)s->code_nco.phase / 4294967296.0) * sfd; | inverse: phase word -> chips

# ── SAFE: deliberate, guarded, and documented ─────────────────────────

native/src/resamp/resamp_core.c::double q = upsample ? 4294967296.0 / rate : rate * 4294967296.0; | NOT a conversion: the arithmetic is resamp's (which reciprocal, which branch) and runs in double, exactly as nco_core.h prescribes; the cast is nco_phase_units_mod's. The literal is deliberately left spelled out rather than hidden behind a named constant -- this gate's detector IS that literal, so a macro would let a future `(uint32_t)(x * SCALE)` past it.

# ── KNOWN VIOLATIONS: recorded as debt, NOT endorsed ──────────────────
# Each of these is a private copy of the conversion. They are listed so
# the gate can stop NEW ones appearing while these are outstanding; the
# ratchet's whole purpose is that removing them is the only permitted
# direction. Do not add to this section.

native/src/symsync/symsync_core.c::return (uint32_t)(4294967296.0 / s); | VIOLATION. Bare cast: at sps == 1 this is (uint32_t)4294967296.0, a value uint32_t cannot represent -- undefined per C99 6.3.1.4. nco_core.h cites this exact site as one of the three that motivated confining the conversion ("symsync at sps == 1 produced 0 on x86 ... where arm64 saturates"), but the cast was never routed through nco_phase_units(). The `sps ? sps : 1` guard against zero substitutes precisely the triggering value.
