nx_provenance_curve_store.nx source
↩ module page · 193 lines · 9749 B
1// nx_provenance_curve_store.nx -- versioned content-addressed curve storage.
2//
3// module: nishi-core.perception.provenance_curve_store
4// depends: nishi-core.io.syscalls
5// disk_kb: 5
6// capability: PERCEPTION
7// wired_status: PARTIAL_WIRED
8//
9// MISSING_CAPABILITIES:
10// - CONTENT_ADDRESSED_HASH (BLAKE2b hash of curve data; queued, depends
11// on nx_blake2b which is FULLY_WIRED — wire the call site)
12// - FS_PATH_RESOLUTION (curve store root + per-instrument subdirectory
13// layout convention)
14// - SERIALIZATION (JSONL or binary serialization of curve + metadata)
15// - VERSION_CHAIN (V1 → V2 → V3 of same instrument's calibration over
16// time, with parent-hash links per Merkle DAG)
17// - LICENSE_TAGGING (CC0 / CC-BY / family-private per
18// [[reference-ingest-citation-and-license-discipline]])
19//
20// license_tier: PUBLIC_NISHI_SUBSTRATE
21// genealogy_id: feedback-substrate-primitives-meta-not-one-off_2026 +
22// feedback-end-to-end-bit-traceability-architecture +
23// reference-ingest-citation-and-license-discipline +
24// merkle_1979_dag_addressing +
25// git_2005_content_addressable
26//
27// Per cardinal [[feedback-substrate-primitives-meta-not-one-off]]:
28// THIS primitive stores ANY measured curve from ANY transducer or
29// calibration session. Versioned per-instance, content-addressed for
30// integrity, with provenance chain back to source samples.
31//
32// Reuse set served by this single primitive:
33// - DAC bit-accuracy + THD curves (per-DAC-serial)
34// - Amplifier FRF + THD-vs-power curves (per-amp-serial)
35// - Speaker FRF (per-driver-build, especially DIY where each build differs)
36// - Microphone calibration curves (per-mic-serial)
37// - Display gamma + gamut curves (per-display-serial)
38// - Camera response curves (per-sensor-serial)
39// - Haptic motor force curves
40// - Hydrophone pressure response
41// - Thermal sensor calibration
42// - Scent cartridge dispense profiles (per-cartridge-lot)
43// - Room impulse response (per-room-config)
44//
45// Per [[feedback-end-to-end-bit-traceability-architecture]]:
46// Each stored curve includes a provenance link chain back to its
47// generating measurement session + source stimulus + reference
48// transducer calibration. Full bit-traceability from any curve to
49// the physical measurements that produced it.
50
51import "nx_syscalls.nx"
52
53// ===== Curve domain sealed enum (mirrors signal compensator) ======
54//
55// Same six values as nx_sig_domain in nx_signal_compensator. Curves are
56// stored per-domain because the inverse-computation strategy varies.
57
58const NX_CURVE_DOMAIN_TEMPORAL_AUDIO: i64 = 1
59const NX_CURVE_DOMAIN_TEMPORAL_VIBRATION: i64 = 2
60const NX_CURVE_DOMAIN_TEMPORAL_SCALAR: i64 = 3
61const NX_CURVE_DOMAIN_TEMPORAL_MULTICHANNEL: i64 = 4
62const NX_CURVE_DOMAIN_SPATIAL_VISUAL: i64 = 5
63const NX_CURVE_DOMAIN_SPATIO_TEMPORAL_VIDEO: i64 = 6
64
65func nx_curve_domain_name(d: i64) -> *u8 {
66 if d == NX_CURVE_DOMAIN_TEMPORAL_AUDIO { return "TEMPORAL_AUDIO" }
67 if d == NX_CURVE_DOMAIN_TEMPORAL_VIBRATION { return "TEMPORAL_VIBRATION" }
68 if d == NX_CURVE_DOMAIN_TEMPORAL_SCALAR { return "TEMPORAL_SCALAR" }
69 if d == NX_CURVE_DOMAIN_TEMPORAL_MULTICHANNEL { return "TEMPORAL_MULTICHANNEL" }
70 if d == NX_CURVE_DOMAIN_SPATIAL_VISUAL { return "SPATIAL_VISUAL" }
71 if d == NX_CURVE_DOMAIN_SPATIO_TEMPORAL_VIDEO { return "SPATIO_TEMPORAL_VIDEO" }
72 return "UNKNOWN_DOMAIN"
73}
74
75// ===== Curve type sealed enum =====================================
76//
77// What KIND of curve is stored. A single transducer may have multiple
78// curve types associated (e.g., a speaker has FRF + THD + step-response +
79// off-axis-response curves).
80
81const NX_CURVE_TYPE_FRF: i64 = 1 // frequency response (mag + phase)
82const NX_CURVE_TYPE_THD: i64 = 2 // THD vs frequency at SPL
83const NX_CURVE_TYPE_THD_VS_LEVEL: i64 = 3 // THD vs output level at frequency
84const NX_CURVE_TYPE_STEP_RESPONSE: i64 = 4 // time-domain step response
85const NX_CURVE_TYPE_IMPULSE_RESPONSE: i64 = 5 // h(t)
86const NX_CURVE_TYPE_OFF_AXIS_RESPONSE: i64 = 6 // FRF at multiple angles
87const NX_CURVE_TYPE_GAMMA_1D: i64 = 7 // visual: per-channel gamma
88const NX_CURVE_TYPE_GAMUT_3D: i64 = 8 // visual: color gamut volume
89const NX_CURVE_TYPE_LINEARITY: i64 = 9 // sensor input-output mapping
90const NX_CURVE_TYPE_TEMPERATURE_DRIFT: i64 = 10 // sensor response vs temperature
91const NX_CURVE_TYPE_AGING_DRIFT: i64 = 11 // response vs time-since-calibration
92const NX_CURVE_TYPE_DISPENSE_PROFILE: i64 = 12 // chemical: cartridge dispense rate
93
94func nx_curve_type_name(t: i64) -> *u8 {
95 if t == NX_CURVE_TYPE_FRF { return "FRF" }
96 if t == NX_CURVE_TYPE_THD { return "THD" }
97 if t == NX_CURVE_TYPE_THD_VS_LEVEL { return "THD_VS_LEVEL" }
98 if t == NX_CURVE_TYPE_STEP_RESPONSE { return "STEP_RESPONSE" }
99 if t == NX_CURVE_TYPE_IMPULSE_RESPONSE { return "IMPULSE_RESPONSE" }
100 if t == NX_CURVE_TYPE_OFF_AXIS_RESPONSE { return "OFF_AXIS_RESPONSE" }
101 if t == NX_CURVE_TYPE_GAMMA_1D { return "GAMMA_1D" }
102 if t == NX_CURVE_TYPE_GAMUT_3D { return "GAMUT_3D" }
103 if t == NX_CURVE_TYPE_LINEARITY { return "LINEARITY" }
104 if t == NX_CURVE_TYPE_TEMPERATURE_DRIFT { return "TEMPERATURE_DRIFT" }
105 if t == NX_CURVE_TYPE_AGING_DRIFT { return "AGING_DRIFT" }
106 if t == NX_CURVE_TYPE_DISPENSE_PROFILE { return "DISPENSE_PROFILE" }
107 return "UNKNOWN_CURVE_TYPE"
108}
109
110// ===== Storage verdicts ===========================================
111
112const NX_CURVE_STORE_OK: i64 = 0
113const NX_CURVE_STORE_FAIL_PATH: i64 = 1 // FS path resolution failed
114const NX_CURVE_STORE_FAIL_HASH_MISMATCH: i64 = 2 // content-address verification failed
115const NX_CURVE_STORE_FAIL_LICENSE_MISSING: i64 = 3 // no license tag, refused
116const NX_CURVE_STORE_FAIL_PROVENANCE_BROKEN: i64 = 4 // parent-hash chain incomplete
117const NX_CURVE_STORE_FAIL_DEPENDENCY_MISSING: i64 = 5 // PARTIAL_WIRED default
118
119func nx_curve_store_verdict_name(v: i64) -> *u8 {
120 if v == NX_CURVE_STORE_OK { return "OK" }
121 if v == NX_CURVE_STORE_FAIL_PATH { return "FAIL_PATH" }
122 if v == NX_CURVE_STORE_FAIL_HASH_MISMATCH { return "FAIL_HASH_MISMATCH" }
123 if v == NX_CURVE_STORE_FAIL_LICENSE_MISSING { return "FAIL_LICENSE_MISSING" }
124 if v == NX_CURVE_STORE_FAIL_PROVENANCE_BROKEN { return "FAIL_PROVENANCE_BROKEN" }
125 if v == NX_CURVE_STORE_FAIL_DEPENDENCY_MISSING { return "FAIL_DEPENDENCY_MISSING" }
126 return "UNKNOWN_VERDICT"
127}
128
129// ===== Top-level entry stubs ======================================
130
131// nx_curve_store_write -- persist a curve into the store with content-
132// addressed hash + provenance link + license tag. Returns curve_hash on
133// success (32-byte BLAKE2b), zero on failure (caller checks verdict via
134// nx_curve_store_get_last_verdict).
135
136func nx_curve_store_write(instrument_serial_ptr: *u8, instrument_serial_len: i64,
137 domain: i64, curve_type: i64,
138 data_ptr: *u8, data_len: i64,
139 parent_hash_ptr: *u8, parent_hash_len: i64,
140 license_tag_ptr: *u8, license_tag_len: i64) -> i64 {
141 if instrument_serial_len <= 0 { return 0 }
142 if data_len <= 0 { return 0 }
143 if domain < NX_CURVE_DOMAIN_TEMPORAL_AUDIO { return 0 }
144 if domain > NX_CURVE_DOMAIN_SPATIO_TEMPORAL_VIDEO { return 0 }
145 if curve_type < NX_CURVE_TYPE_FRF { return 0 }
146 if curve_type > NX_CURVE_TYPE_DISPENSE_PROFILE { return 0 }
147 if license_tag_len <= 0 { return 0 }
148 // PARTIAL_WIRED: BLAKE2b hash call + FS serialization + provenance
149 // link writer queued.
150 return 0
151}
152
153// nx_curve_store_read -- load latest curve for an instrument+domain+type.
154
155func nx_curve_store_read(instrument_serial_ptr: *u8, instrument_serial_len: i64,
156 domain: i64, curve_type: i64,
157 out_buf_ptr: *u8, out_buf_cap: i64) -> i64 {
158 if instrument_serial_len <= 0 { return 0 }
159 if out_buf_cap <= 0 { return 0 }
160 if domain < NX_CURVE_DOMAIN_TEMPORAL_AUDIO { return 0 }
161 if domain > NX_CURVE_DOMAIN_SPATIO_TEMPORAL_VIDEO { return 0 }
162 if curve_type < NX_CURVE_TYPE_FRF { return 0 }
163 if curve_type > NX_CURVE_TYPE_DISPENSE_PROFILE { return 0 }
164 return 0
165}
166
167// nx_curve_store_read_by_hash -- load a specific historical curve by its
168// content hash, regardless of whether it's the latest version.
169
170func nx_curve_store_read_by_hash(curve_hash_ptr: *u8, curve_hash_len: i64,
171 out_buf_ptr: *u8, out_buf_cap: i64) -> i64 {
172 if curve_hash_len != 32 { return 0 } // BLAKE2b output size
173 if out_buf_cap <= 0 { return 0 }
174 return 0
175}
176
177// nx_curve_store_get_last_verdict -- inspector for the most recent write.
178
179func nx_curve_store_get_last_verdict() -> i64 {
180 return NX_CURVE_STORE_FAIL_DEPENDENCY_MISSING
181}
182
183// nx_curve_store_get_age_days -- how stale is the latest curve for this
184// instrument? Used by nx_calibration_drift_monitor to schedule
185// re-characterization.
186
187func nx_curve_store_get_age_days(instrument_serial_ptr: *u8, instrument_serial_len: i64,
188 domain: i64, curve_type: i64) -> i64 {
189 if instrument_serial_len <= 0 { return -1 }
190 if domain < NX_CURVE_DOMAIN_TEMPORAL_AUDIO { return -1 }
191 if domain > NX_CURVE_DOMAIN_SPATIO_TEMPORAL_VIDEO { return -1 }
192 return -1
193}