code wiki / (root) / nx_colorsci_gate.nx

nx_colorsci_gate.nx

buildroot/runtime/nx_colorsci_gate.nx

26222 B424 linesdepth 4pulls 7 transitivereach 0 importersview sourcekind gate/proof
docsdependenciesstructsconstsfunctions

about

nx_colorsci_gate.nx -- THE GATE FOR THE COLOUR-SCIENCE RULER (nx_colorsci_lib + nx_fixq30_lib), 2026-08-24. SUBJECT: the libs in-process (they have no main; the ruler IS the code under test). Teeth, in order: T1 the DERIVED constants against their published digits -- pi (Machin) and e to 1e-7, and the identities sqrt(2)^2 = 2, atan2(0,-1) = pi, sin(pi/2) = 1, cos(pi/3) = 1/2, cbrt(27) = 3, ln(exp(3)) = 3. A CORDIC whose table was mistyped cannot pass these; a series that stopped early cannot either. T2 CIEDE2000 against Sharma-Wu-Dalal 2005 Table I: ALL 34 pairs (gv_subjects binds the denominator), both directions (the formula is symmetric by construction, and pairs 7/8 exist to prove it), and the table's h_bar_prime column (the arctangent branch handling pairs 9-16 exist to trap). T3 NEG-CONTROL: pair 1 against a WRONG expectation (+0.5 dE00) must FAIL the tolerance -- a tolerance so wide that anything passes would read green on every KAT row and prove nothing. T4 ICC: the mirrored sRGB2014.icc (color.org) parses; rXYZ+gXYZ+bXYZ sum to wtpt within s15Fixed16 resolution (an ICC structural invariant, not a typed expectation); white reads L=100 a=b=0; black L=0; EVERY one of the 256 greys reads a=b=0 (the whole population, not a sample); rgb->lab->rgb round-trips within one code over all greys and the eight cube corners. T5 the gamut descriptor: derived from the profile at the conf's sampling; every sample it was built from reads INSIDE; a chroma no display reaches reads OUTSIDE; bite-proven both ways; chroma clipping brings the outside probe inside at the same L and hue. Thresholds: the KAT tolerance is the half-ulp of a four-decimal table plus Q30 headroom; everything else is a structural identity. license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 3 imports · 0 importers

nx_syscalls.nx nx_gate_verdict.nx nx_colorsci_lib.nx nx_colorsci_gate.nx

imports: nx_syscalls.nxnx_gate_verdict.nxnx_colorsci_lib.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main gv_ctr sys_mmap nxa_die sys_write sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ gv_head gv_puts sys_write ↻ cs_ctx sys_mmap ↻ fq_ctx sys_mmap ↻ fq_atan_small fq_mul fq_atanh_small fq_mul ↻ fq_mul ↻ fq_div fq_sqrt fq_bitlen fq_isqrt vm_isqrt fq_div ↻ fq_from_int fq_mul ↻ cs_fq cg_nano gv_puts ↻

structs

none

consts

25const CG_KAT_PATH: *u8 = "knowledge/colorsci_ciede2000_kat.tsv"
26const CG_PROFILE: *u8 = "knowledge/fetched/cmp_phototwin_srgb2014.b64" // base64 transport of sRGB2014.icc (Google skcms mirror of color.org)
27const CG_CONF: *u8 = "knowledge/colorsci.conf"
28const CG_KAT_ROWS: i64 = 34 // Table I declares 34 pairs; another count is a partial table, refused
29const CG_KAT_FIELDS: i64 = 9
30const CG_F_L1: i64 = 1
31const CG_F_A1: i64 = 2
32const CG_F_B1: i64 = 3
33const CG_F_L2: i64 = 4
34const CG_F_A2: i64 = 5
35const CG_F_B2: i64 = 6
36const CG_F_HBAR: i64 = 7
37const CG_F_DE: i64 = 8
38const CG_DE_TOL_MICRO: i64 = 60 // half-ulp of a 4-decimal table (50) + Q30 arithmetic headroom (10)
39const CG_H_TOL_MICRO: i64 = 1000 // MEASURED 2026-08-24: the table's h' column is NOT four-decimal exact -- pair 21's own printed
42const CG_NANO: i64 = 1000000000
43const CG_PI_NANO: i64 = 3141592654 // pi, published digits (the KAT oracle for the Machin derivation)
44const CG_E_NANO: i64 = 2718281828 // e, published digits
45const CG_NANO_TOL: i64 = 100 // 1e-7: the Q30 series accumulate ~4e-8, doubled
46const CG_THREE: i64 = 3
47const CG_TWO: i64 = 2
48const CG_SQRT_ARG: i64 = 2
49const CG_CBRT_ARG: i64 = 27
50const CG_LN_ARG: i64 = 3
57const CG_WHITE_TOL_MICRO: i64 = 50000
58const CG_L_WHITE: i64 = 100
59const CG_S15_SUM_TOL_Q30: i64 = 262144
60const CG_GREYS: i64 = 256
61const CG_CODE_MAX: i64 = 255
62const CG_CODE_TOL: i64 = 1
63const CG_CORNERS: i64 = 8
64const CG_TAB: i64 = 9
65const CG_NL: i64 = 10
66const CG_HASH: i64 = 35
67const CG_ROW_SLOTS: i64 = 16
68const CG_BITE_DE_OFFSET_MICRO: i64 = 500000 // the planted-wrong expectation: +0.5 dE00
69const CG_OUT_L: i64 = 50
70const CG_OUT_A: i64 = 150 // a chroma of 150 at L=50: outside every display-class gamut
71const CG_GREY_MID: i64 = 128 // a mid grey: strictly inside on every channel
72const CG_BOUNDARY_SLACK_PERMIL: i64 = 1 // a cube-face sample sits ON the boundary: 1000 permil plus/minus one unit of Q30 rounding
73const CG_PERMIL: i64 = 1000
74const CG_SLOT: i64 = 8
75const CG_KAT_CAP: i64 = 65536

functions

77func cg_nano(x: i64) -> i64 { if x >= 0 { return (x * CG_NANO) >> FQ_SHIFT } return 0 - (((0 - x) * CG_NANO) >> FQ_SHIFT) }
called by 1: main
78func cg_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
called by 2: cg_withinmain
80func cg_field(buf: *u8, s: i64, e: i64, idx: i64, box: *i64) -> i64
called by 2: cg_fld_q30main
100func cg_fld_q30(buf: *u8, s: i64, e: i64, idx: i64, box: *i64) -> i64
104func cg_within(x: i64, y: i64, tol_micro: i64) -> i64
called by 1: main calls 2: cg_absfq_to_micro
109func main(argc: i64, argv: *i64) -> i64