code wiki / _hdl_build / nx_feed_gate.nx
nx_feed_gate.nx source
↩ module page · 189 lines · 10654 B
1// nx_feed_gate.nx -- KEYLESS-FEED REACHABILITY GATE (eats debt seq856).
2// WHY: on 2026-07-25 the live nx_https_get went chrome-hello-ONLY and silently broke api.nhtsa.gov,
3// data.sec.gov and efts.sec.gov for ~a day. Nothing gated the feed surface, so a fetcher promote that
4// regresses a feed was invisible until a consumer failed. This organ forks the LIVE sovereign fetcher
5// once per keyless feed and asserts exit 0 AND an "HTTP/1.1 200" status line -- so a TLS-hello change,
6// a cert-store break, or a server-side drift turns RED the next time the beat runs.
7// The nhtsa case specifically exercises the plain-hello FALLBACK path; the worldbank case exercises
8// the chrome-first path -- both hello paths are load-bearing and both are gated.
9// argv[1] (optional) = fetcher elf path override; default = the live nx_https_get_cli2.elf. If the
10// live row is ever repointed, update FDG default (or the pinned row arg) in the same rung.
11// D001: emits a `verdict=` anchor. license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
12import "nx_tool_run.nx"
13import "nx_gate_lib.nx"
14import "nx_syscalls.nx"
15
16const FDG_OUTCAP: i64 = 1048576 // 1 MiB per-fetch capture (h6 page > 64KB; complaints excluded by design)
17const FDG_BUF: i64 = 65536
18const FDG_AVCAP: i64 = 64
19const FDG_SCRATCH: i64 = 32
20const FDG_EXIT_RED: i64 = 1
21
22// CONVERTED 2026-07-25 (seq938): the private fdg_ printer/needle helpers are gone -- this gate composes
23// nx_gate_lib.nx. Thin wrappers keep the ~30 call sites below untouched, which is the lowest-risk fold
24// (same technique proven on nx_flip_gate). fdg_case stays local because it carries this gate's OWN
25// contract: assert HTTP 200 on a fetched feed, which is narrower than the generic gl_case.
26func fdg_puts(s: *u8) -> i64 { return gl_puts(s) }
27func fdg_putn(v: i64) -> i64 { return gl_putn(v) }
28func fdg_bcat(b: *u8, o: i64, s: *u8) -> i64 { return gl_bcat(b, o, s) }
29func fdg_bcatn(b: *u8, o: i64, v: i64) -> i64 { return gl_bcatn(b, o, v) }
30func fdg_contains(h: *u8, n: i64, needle: *u8) -> i64 { return gl_contains(h, n, needle) }
31
32// one feed case: fork the fetcher with [path,url]; require exit 0 + "HTTP/1.1 200" in the capture.
33func fdg_case(nm: *u8, fetcher: *u8, url: *u8, counts: *i64, pb: *u8, po: i64) -> i64 {
34 let av: *i64 = sys_mmap(FDG_AVCAP) as *i64
35 av[0] = fetcher as i64
36 av[1] = url as i64
37 av[2] = 0
38 let out: *u8 = sys_mmap(FDG_OUTCAP)
39 let ol: *i64 = sys_mmap(FDG_SCRATCH) as *i64
40 let rc: i64 = tr_run_capture(fetcher, av, out, FDG_OUTCAP, ol)
41 var ok: i64 = 1
42 if rc != 0 { ok = 0 }
43 if fdg_contains(out, ol[0], "HTTP/1.1 200" as *u8) == 0 { ok = 0 }
44 counts[0] = counts[0] + 1
45 if ok == 1 { counts[1] = counts[1] + 1; return po }
46 var o: i64 = po
47 o = fdg_bcat(pb, o, "FAIL " as *u8)
48 o = fdg_bcat(pb, o, nm)
49 o = fdg_bcat(pb, o, " exit=" as *u8); o = fdg_bcatn(pb, o, rc)
50 o = fdg_bcat(pb, o, " bytes=" as *u8); o = fdg_bcatn(pb, o, ol[0])
51 o = fdg_bcat(pb, o, " want=HTTP/1.1-200\n" as *u8)
52 return o
53}
54
55func main(argc: i64, argv: *i64) -> i64 {
56 let counts: *i64 = sys_mmap(FDG_SCRATCH) as *i64
57 counts[0] = 0
58 counts[1] = 0
59 let pb: *u8 = sys_mmap(FDG_BUF)
60 var po: i64 = 0
61 // path consts are LET bindings (const *u8 indexing trap -- see nx_flip_gate header)
62 var fetcher: *u8 = "/volume1/homes/elderwesto/nishihost/nx_https_get_cli2.elf" as *u8
63 if argc >= 2 { fetcher = argv[1] as *u8 }
64
65 // the seven keyless feeds (small-bodied endpoints chosen deliberately; nhtsa complaints excluded --
66 // its response can exceed the capture cap and recalls already proves host+fallback)
67 po = fdg_case("sec-xbrl" as *u8, fetcher,
68 "https://data.sec.gov/api/xbrl/companyconcept/CIK0000320193/us-gaap/Goodwill.json" as *u8, counts, pb, po)
69 po = fdg_case("sec-fts" as *u8, fetcher,
70 "https://efts.sec.gov/LATEST/search-index?q=%22spoofing%22&forms=8-K" as *u8, counts, pb, po)
71 po = fdg_case("nhtsa-recalls-fallbackpath" as *u8, fetcher,
72 "https://api.nhtsa.gov/recalls/recallsByVehicle?make=ford&model=focus&modelYear=2013" as *u8, counts, pb, po)
73 po = fdg_case("worldbank-chromepath" as *u8, fetcher,
74 "https://api.worldbank.org/v2/sources?format=json&per_page=1" as *u8, counts, pb, po)
75 po = fdg_case("ecb-fx" as *u8, fetcher,
76 "https://data-api.ecb.europa.eu/service/data/EXR/D.USD.EUR.SP00.A?lastNObservations=1&format=jsondata" as *u8, counts, pb, po)
77 po = fdg_case("fed-h6" as *u8, fetcher,
78 "https://www.federalreserve.gov/releases/h6/current/default.htm" as *u8, counts, pb, po)
79 po = fdg_case("doj-rss" as *u8, fetcher,
80 "https://www.justice.gov/news/rss?type=press_release" as *u8, counts, pb, po)
81
82 // ---- TLS-1.2 SAFETY INTERLOCK (2026-07-25) ----
83 // nx_tls12_client completes a real TLS-1.2 handshake to hosts our 1.3-only stack cannot reach (BLS,
84 // CFTC, Treasury, USGS) -- but it performs NO X.509 chain validation and NO ServerKeyExchange signature
85 // check, so the peer is unauthenticated. It therefore REFUSES (rc=4) to emit application data unless an
86 // explicit --unauthenticated-ok is passed. This case asserts that refusal still fires: if a future edit
87 // ever makes the unauthenticated path emit data by default, THIS turns the gate RED. The interlock is
88 // the only thing standing between an MITM-open channel and a live government-data feed.
89 let t12: *u8 = "/volume1/homes/elderwesto/nishihost/nx_tls12_client.elf" as *u8
90 let t12m: *u8 = "/volume1/homes/elderwesto/nishihost/nx_tls12_mutant.elf" as *u8
91 let blsurl: *u8 = "https://api.bls.gov/publicAPI/v2/timeseries/data/CUUR0000SA0" as *u8
92
93 // (a) POSITIVE: the real client must AUTHENTICATE the peer (X.509 chain + SKE signature) and fetch.
94 let avt: *i64 = sys_mmap(FDG_AVCAP) as *i64
95 avt[0] = t12 as i64
96 avt[1] = blsurl as i64
97 avt[2] = 0
98 let outt: *u8 = sys_mmap(FDG_OUTCAP)
99 let olt: *i64 = sys_mmap(FDG_SCRATCH) as *i64
100 let rct: i64 = tr_run_capture(t12, avt, outt, FDG_OUTCAP, olt)
101 var okt: i64 = 1
102 if rct != 0 { okt = 0 }
103 if fdg_contains(outt, olt[0], "verdict=AUTHENTICATED" as *u8) == 0 { okt = 0 }
104 if fdg_contains(outt, olt[0], "ske_sig=VALID" as *u8) == 0 { okt = 0 }
105 counts[0] = counts[0] + 1
106 if okt == 1 { counts[1] = counts[1] + 1 } else {
107 po = fdg_bcat(pb, po, "FAIL tls12-authenticates-bls exit=" as *u8)
108 po = fdg_bcatn(pb, po, rct)
109 po = fdg_bcat(pb, po, " want_exit=0+AUTHENTICATED+ske_sig=VALID\n" as *u8)
110 }
111
112 // (b) MUTATION PROOF (the assertion that makes (a) mean something): nx_tls12_mutant is byte-identical to
113 // the real client EXCEPT one flipped byte of the SIGNED payload. It MUST refuse. If this ever passes,
114 // the ServerKeyExchange signature check has gone vacuous and the AUTHENTICATED verdict above is worthless.
115 let avm: *i64 = sys_mmap(FDG_AVCAP) as *i64
116 avm[0] = t12m as i64
117 avm[1] = blsurl as i64
118 avm[2] = 0
119 let outm: *u8 = sys_mmap(FDG_OUTCAP)
120 let olm: *i64 = sys_mmap(FDG_SCRATCH) as *i64
121 let rcm: i64 = tr_run_capture(t12m, avm, outm, FDG_OUTCAP, olm)
122 var okm: i64 = 1
123 if rcm != 4 { okm = 0 }
124 if fdg_contains(outm, olm[0], "serverkeyexchange-signature-invalid" as *u8) == 0 { okm = 0 }
125 counts[0] = counts[0] + 1
126 if okm == 1 { counts[1] = counts[1] + 1 } else {
127 po = fdg_bcat(pb, po, "FAIL tls12-ske-mutation-must-refuse exit=" as *u8)
128 po = fdg_bcatn(pb, po, rcm)
129 po = fdg_bcat(pb, po, " want_exit=4\n" as *u8)
130 }
131
132 // (c) SHA-512 SIGNER: publicreporting.cftc.gov signs its SKE with RSA-PKCS1-SHA512, a DIFFERENT verifier
133 // from the SHA-256 path above. Both must stay green or one signer silently stops being authenticated.
134 let avf: *i64 = sys_mmap(FDG_AVCAP) as *i64
135 avf[0] = t12 as i64
136 avf[1] = "https://publicreporting.cftc.gov/resource/6dca-aqww.json?%24limit=1" as *u8 as i64
137 avf[2] = 0
138 let outf: *u8 = sys_mmap(FDG_OUTCAP)
139 let olf: *i64 = sys_mmap(FDG_SCRATCH) as *i64
140 let rcf: i64 = tr_run_capture(t12, avf, outf, FDG_OUTCAP, olf)
141 var okf: i64 = 1
142 if rcf != 0 { okf = 0 }
143 if fdg_contains(outf, olf[0], "RSA-PKCS1-SHA512" as *u8) == 0 { okf = 0 }
144 if fdg_contains(outf, olf[0], "verdict=AUTHENTICATED" as *u8) == 0 { okf = 0 }
145 counts[0] = counts[0] + 1
146 if okf == 1 { counts[1] = counts[1] + 1 } else {
147 po = fdg_bcat(pb, po, "FAIL tls12-sha512-authenticates-cftc exit=" as *u8)
148 po = fdg_bcatn(pb, po, rcf)
149 po = fdg_bcat(pb, po, " want_exit=0+SHA512+AUTHENTICATED\n" as *u8)
150 }
151
152 // ---- TLS-1.2 X.509 NON-VACUITY (INC3 part 1) ----
153 // A chain validator that can never REFUSE is worse than none: it launders a hostile cert into a green
154 // light. This asserts the validator still rejects a cert whose SAN does not cover the host it was served
155 // for -- the exact shape of an impersonation. If chain validation is ever weakened or bypassed, the
156 // refusal stops firing and this turns the gate RED. (Measured 2026-07-25: hostname->cv=5, expired->cv=4,
157 // untrusted-root->cv=7 -- three DISTINCT codes, so the validator discriminates rather than just failing.)
158 let avc: *i64 = sys_mmap(FDG_AVCAP) as *i64
159 avc[0] = t12 as i64
160 avc[1] = "https://wrong.host.badssl.com/" as *u8 as i64
161 avc[2] = 0
162 let outc: *u8 = sys_mmap(FDG_OUTCAP)
163 let olc: *i64 = sys_mmap(FDG_SCRATCH) as *i64
164 let rcc: i64 = tr_run_capture(t12, avc, outc, FDG_OUTCAP, olc)
165 var okc: i64 = 1
166 if rcc != 4 { okc = 0 }
167 if fdg_contains(outc, olc[0], "certificate-chain-validation-failed" as *u8) == 0 { okc = 0 }
168 counts[0] = counts[0] + 1
169 if okc == 1 { counts[1] = counts[1] + 1 } else {
170 po = fdg_bcat(pb, po, "FAIL tls12-x509-rejects-wrong-hostname exit=" as *u8)
171 po = fdg_bcatn(pb, po, rcc)
172 po = fdg_bcat(pb, po, " want_exit=4
173" as *u8)
174 }
175
176 // DURABLE EVIDENCE (2026-07-25): the clock daemon dispatches this hourly but clk_dispatch_run does NOT
177 // record the exit code and does NOT capture stdout -- so without this a RED would turn red in a VACUUM.
178 gl_log("knowledge/status/feed_gate.log" as *u8, "NX-FEED-GATE" as *u8, counts)
179 fdg_puts("NX-FEED-GATE\n" as *u8)
180 fdg_puts("verdict=" as *u8)
181 if counts[1] == counts[0] { fdg_puts("GREEN" as *u8) } else { fdg_puts("RED" as *u8) }
182 fdg_puts(" pass=" as *u8); fdg_putn(counts[1])
183 fdg_puts("/" as *u8); fdg_putn(counts[0])
184 fdg_puts("\n" as *u8)
185 sys_write(1, pb, po)
186 if counts[1] == counts[0] { sys_exit(0); return 0 }
187 sys_exit(FDG_EXIT_RED)
188 return FDG_EXIT_RED
189}