nx_https_client_gate.nx source
↩ module page · 106 lines · 6495 B
1// nx_https_client_gate.nx -- THE GATE FOR THE STUB HTTPS CLIENT, 2026-09-03.
2//
3// SUBJECT: nx_https_get and nx_https_post_json AS DEFINED IN nx_https_client.nx, in-process.
4//
5// WHY A GATE FOR A MODULE NOBODY IMPORTS. Measured 2026-09-03: nx_https_client.nx has ZERO importers
6// and nx_https_post_json has ZERO callers, so nothing it does is observable today. It is gated anyway
7// because of what it WOULD do the moment someone imported it:
8//
9// 1. nx_https_post_json performed a **GET** and silently discarded json_body, then reported OK.
10// A function whose NAME is the contract, issuing the wrong method, sending no body, and
11// returning success, cannot be detected by anything downstream.
12// 2. nx_https_get here returned NX_HTTPS_OK without opening a socket -- while the module itself
13// already DEFINED NX_HTTPS_NOT_IMPLEMENTED and never used it.
14// 3. nx_https_get is defined in BOTH this module and nx_https_get.nx (the real one). The first
15// file to import both gets a working implementation SHADOWED by a stub that answers OK.
16//
17// THE TEETH ARE ABOUT THE DIRECTION OF FAILURE, NOT ABOUT FEATURES. There is no correct HTTPS
18// behaviour to assert here -- the module is a declared composition framework. What must be true is
19// that an unimplemented path FAILS LOUD. So every tooth checks that the verdict is NOT the success
20// value, and T3 pins the two constants apart so a future edit cannot quietly define them equal.
21//
22// T5 IS THE ANTI-VACUITY TOOTH. T1/T2 assert "verdict != OK", which a function returning any garbage
23// would pass. T5 demands the verdict be exactly NX_HTTPS_NOT_IMPLEMENTED -- the named refusal --
24// so an uninitialised or arbitrary value cannot score a pass.
25//
26// Teeth, in order:
27// T1 nx_https_get does NOT report success for a request it never made.
28// T2 nx_https_post_json does NOT report success for a body it never sent.
29// T3 NX_HTTPS_OK and NX_HTTPS_NOT_IMPLEMENTED are distinct values (so T1/T2 can discriminate).
30// T4 post_json does not scribble the caller's body buffer: the sentinel written there survives.
31// T5 ANTI-VACUITY: the verdict is the NAMED refusal, not merely non-OK.
32// T6 post_json reports no body and no bytes -- a refusal that claimed bytes would invite a read.
33// MEASURED 6/6 GREEN 2026-09-03 on the laptop. Bite locally INCONCLUSIVE (9 valid mutants, 0 kills)
34// and the reason is named rather than hidden: the laptop nx_gate_bite runs only operators 1/2a/2b,
35// while the NAS binary also runs 3 (NUMERIC CONSTANT) and 4 (SYMBOL-TARGETED). The two corrected
36// functions are straight-line constant assignments carrying no comparisons and no literals, so
37// operator 4 is the only one that could reach them -- a local INCONCLUSIVE is a fact about the
38// weaker tester, NOT evidence about this gate. Bite it on the NAS.
39// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
40import "nx_syscalls.nx"
41import "nx_gate_verdict.nx"
42import "nx_https_client.nx"
43
44const HCG_CAP: i64 = 4096
45const HCG_SENTINEL: i64 = 0xA5
46const HCG_NOW: i64 = 1788470000
47
48func main(argc: i64, argv: *i64) -> i64 {
49 let ctr: *i64 = gv_ctr()
50 gv_head("nx_https_client gate -- an unimplemented path must fail LOUD, and a post that sends no body must never report OK" as *u8)
51
52 let url: *u8 = "https://example.invalid/x" as *u8
53 var ulen: i64 = 0
54 while url[ulen] != (0 as u8) { ulen = ulen + 1 }
55
56 let body: *u8 = "{\x22a\x22:1}" as *u8
57 var blen: i64 = 0
58 while body[blen] != (0 as u8) { blen = blen + 1 }
59
60 // ---- T1 the GET stub ----
61 let ob1: *u8 = sys_mmap(HCG_CAP)
62 let r1: *HttpsResponse = nx_https_get(url, ulen, ob1, HCG_CAP, 1, HCG_NOW)
63 gv_puts(" [T1] get verdict=" as *u8); gv_num(r1.verdict)
64 gv_puts(" NX_HTTPS_OK=" as *u8); gv_num(NX_HTTPS_OK); gv_puts("\n" as *u8)
65 gv_check("an-unimplemented-GET-does-NOT-report-success-for-a-request-it-never-made" as *u8, (r1.verdict != NX_HTTPS_OK) as i64, ctr)
66
67 // ---- T4 sentinel: post_json must not treat the caller's BODY buffer as its response struct ----
68 let ob2: *u8 = sys_mmap(HCG_CAP)
69 var s: i64 = 0
70 while s < HCG_CAP { ob2[s] = HCG_SENTINEL as u8; s = s + 1 }
71
72 // ---- T2 the POST stub ----
73 let r2: *HttpsResponse = nx_https_post_json(url, ulen, body, blen, ob2, HCG_CAP, HCG_NOW)
74 gv_puts(" [T2] post_json verdict=" as *u8); gv_num(r2.verdict); gv_puts("\n" as *u8)
75 gv_check("a-post-that-sends-no-body-does-NOT-report-success" as *u8, (r2.verdict != NX_HTTPS_OK) as i64, ctr)
76
77 // ---- T3 the two constants must be distinguishable ----
78 gv_puts(" [T3] OK=" as *u8); gv_num(NX_HTTPS_OK)
79 gv_puts(" NOT_IMPLEMENTED=" as *u8); gv_num(NX_HTTPS_NOT_IMPLEMENTED); gv_puts("\n" as *u8)
80 gv_check("NX_HTTPS_OK-and-NX_HTTPS_NOT_IMPLEMENTED-are-distinct (without this T1 and T2 cannot discriminate)" as *u8, (NX_HTTPS_OK != NX_HTTPS_NOT_IMPLEMENTED) as i64, ctr)
81
82 // ---- T4 the sentinel survived ----
83 var intact: i64 = 1
84 var k: i64 = 0
85 while k < HCG_CAP {
86 if ob2[k] != (HCG_SENTINEL as u8) { intact = 0; k = HCG_CAP } else { k = k + 1 }
87 }
88 gv_puts(" [T4] caller body buffer intact=" as *u8); gv_num(intact); gv_puts("\n" as *u8)
89 gv_check("post_json-does-not-scribble-the-callers-body-buffer (out_buf is a BODY buffer, not a response struct)" as *u8, intact, ctr)
90
91 // ---- T5 ANTI-VACUITY: the NAMED refusal, not merely non-OK ----
92 var t5: i64 = 0
93 if r1.verdict == NX_HTTPS_NOT_IMPLEMENTED { if r2.verdict == NX_HTTPS_NOT_IMPLEMENTED { t5 = 1 } }
94 gv_puts(" [T5] both verdicts == NOT_IMPLEMENTED -> " as *u8); gv_num(t5); gv_puts("\n" as *u8)
95 gv_check("ANTI-VACUITY-the-verdict-is-the-NAMED-refusal-not-merely-non-OK (garbage would pass T1 and T2)" as *u8, t5, ctr)
96
97 // ---- T6 a refusal must not advertise bytes ----
98 gv_puts(" [T6] post body_len=" as *u8); gv_num(r2.body_len)
99 gv_puts(" bytes_total=" as *u8); gv_num(r2.bytes_total)
100 gv_puts(" status=" as *u8); gv_num(r2.status_code); gv_puts("\n" as *u8)
101 var t6: i64 = 0
102 if r2.body_len == 0 { if r2.bytes_total == 0 { t6 = 1 } }
103 gv_check("a-refusal-reports-no-body-and-no-bytes (a refusal claiming bytes invites a read of storage it never filled)" as *u8, t6, ctr)
104
105 return gv_verdict("https_client" as *u8, ctr, "the stub HTTPS client now fails loud by its own named verdict instead of reporting OK for a request it never made, and post_json no longer issues a GET while discarding its body" as *u8)
106}