nx_send.nx source
↩ module page · 208 lines · 10726 B
1// nx_send.nx -- THE UNIFIED SEND SPINE (rung 1 of Nishi Mail to SOTA). Operator 2026-07-08:
2// "send a postcard or present as easily as i can send digital". ONE model to send to a recipient
3// over ANY channel -- email | postcard | letter | card | gift -- so the compose surface + the
4// scheduler + the delivery ledger all speak one vocabulary.
5// SEND-CHANNEL : the routing table (channel -> which sovereign composer/transport handles it).
6// POSTAL-ADDR : a structured postal address model + sovereign deliverability validation.
7// SEND-INTENT : the send descriptor (recipient + channel + destination + occasion + status).
8// Sovereign by construction: no 3rd party on the path. Physical last-mile = own print pipeline
9// (nx_mailpiece -> nx_img_print, next rung); a carrier adapter (Lob/PostGrid-class) is an opt-in
10// edge, and gifts stop at a sovereign gift-intent + order doc -- both per operator decision.
11// Pure logic + a self-test gate (argless = selftest). Persistence + raster composition = next rungs.
12// Commands: channels | addr <l1> <city> <region> <postal> <country> | intent <recip> <chan> <occ> <dest> | selftest
13// expect_exit: 0 license_tier: ORIGINAL
14import "nx_syscalls.nx"
15
16func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
17func p(s: *u8) -> i64 { sys_write(1, s, slen(s)); return 0 }
18func pn(v: i64) -> i64 {
19 var m: i64 = v; if m < 0 { p("-" as *u8); m = 0 - m }
20 let t: *u8 = sys_mmap(24); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 }
21 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
22 let o: *u8 = sys_mmap(24); var i: i64 = 0; while i < k { o[i] = t[k-1-i]; i = i + 1 } sys_write(1, o, k); return 0
23}
24func seq(a: *u8, b: *u8) -> i64 {
25 var i: i64 = 0
26 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
27 if b[i] != (0 as u8) { return 0 }
28 return 1
29}
30func is_empty(s: *u8) -> i64 { if s[0] == (0 as u8) { return 1 } return 0 }
31func has_at(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { if s[i] == (64 as u8) { return 1 } i = i + 1 } return 0 }
32func is_zip5(s: *u8) -> i64 {
33 var i: i64 = 0
34 while i < 5 { let c: i64 = s[i] as i64; if c < 48 { return 0 } if c > 57 { return 0 } i = i + 1 }
35 if s[5] != (0 as u8) { return 0 }
36 return 1
37}
38// extract the idx-th '|'-delimited field of s into out (NUL-terminated); returns 1 if that field exists
39func pipe_field(s: *u8, idx: i64, out: *u8, cap: i64) -> i64 {
40 var seg: i64 = 0
41 var t: i64 = 0
42 var i: i64 = 0
43 var found: i64 = 0
44 var go: i64 = 1
45 while go == 1 {
46 let c: i64 = s[i] as i64
47 if c == 0 { go = 0 }
48 if go == 1 {
49 if c == 124 { seg = seg + 1 } else {
50 if seg == idx { found = 1; if t < cap - 1 { out[t] = s[i]; t = t + 1 } }
51 }
52 i = i + 1
53 }
54 }
55 out[t] = 0 as u8
56 if seg >= idx { if found == 1 { return 1 } if seg > idx { return 1 } }
57 return found
58}
59
60// ---- SEND-CHANNEL: routing table ----
61func sr_valid(ch: *u8) -> i64 {
62 if seq(ch, "email" as *u8) == 1 { return 1 }
63 if seq(ch, "postcard" as *u8) == 1 { return 1 }
64 if seq(ch, "letter" as *u8) == 1 { return 1 }
65 if seq(ch, "card" as *u8) == 1 { return 1 }
66 if seq(ch, "gift" as *u8) == 1 { return 1 }
67 return 0
68}
69func sr_physical(ch: *u8) -> i64 {
70 if seq(ch, "postcard" as *u8) == 1 { return 1 }
71 if seq(ch, "letter" as *u8) == 1 { return 1 }
72 if seq(ch, "card" as *u8) == 1 { return 1 }
73 return 0
74}
75func sr_route(ch: *u8) -> *u8 {
76 if seq(ch, "email" as *u8) == 1 { return "nx_email_send (DKIM-signed SMTP over sovereign TLS)" as *u8 }
77 if seq(ch, "postcard" as *u8) == 1 { return "nx_mailpiece postcard -> nx_img_print (raster URF/IPP) or carrier" as *u8 }
78 if seq(ch, "letter" as *u8) == 1 { return "nx_mailpiece letter (No.10 window envelope) -> print or carrier" as *u8 }
79 if seq(ch, "card" as *u8) == 1 { return "nx_mailpiece card (A7 folded) -> print or carrier" as *u8 }
80 if seq(ch, "gift" as *u8) == 1 { return "nx_gift (sovereign gift-intent + order doc)" as *u8 }
81 return "none (unknown channel)" as *u8
82}
83
84// ---- POSTAL-ADDR: validate a structured postal address ----
85// required: line1, city, country. US: also region + 5-digit zip. returns 1 deliverable, 0 not.
86func pa_valid(l1: *u8, city: *u8, region: *u8, postal: *u8, country: *u8) -> i64 {
87 if is_empty(l1) == 1 { return 0 }
88 if is_empty(city) == 1 { return 0 }
89 if is_empty(country) == 1 { return 0 }
90 if seq(country, "US" as *u8) == 1 {
91 if is_empty(region) == 1 { return 0 }
92 if is_zip5(postal) == 0 { return 0 }
93 }
94 return 1
95}
96
97// ---- CLI commands ----
98func cmd_channels() -> i64 {
99 p("=== NX-SEND channels (SEND-CHANNEL routing) ===\n" as *u8)
100 let chs: *i64 = sys_mmap(8 * 8) as *i64
101 chs[0] = "email" as *u8 as i64
102 chs[1] = "postcard" as *u8 as i64
103 chs[2] = "letter" as *u8 as i64
104 chs[3] = "card" as *u8 as i64
105 chs[4] = "gift" as *u8 as i64
106 var i: i64 = 0
107 while i < 5 {
108 let ch: *u8 = chs[i] as *u8
109 p(" " as *u8); p(ch); p(" -> " as *u8); p(sr_route(ch))
110 if sr_physical(ch) == 1 { p(" [physical]" as *u8) } else { p(" [digital/other]" as *u8) }
111 p("\n" as *u8)
112 i = i + 1
113 }
114 return 0
115}
116func cmd_addr(l1: *u8, city: *u8, region: *u8, postal: *u8, country: *u8) -> i64 {
117 let ok: i64 = pa_valid(l1, city, region, postal, country)
118 p("POSTAL-ADDR " as *u8); p(l1); p(" / " as *u8); p(city); p(", " as *u8); p(region); p(" " as *u8); p(postal); p(" / " as *u8); p(country)
119 if ok == 1 { p(" deliverable=yes\n" as *u8) } else { p(" deliverable=no (missing required field or bad postal code)\n" as *u8) }
120 return 0
121}
122func cmd_intent(recip: *u8, chan: *u8, occ: *u8, dest: *u8) -> i64 {
123 if sr_valid(chan) == 0 { p("SEND-INTENT ERROR unknown channel=" as *u8); p(chan); p(" -- fail loud\n" as *u8); return 1 }
124 var ok: i64 = 1
125 var why: *u8 = "ok" as *u8
126 if seq(chan, "email" as *u8) == 1 {
127 if has_at(dest) == 0 { ok = 0; why = "email destination is not an address" as *u8 }
128 }
129 if sr_physical(chan) == 1 {
130 let l1: *u8 = sys_mmap(128); let ci: *u8 = sys_mmap(128); let rg: *u8 = sys_mmap(64); let pc: *u8 = sys_mmap(64); let co: *u8 = sys_mmap(64)
131 pipe_field(dest, 0, l1, 128); pipe_field(dest, 1, ci, 128); pipe_field(dest, 2, rg, 64); pipe_field(dest, 3, pc, 64); pipe_field(dest, 4, co, 64)
132 if pa_valid(l1, ci, rg, pc, co) == 0 { ok = 0; why = "physical destination is not a deliverable postal address" as *u8 }
133 }
134 if seq(chan, "gift" as *u8) == 1 {
135 if is_empty(dest) == 1 { ok = 0; why = "gift destination/recipient missing" as *u8 }
136 }
137 p("SEND-INTENT recipient=" as *u8); p(recip); p(" channel=" as *u8); p(chan)
138 p(" route=" as *u8); p(sr_route(chan)); p(" occasion=" as *u8); p(occ); p(" dest=" as *u8); p(dest)
139 if ok == 1 { p(" status=draft-ready\n" as *u8); return 0 }
140 p(" status=REJECTED (" as *u8); p(why); p(")\n" as *u8)
141 return 1
142}
143
144// ---- SELFTEST (the gate; argless default) ----
145func cmd_selftest() -> i64 {
146 p("=== NX-SEND SELFTEST (SEND-CHANNEL + POSTAL-ADDR + SEND-INTENT) ===\n" as *u8)
147 var ok: i64 = 1
148 let mt: *u8 = sys_mmap(8); mt[0] = 0 as u8 // real empty string (a bare "" literal aliases the pool)
149 // channel validity + physical classification (pos + neg)
150 if sr_valid("email" as *u8) != 1 { ok = 0 }
151 if sr_valid("postcard" as *u8) != 1 { ok = 0 }
152 if sr_valid("card" as *u8) != 1 { ok = 0 }
153 if sr_valid("gift" as *u8) != 1 { ok = 0 }
154 if sr_valid("fax" as *u8) != 0 { ok = 0 }
155 if sr_valid(mt) != 0 { ok = 0 }
156 if sr_physical("postcard" as *u8) != 1 { ok = 0 }
157 if sr_physical("letter" as *u8) != 1 { ok = 0 }
158 if sr_physical("email" as *u8) != 0 { ok = 0 }
159 if sr_physical("gift" as *u8) != 0 { ok = 0 }
160 // postal address validation (pos + neg)
161 if pa_valid("123 Main St" as *u8, "Springfield" as *u8, "IL" as *u8, "62704" as *u8, "US" as *u8) != 1 { ok = 0 }
162 if pa_valid("10 Downing St" as *u8, "London" as *u8, mt, "SW1A2AA" as *u8, "UK" as *u8) != 1 { ok = 0 }
163 if pa_valid(mt, "Springfield" as *u8, "IL" as *u8, "62704" as *u8, "US" as *u8) != 0 { ok = 0 }
164 if pa_valid("123 Main St" as *u8, mt, "IL" as *u8, "62704" as *u8, "US" as *u8) != 0 { ok = 0 }
165 if pa_valid("123 Main St" as *u8, "Springfield" as *u8, mt, "62704" as *u8, "US" as *u8) != 0 { ok = 0 }
166 if pa_valid("123 Main St" as *u8, "Springfield" as *u8, "IL" as *u8, "ABCDE" as *u8, "US" as *u8) != 0 { ok = 0 }
167 if pa_valid("123 Main St" as *u8, "Springfield" as *u8, "IL" as *u8, "6270" as *u8, "US" as *u8) != 0 { ok = 0 }
168 // primitives
169 if has_at("a@b.com" as *u8) != 1 { ok = 0 }
170 if has_at("nope" as *u8) != 0 { ok = 0 }
171 if is_zip5("62704" as *u8) != 1 { ok = 0 }
172 if is_zip5("627o4" as *u8) != 0 { ok = 0 }
173 // pipe_field
174 let fb: *u8 = sys_mmap(64)
175 pipe_field("a|bb|ccc" as *u8, 1, fb, 64)
176 if seq(fb, "bb" as *u8) != 1 { ok = 0 }
177 pipe_field("a|bb|ccc" as *u8, 2, fb, 64)
178 if seq(fb, "ccc" as *u8) != 1 { ok = 0 }
179 // end-to-end intents
180 let e1: i64 = cmd_intent("Grandma" as *u8, "postcard" as *u8, "birthday" as *u8, "742 Evergreen Ter|Springfield|IL|62704|US" as *u8)
181 let e2: i64 = cmd_intent("Alex" as *u8, "email" as *u8, "hello" as *u8, "alex@example.com" as *u8)
182 let e3: i64 = cmd_intent("Bob" as *u8, "postcard" as *u8, "thanks" as *u8, "bad@example.com" as *u8)
183 if e1 != 0 { ok = 0 }
184 if e2 != 0 { ok = 0 }
185 if e3 != 1 { ok = 0 }
186 p("NX-SEND-SELFTEST channels=5 postal=validated intents=3 " as *u8)
187 if ok == 1 { p("verdict=GREEN\n" as *u8); return 0 }
188 p("verdict=RED\n" as *u8)
189 return 1
190}
191
192// PURE-CORE entry (no main): consumers = _hdl_build/nx_send_gate (CLI+selftest wrapper) + nx_send_merge (bulk merge).
193func sd_cli(argc: i64, argv: *i64) -> i64 {
194 if argc < 2 { return cmd_selftest() }
195 let cmd: *u8 = argv[1] as *u8
196 if seq(cmd, "selftest" as *u8) == 1 { return cmd_selftest() }
197 if seq(cmd, "channels" as *u8) == 1 { return cmd_channels() }
198 if seq(cmd, "addr" as *u8) == 1 {
199 if argc < 7 { p("usage: addr <line1> <city> <region> <postal> <country>\n" as *u8); return 1 }
200 return cmd_addr(argv[2] as *u8, argv[3] as *u8, argv[4] as *u8, argv[5] as *u8, argv[6] as *u8)
201 }
202 if seq(cmd, "intent" as *u8) == 1 {
203 if argc < 6 { p("usage: intent <recipient> <channel> <occasion> <dest>\n" as *u8); return 1 }
204 return cmd_intent(argv[2] as *u8, argv[3] as *u8, argv[4] as *u8, argv[5] as *u8)
205 }
206 p("NX-SEND usage: channels | addr | intent | selftest\n" as *u8)
207 return 1
208}