code wiki / _hdl_build / nx_pub_plane.nx
nx_pub_plane.nx source
↩ module page · 398 lines · 21725 B
1// nx_pub_plane.nx -- THE PUBLISHING PLANE driver: one command, every site, all discovery artifacts
2// DERIVED from the per-site registry. The organ the operator asked for when they said publishing is
3// "random and arbitrary" and that they want to "focus on work, not on where something was put".
4//
5// nx_pub_plane list [conf] the configured sites (proves the site table parses)
6// nx_pub_plane emit <site> [conf] write <docroot>/{sitemap.xml,robots.txt,llms.txt}
7// nx_pub_plane emitall [conf] every configured site, one pass
8// nx_pub_plane adopt <site> [conf] bring UNREGISTERED docroot entries into the registry
9// (idempotent; the migration step that must run BEFORE
10// the gateway starts refusing, or it refuses live pages)
11// nx_pub_plane check <site> <relpath> [conf] THE GATEWAY: exit 0 publishable, 3 REFUSED
12//
13// Proof lives in the sibling verifier nx_pub_plane_gate.nx (the /api/gate_run route executes
14// VERIFIERS ONLY -- a name ending in gate/test/kat -- which is what keeps that route never-brick).
15// Default site table: knowledge/pub_sites.conf (DATA -- adding a site is a row, never a recompile).
16// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
17import "nx_pub_lib.nx"
18import "nx_syscalls.nx"
19
20const PP_CONF: i64 = 65536
21const PP_SPANS: i64 = 128
22const PP_PATHCAP: i64 = 1024
23const PP_NAMECAP: i64 = 256
24const PP_SPAN: i64 = 16
25const PP_ARG_A: i64 = 2
26const PP_ARG_B: i64 = 3
27const PP_ARG_C: i64 = 4
28const PP_EXIT_USAGE: i64 = 2
29const PP_EXIT_REFUSED: i64 = 3
30const PP_EXIT_EMIT: i64 = 1
31const PP_EXIT_NOSITE: i64 = 4
32const PP_HASH: i64 = 35
33const PP_OUTCAP: i64 = 1048576
34
35func pp_puts(s: *u8) -> i64 { return pl_puts(s) }
36func pp_werr(s: *u8) -> i64 { return pl_werr(s) }
37func pp_num(v: i64) -> i64 {
38 let b: *u8 = sys_mmap(PP_NAMECAP)
39 let n: i64 = pl_catn(b, 0, v)
40 b[n] = 0 as u8
41 pl_puts(b)
42 sys_munmap(b, PP_NAMECAP)
43 return 0
44}
45func pp_span_puts(q: *u8, s: i64, e: i64) -> i64 {
46 let b: *u8 = sys_mmap(PP_PATHCAP)
47 pl_span_cstr(q, s, e, b)
48 pl_puts(b)
49 sys_munmap(b, PP_PATHCAP)
50 return 0
51}
52
53// emit all three discovery artifacts for ONE resolved site. Returns 0 ok, -1 on any emit failure.
54func pp_emit_site(conf: *u8, spans: *i64, site: *u8) -> i64 {
55 let docroot: *u8 = sys_mmap(PP_PATHCAP)
56 let prefix: *u8 = sys_mmap(PP_PATHCAP)
57 let baseurl: *u8 = sys_mmap(PP_PATHCAP)
58 let title: *u8 = sys_mmap(PP_PATHCAP)
59 let outp: *u8 = sys_mmap(PP_PATHCAP)
60 let flags: *i64 = sys_mmap(PP_SPAN) as *i64
61 pl_span_cstr(conf, spans[0], spans[1], docroot)
62 pl_span_cstr(conf, spans[2], spans[3], prefix)
63 pl_span_cstr(conf, spans[4], spans[5], baseurl)
64 pl_span_cstr(conf, spans[6], spans[7], title)
65 var rc: i64 = 0
66 pl_join(outp, docroot, "sitemap.xml" as *u8)
67 let nurl: i64 = pl_sitemap(docroot, prefix, baseurl, outp, flags)
68 if nurl < 0 { rc = 0 - 1 }
69 pl_join(outp, docroot, "robots.txt" as *u8)
70 let nd: i64 = pl_robots(baseurl, conf, spans[8], spans[9], outp)
71 if nd < 0 { rc = 0 - 1 }
72 pl_join(outp, docroot, "llms.txt" as *u8)
73 let nl: i64 = pl_llms(docroot, prefix, baseurl, title, outp)
74 if nl < 0 { rc = 0 - 1 }
75 // SELF-REGISTER what we just wrote, so the plane's own output is never an orphan on its own desk.
76 // Idempotent: already-present paths are left alone, so a human's curated row is never overwritten.
77 var reg_added: i64 = 0
78 if pl_register_asset(prefix, "sitemap.xml" as *u8, "derived from the registry by nx_pub_plane emit" as *u8) == 1 { reg_added = reg_added + 1 }
79 if pl_register_asset(prefix, "robots.txt" as *u8, "derived from the registry by nx_pub_plane emit" as *u8) == 1 { reg_added = reg_added + 1 }
80 if pl_register_asset(prefix, "llms.txt" as *u8, "derived from the registry by nx_pub_plane emit" as *u8) == 1 { reg_added = reg_added + 1 }
81 pp_puts("PUB-EMIT site=" as *u8)
82 pp_puts(site)
83 pp_puts(" urls=" as *u8)
84 pp_num(nurl)
85 pp_puts(" disallow=" as *u8)
86 pp_num(nd)
87 pp_puts(" llms_links=" as *u8)
88 pp_num(nl)
89 pp_puts(" self_registered=" as *u8)
90 pp_num(reg_added)
91 pp_puts(" registry_declared=" as *u8)
92 pp_num(flags[0])
93 pp_puts(" loaded=" as *u8)
94 pp_num(flags[1])
95 // HONESTY: a registry that could not be fully reached must never look like a complete site.
96 if flags[2] > 0 {
97 pp_puts(" UNREACHED_BEYOND_COUNT=" as *u8)
98 pp_num(flags[2])
99 }
100 pp_puts(" -> " as *u8)
101 pp_puts(docroot)
102 pp_puts("\n" as *u8)
103 sys_munmap(docroot, PP_PATHCAP)
104 sys_munmap(prefix, PP_PATHCAP)
105 sys_munmap(baseurl, PP_PATHCAP)
106 sys_munmap(title, PP_PATHCAP)
107 sys_munmap(outp, PP_PATHCAP)
108 return rc
109}
110
111// walk the site table; mode 0 = list, mode 1 = emit each. Returns sites handled, or -1.
112func pp_walk(confpath: *u8, mode: i64) -> i64 {
113 let conf: *u8 = sys_mmap(PP_CONF)
114 let n: i64 = pl_rfile(confpath, conf, PP_CONF)
115 if n <= 0 { return 0 - 1 }
116 let c: *i64 = sys_mmap(PP_SPAN) as *i64
117 let spans: *i64 = sys_mmap(PP_SPANS) as *i64
118 let namb: *u8 = sys_mmap(PP_NAMECAP)
119 var cnt: i64 = 0
120 var bad: i64 = 0
121 var i: i64 = 0
122 while i < n {
123 let le: i64 = pl_le(conf, i, n)
124 var skip: i64 = 0
125 if le <= i { skip = 1 }
126 if skip == 0 { if conf[i] == (PP_HASH as u8) { skip = 1 } }
127 if skip == 0 {
128 if pl_col(conf, i, le, PL_S_SITE, c) == 1 {
129 pl_span_cstr(conf, c[0], c[1], namb)
130 var ok: i64 = 1
131 if pl_col(conf, i, le, PL_S_DOCROOT, c) == 1 { spans[0] = c[0]; spans[1] = c[1] } else { ok = 0 }
132 if pl_col(conf, i, le, PL_S_PREFIX, c) == 1 { spans[2] = c[0]; spans[3] = c[1] } else { ok = 0 }
133 if pl_col(conf, i, le, PL_S_BASEURL, c) == 1 { spans[4] = c[0]; spans[5] = c[1] } else { ok = 0 }
134 if pl_col(conf, i, le, PL_S_TITLE, c) == 1 { spans[6] = c[0]; spans[7] = c[1] } else { ok = 0 }
135 spans[8] = 0
136 spans[9] = 0
137 if pl_col(conf, i, le, PL_S_DISALLOW, c) == 1 { spans[8] = c[0]; spans[9] = c[1] }
138 if ok == 1 {
139 cnt = cnt + 1
140 if mode == 0 {
141 pp_puts("PUB-SITE " as *u8)
142 pp_puts(namb)
143 pp_puts("\tdocroot=" as *u8)
144 pp_span_puts(conf, spans[0], spans[1])
145 pp_puts("\tregistry=" as *u8)
146 pp_span_puts(conf, spans[2], spans[3])
147 pp_puts("\tbase=" as *u8)
148 pp_span_puts(conf, spans[4], spans[5])
149 pp_puts("\n" as *u8)
150 }
151 if mode == 1 { if pp_emit_site(conf, spans, namb) != 0 { bad = bad + 1 } }
152 } else {
153 pp_werr("PUB-FAIL malformed site row (need site/docroot/regprefix/baseurl/title)\n" as *u8)
154 bad = bad + 1
155 }
156 }
157 }
158 i = le + 1
159 }
160 sys_munmap(conf, PP_CONF)
161 sys_munmap(c as *u8, PP_SPAN)
162 sys_munmap(spans as *u8, PP_SPANS)
163 sys_munmap(namb, PP_NAMECAP)
164 if bad > 0 { return 0 - 1 }
165 return cnt
166}
167
168// ---- THE PUBLISHING DESK: one page, EVERY site, every number DERIVED ---------------------------
169// The desk that existed was single-site (it did not know andelinwest existed) and stale by half a day,
170// because it was generated once and never re-derived. This one walks the SITE TABLE, so a site added
171// as a config row appears here with no code change, and every figure comes from pl_status_counts /
172// pl_disk_counts -- the registry plane and a live docroot walk. Nothing on this page is hand-written.
173func pp_board(confpath: *u8, outpath: *u8) -> i64 {
174 let conf: *u8 = sys_mmap(PP_CONF)
175 let n: i64 = pl_rfile(confpath, conf, PP_CONF)
176 if n <= 0 { return 0 - 1 }
177 let out: *u8 = sys_mmap(PP_OUTCAP)
178 let c: *i64 = sys_mmap(PP_SPAN) as *i64
179 let sc: *i64 = sys_mmap(PP_SPANS) as *i64
180 let dc: *i64 = sys_mmap(PP_SPANS) as *i64
181 let docroot: *u8 = sys_mmap(PP_PATHCAP)
182 let prefix: *u8 = sys_mmap(PP_PATHCAP)
183 var o: i64 = 0
184 o = pl_cat(out, o, "<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\">\n" as *u8)
185 o = pl_cat(out, o, "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n" as *u8)
186 o = pl_cat(out, o, "<title>Publishing desk -- every site, derived from the registry</title>\n" as *u8)
187 o = pl_cat(out, o, "<style>body{font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif;color:#16202e;background:#fff;margin:0}main{max-width:960px;margin:0 auto;padding:24px 20px 64px}h1{font-size:1.6rem;margin:0 0 4px}h2{color:#0b2545;margin:32px 0 8px;font-size:1.15rem}.sub{color:#5a6b85;margin:0 0 24px}table{border-collapse:collapse;width:100%;margin:10px 0 4px}th,td{text-align:left;padding:7px 10px;border-bottom:1px solid #e3e9f2}th{color:#5a6b85;font-weight:600;font-size:.85rem;letter-spacing:.02em}td.n{text-align:right;font-variant-numeric:tabular-nums}.k{color:#5a6b85;font-size:.85rem}.warn{color:#a3341f;font-weight:600}.ok{color:#1d6b3f;font-weight:600}.card{border:1px solid #dce3ec;border-left:4px solid #0b2545;border-radius:8px;padding:14px 18px;margin:14px 0;background:#fbfcfe}code{background:#eef2f8;padding:1px 5px;border-radius:3px;font-size:.9em}</style>\n" as *u8)
188 o = pl_cat(out, o, "</head><body><main>\n" as *u8)
189 o = pl_cat(out, o, "<h1>Publishing desk</h1>\n" as *u8)
190 o = pl_cat(out, o, "<p class=sub>Every site in <code>knowledge/pub_sites.conf</code>, with every number read live from that site's registry plane and a walk of its docroot. Adding a site is a config row, not a code change. Nothing on this page is hand-maintained.</p>\n" as *u8)
191 var nsite: i64 = 0
192 var i: i64 = 0
193 while i < n {
194 let le: i64 = pl_le(conf, i, n)
195 var skip: i64 = 0
196 if le <= i { skip = 1 }
197 if skip == 0 { if conf[i] == (PP_HASH as u8) { skip = 1 } }
198 if skip == 0 {
199 if pl_col(conf, i, le, PL_S_SITE, c) == 1 {
200 var ok: i64 = 1
201 var ds: i64 = 0
202 var de: i64 = 0
203 var ps: i64 = 0
204 var pe: i64 = 0
205 var bs: i64 = 0
206 var be: i64 = 0
207 let nameS: i64 = c[0]
208 let nameE: i64 = c[1]
209 if pl_col(conf, i, le, PL_S_DOCROOT, c) == 1 { ds = c[0]; de = c[1] } else { ok = 0 }
210 if pl_col(conf, i, le, PL_S_PREFIX, c) == 1 { ps = c[0]; pe = c[1] } else { ok = 0 }
211 if pl_col(conf, i, le, PL_S_BASEURL, c) == 1 { bs = c[0]; be = c[1] } else { ok = 0 }
212 if ok == 1 {
213 nsite = nsite + 1
214 pl_span_cstr(conf, ds, de, docroot)
215 pl_span_cstr(conf, ps, pe, prefix)
216 pl_status_counts(prefix, sc)
217 pl_disk_counts(docroot, prefix, dc)
218 o = pl_cat(out, o, "<h2>" as *u8)
219 o = pl_span_put(out, o, conf, nameS, nameE)
220 o = pl_cat(out, o, "</h2>\n<p class=k>" as *u8)
221 o = pl_span_put(out, o, conf, bs, be)
222 o = pl_cat(out, o, " · docroot <code>" as *u8)
223 o = pl_span_put(out, o, conf, ds, de)
224 o = pl_cat(out, o, "</code> · registry <code>" as *u8)
225 o = pl_span_put(out, o, conf, ps, pe)
226 o = pl_cat(out, o, "</code></p>\n" as *u8)
227 o = pl_cat(out, o, "<table><tr><th>registry status</th><th>rows</th><th>meaning</th></tr>\n" as *u8)
228 o = pl_cat(out, o, "<tr><td>live</td><td class=n>" as *u8); o = pl_catn(out, o, sc[0])
229 o = pl_cat(out, o, "</td><td class=k>indexable; in sitemap.xml and llms.txt</td></tr>\n" as *u8)
230 o = pl_cat(out, o, "<tr><td>asset</td><td class=n>" as *u8); o = pl_catn(out, o, sc[1])
231 o = pl_cat(out, o, "</td><td class=k>served, never indexed</td></tr>\n" as *u8)
232 o = pl_cat(out, o, "<tr><td>draft</td><td class=n>" as *u8); o = pl_catn(out, o, sc[2])
233 o = pl_cat(out, o, "</td><td class=k>registered, publishable, NOT indexed -- where adoption lands pages</td></tr>\n" as *u8)
234 o = pl_cat(out, o, "<tr><td>withdrawn</td><td class=n>" as *u8); o = pl_catn(out, o, sc[3])
235 o = pl_cat(out, o, "</td><td class=k>must not be served; the edge 404s a removed URL</td></tr>\n" as *u8)
236 o = pl_cat(out, o, "<tr><td>redirect</td><td class=n>" as *u8); o = pl_catn(out, o, sc[4])
237 o = pl_cat(out, o, "</td><td class=k>successor URL in the note column</td></tr>\n" as *u8)
238 o = pl_cat(out, o, "<tr><td>debris</td><td class=n>" as *u8); o = pl_catn(out, o, sc[5])
239 o = pl_cat(out, o, "</td><td class=k>rollback/backup artifacts; refused by the edge</td></tr>\n" as *u8)
240 o = pl_cat(out, o, "<tr><td><strong>total rows</strong></td><td class=n><strong>" as *u8); o = pl_catn(out, o, sc[6])
241 o = pl_cat(out, o, "</strong></td><td class=k>the site's single source of truth</td></tr></table>\n" as *u8)
242 o = pl_cat(out, o, "<table><tr><th>docroot (top level)</th><th>count</th></tr>\n" as *u8)
243 o = pl_cat(out, o, "<tr><td>pages (.html)</td><td class=n>" as *u8); o = pl_catn(out, o, dc[0]); o = pl_cat(out, o, "</td></tr>\n" as *u8)
244 o = pl_cat(out, o, "<tr><td>directories</td><td class=n>" as *u8); o = pl_catn(out, o, dc[1]); o = pl_cat(out, o, "</td></tr>\n" as *u8)
245 o = pl_cat(out, o, "<tr><td>other files</td><td class=n>" as *u8); o = pl_catn(out, o, dc[2]); o = pl_cat(out, o, "</td></tr>\n" as *u8)
246 o = pl_cat(out, o, "<tr><td>.prev rollback artifacts</td><td class=n>" as *u8); o = pl_catn(out, o, dc[3]); o = pl_cat(out, o, "</td></tr>\n" as *u8)
247 o = pl_cat(out, o, "<tr><td>ORPHANS (on disk, in no registry row)</td><td class=n>" as *u8)
248 if dc[4] > 0 { o = pl_cat(out, o, "<span class=warn>" as *u8); o = pl_catn(out, o, dc[4]); o = pl_cat(out, o, "</span>" as *u8) }
249 if dc[4] == 0 { o = pl_cat(out, o, "<span class=ok>0</span>" as *u8) }
250 o = pl_cat(out, o, "</td></tr></table>\n" as *u8)
251 if dc[4] > 0 {
252 o = pl_cat(out, o, "<div class=card>An orphan is a file the site serves that its registry does not describe: it cannot appear in sitemap.xml, no owner is recorded, and nothing decides whether it should exist. Run <code>nx_pub_plane adopt " as *u8)
253 o = pl_span_put(out, o, conf, nameS, nameE)
254 o = pl_cat(out, o, "</code> to register them as <code>draft</code> -- that changes what the registry KNOWS, never what the world SEES.</div>\n" as *u8)
255 }
256 }
257 }
258 }
259 i = le + 1
260 }
261 o = pl_cat(out, o, "<h2>How this page stays true</h2>\n<div class=card>Each figure is re-derived on every emit: statuses from the site's registry plane, disk counts from a live walk of its docroot. There is no cached copy to go stale, and a site that is not in the site table cannot appear here at all. Re-emit with <code>nx_pub_plane board</code>.</div>\n" as *u8)
262 o = pl_cat(out, o, "<p class=k>sites rendered: " as *u8)
263 o = pl_catn(out, o, nsite)
264 o = pl_cat(out, o, "</p>\n</main></body></html>\n" as *u8)
265 let rc: i64 = pl_commit(outpath, out, o)
266 sys_munmap(conf, PP_CONF)
267 sys_munmap(out, PP_OUTCAP)
268 if rc != 0 { return 0 - 1 }
269 return nsite
270}
271
272func main(argc: i64, argv: *i64) -> i64 {
273 if argc < 2 {
274 pp_werr("usage: nx_pub_plane {list [conf] | emit <site> [conf] | emitall [conf] | check <site> <relpath> [conf]}\n" as *u8)
275 sys_exit(PP_EXIT_USAGE)
276 return PP_EXIT_USAGE
277 }
278 let verb: *u8 = argv[1] as *u8
279 let vl: i64 = pl_vlen(verb)
280 if pl_lit_eq(verb, 0, vl, "list" as *u8) == 1 {
281 var cf: *u8 = "knowledge/pub_sites.conf" as *u8
282 if argc > PP_ARG_A { cf = argv[PP_ARG_A] as *u8 }
283 let n: i64 = pp_walk(cf, 0)
284 if n < 0 { pp_werr("PUB-FAIL site table unreadable or malformed\n" as *u8); sys_exit(PP_EXIT_NOSITE); return PP_EXIT_NOSITE }
285 pp_puts("PUB-SITES total=" as *u8)
286 pp_num(n)
287 pp_puts("\n" as *u8)
288 sys_exit(0)
289 return 0
290 }
291 if pl_lit_eq(verb, 0, vl, "emitall" as *u8) == 1 {
292 var cf2: *u8 = "knowledge/pub_sites.conf" as *u8
293 if argc > PP_ARG_A { cf2 = argv[PP_ARG_A] as *u8 }
294 let n2: i64 = pp_walk(cf2, 1)
295 if n2 < 0 { pp_werr("PUB-FAIL emitall\n" as *u8); sys_exit(PP_EXIT_EMIT); return PP_EXIT_EMIT }
296 pp_puts("PUB-EMITALL sites=" as *u8)
297 pp_num(n2)
298 pp_puts("\n" as *u8)
299 sys_exit(0)
300 return 0
301 }
302 if pl_lit_eq(verb, 0, vl, "emit" as *u8) == 1 {
303 if argc < PP_ARG_B { pp_werr("PUB-FAIL emit needs <site>\n" as *u8); sys_exit(PP_EXIT_USAGE); return PP_EXIT_USAGE }
304 var cf3: *u8 = "knowledge/pub_sites.conf" as *u8
305 if argc > PP_ARG_B { cf3 = argv[PP_ARG_B] as *u8 }
306 let conf: *u8 = sys_mmap(PP_CONF)
307 let spans: *i64 = sys_mmap(PP_SPANS) as *i64
308 if pl_site_lookup(cf3, argv[PP_ARG_A] as *u8, conf, spans) != 1 {
309 pp_werr("PUB-FAIL no such site in the site table\n" as *u8)
310 sys_exit(PP_EXIT_NOSITE)
311 return PP_EXIT_NOSITE
312 }
313 let rc: i64 = pp_emit_site(conf, spans, argv[PP_ARG_A] as *u8)
314 if rc != 0 { pp_werr("PUB-FAIL emit\n" as *u8); sys_exit(PP_EXIT_EMIT); return PP_EXIT_EMIT }
315 sys_exit(0)
316 return 0
317 }
318 if pl_lit_eq(verb, 0, vl, "board" as *u8) == 1 {
319 var bo: *u8 = "sites/nishifamily/publishing.html" as *u8
320 if argc > PP_ARG_A { bo = argv[PP_ARG_A] as *u8 }
321 var cf6: *u8 = "knowledge/pub_sites.conf" as *u8
322 if argc > PP_ARG_B { cf6 = argv[PP_ARG_B] as *u8 }
323 let nb: i64 = pp_board(cf6, bo)
324 if nb < 0 { pp_werr("PUB-FAIL board emit\n" as *u8); sys_exit(PP_EXIT_EMIT); return PP_EXIT_EMIT }
325 pp_puts("PUB-BOARD sites=" as *u8)
326 pp_num(nb)
327 pp_puts(" -> " as *u8)
328 pp_puts(bo)
329 pp_puts("\n" as *u8)
330 sys_exit(0)
331 return 0
332 }
333 if pl_lit_eq(verb, 0, vl, "adopt" as *u8) == 1 {
334 if argc < PP_ARG_B { pp_werr("PUB-FAIL adopt needs <site>\n" as *u8); sys_exit(PP_EXIT_USAGE); return PP_EXIT_USAGE }
335 var cf5: *u8 = "knowledge/pub_sites.conf" as *u8
336 if argc > PP_ARG_B { cf5 = argv[PP_ARG_B] as *u8 }
337 let conf3: *u8 = sys_mmap(PP_CONF)
338 let spans3: *i64 = sys_mmap(PP_SPANS) as *i64
339 if pl_site_lookup(cf5, argv[PP_ARG_A] as *u8, conf3, spans3) != 1 {
340 pp_werr("PUB-FAIL no such site in the site table\n" as *u8)
341 sys_exit(PP_EXIT_NOSITE)
342 return PP_EXIT_NOSITE
343 }
344 let dr: *u8 = sys_mmap(PP_PATHCAP)
345 let pf: *u8 = sys_mmap(PP_PATHCAP)
346 pl_span_cstr(conf3, spans3[0], spans3[1], dr)
347 pl_span_cstr(conf3, spans3[2], spans3[3], pf)
348 let counts: *i64 = sys_mmap(PP_SPANS) as *i64
349 let nadd: i64 = pl_adopt(dr, pf, counts)
350 // -2 (lossy plane) and -3 (scan cap) already NAMED their cause on stderr; stamping the
351 // generic message over those would misattribute the refusal (the wrong-cause trap).
352 if nadd < 0 {
353 if nadd == 0 - 1 { pp_werr("PUB-FAIL adopt (docroot unreadable or seed failed)\n" as *u8) }
354 sys_exit(PP_EXIT_EMIT)
355 return PP_EXIT_EMIT
356 }
357 pp_puts("PUB-ADOPT site=" as *u8)
358 pp_puts(argv[PP_ARG_A] as *u8)
359 pp_puts(" added=" as *u8)
360 pp_num(nadd)
361 // counts[0] is DRAFT, not live -- adoption never auto-indexes. A label that said "live"
362 // here would misreport the one thing an operator checks after a bulk migration.
363 pp_puts(" draft_pages=" as *u8)
364 pp_num(counts[0])
365 pp_puts(" asset=" as *u8)
366 pp_num(counts[1])
367 pp_puts(" debris=" as *u8)
368 pp_num(counts[2])
369 pp_puts(" already_registered=" as *u8)
370 pp_num(counts[3])
371 pp_puts("\n" as *u8)
372 sys_exit(0)
373 return 0
374 }
375 if pl_lit_eq(verb, 0, vl, "check" as *u8) == 1 {
376 if argc < PP_ARG_C { pp_werr("PUB-FAIL check needs <site> <relpath>\n" as *u8); sys_exit(PP_EXIT_USAGE); return PP_EXIT_USAGE }
377 var cf4: *u8 = "knowledge/pub_sites.conf" as *u8
378 if argc > PP_ARG_C { cf4 = argv[PP_ARG_C] as *u8 }
379 let conf2: *u8 = sys_mmap(PP_CONF)
380 let spans2: *i64 = sys_mmap(PP_SPANS) as *i64
381 if pl_site_lookup(cf4, argv[PP_ARG_A] as *u8, conf2, spans2) != 1 {
382 pp_werr("PUB-REFUSED unknown site\n" as *u8)
383 sys_exit(PP_EXIT_REFUSED)
384 return PP_EXIT_REFUSED
385 }
386 let pfx: *u8 = sys_mmap(PP_PATHCAP)
387 pl_span_cstr(conf2, spans2[2], spans2[3], pfx)
388 let v: i64 = pl_check(pfx, argv[PP_ARG_B] as *u8)
389 if v == 0 { pp_puts("PUB-CHECK OK " as *u8) } else { pp_puts("PUB-CHECK REFUSED " as *u8) }
390 pp_puts(argv[PP_ARG_B] as *u8)
391 pp_puts("\n" as *u8)
392 sys_exit(v)
393 return v
394 }
395 pp_werr("PUB-FAIL unknown verb\n" as *u8)
396 sys_exit(PP_EXIT_USAGE)
397 return PP_EXIT_USAGE
398}