code wiki / (root) / nx_pushback_publish.nx

nx_pushback_publish.nx source

↩ module page · 145 lines · 8072 B

1// nx_pushback_publish.nx -- THE COMMUNITY PUSH-BACK COMMAND (/compare/modding MD23 pushback_publish, 2026-09-06). A thin caller 2// of nx_pushback_lib: one sovereign manifest, N community targets from knowledge/modding_communities.conf, one bundle per 3// community (the byte-identical manifest, the estate-written 7z, the content id, magnet, download url and index row, and the 4// publish row carrying the licence row and the referee grade). Every refusal is NAMED on its own line and the summary 5// partition sums (requested = published + refused). 6// usage: nx_pushback_publish publish <pkg-root> <manifest.nxmod> <community[,community...]> [outdir=<dir>] [grade=<file>] [conf=<path>] [jrnl=<path>] 7// nx_pushback_publish communities [conf=<path>] 8// outdir defaults to <pkg-root>/pushback; grade defaults to <pkg-root>/referee.grade (no grade file = UNGRADED, and an 9// ungraded package never publishes); conf defaults to knowledge/modding_communities.conf; jrnl to the ONE asset journal. 10// exits: 0 every requested community published (GREEN) - 2 usage - 3 at least one community refused (RED, each named) - 11// 4 the request refused before any community was tried (conf or manifest unreadable) 12// license_tier: ORIGINAL No hw writes (Rule 26). 13import "nx_syscalls.nx" 14import "nx_pushback_lib.nx" 15 16const PP_EXIT_OK: i64 = 0 17const PP_EXIT_USAGE: i64 = 2 18const PP_EXIT_REFUSED: i64 = 3 19const PP_EXIT_REQUEST: i64 = 4 20const PP_ARGC_PUBLISH: i64 = 5 21const PP_ARG_ROOT: i64 = 2 22const PP_ARG_MANIFEST: i64 = 3 23const PP_ARG_IDS: i64 = 4 24const PP_KEY_OUTDIR: *u8 = "outdir=" 25const PP_KEY_GRADE: *u8 = "grade=" 26const PP_KEY_CONF: *u8 = "conf=" 27const PP_KEY_JRNL: *u8 = "jrnl=" 28const PP_VERB_PUBLISH: *u8 = "publish" 29const PP_VERB_COMMUNITIES: *u8 = "communities" 30 31func pp_usage() -> i64 { 32 pv_puts("usage: nx_pushback_publish publish <pkg-root> <manifest.nxmod> <community[,community...]> [outdir=<dir>] [grade=<file>] [conf=<path>] [jrnl=<path>]\n" as *u8) 33 pv_puts(" nx_pushback_publish communities [conf=<path>]\n" as *u8) 34 return PP_EXIT_USAGE 35} 36func pp_prefix(s: *u8, pfx: *u8) -> i64 { 37 var i: i64 = 0 38 while pfx[i] != (0 as u8) { if s[i] != pfx[i] { return 0 } i = i + 1 } 39 return 1 40} 41func pp_arg(argc: i64, argv: *i64, key: *u8) -> *u8 { 42 var i: i64 = 2 43 while i < argc { 44 let a: *u8 = argv[i] as *u8 45 if pp_prefix(a, key) == 1 { return a + mm_len(key) } 46 i = i + 1 47 } 48 return 0 as *u8 49} 50func pp_kv(k: *u8, v: *u8) -> i64 { pv_puts(" " as *u8); pv_puts(k); pv_puts("=" as *u8); pv_puts(v); return 0 } 51func pp_kvn(k: *u8, v: i64) -> i64 { pv_puts(" " as *u8); pv_puts(k); pv_puts("=" as *u8); pv_putn(v); return 0 } 52func pp_under(root: *u8, name: *u8) -> *u8 { let o: *u8 = sys_mmap(PB_PATH_CAP); mm_join_path(root, name, o); return o } 53 54func main(argc: i64, argv: *i64) -> i64 { 55 if argc < 2 { return pp_usage() } 56 let verb: *u8 = argv[1] as *u8 57 if mm_streq(verb, PP_VERB_COMMUNITIES) == 1 { 58 var conf: *u8 = pp_arg(argc, argv, PP_KEY_CONF) 59 if (conf as i64) == 0 { conf = PB_CONF_DEFAULT } 60 let tbl: *i64 = sys_mmap(8 * PB_C_SLOTS * PB_MAX_COMMUNITIES) as *i64 61 let n: i64 = pb_conf_load(conf, tbl, PB_MAX_COMMUNITIES) 62 if n < 0 { 63 pv_puts("COMMUNITIES-REFUSED rule=CONF-UNREADABLE" as *u8); pp_kv("conf" as *u8, conf); pv_puts("\n" as *u8) 64 return PP_EXIT_REQUEST 65 } 66 var i: i64 = 0 67 while i < n { 68 let b: i64 = i * PB_C_SLOTS 69 pv_puts("COMMUNITY" as *u8) 70 pp_kv("id" as *u8, tbl[b + PB_C_ID] as *u8) 71 pp_kv("kind" as *u8, tbl[b + PB_C_KIND] as *u8) 72 pp_kv("endpoint" as *u8, tbl[b + PB_C_ENDPOINT] as *u8) 73 pp_kvn("minredist" as *u8, tbl[b + PB_C_MINREDIST]) 74 pp_kv("note" as *u8, tbl[b + PB_C_NOTE] as *u8) 75 pv_puts("\n" as *u8) 76 i = i + 1 77 } 78 pv_puts("COMMUNITIES" as *u8); pp_kvn("rows" as *u8, n); pp_kv("conf" as *u8, conf); pv_puts(" verdict=GREEN\n" as *u8) 79 return PP_EXIT_OK 80 } 81 if mm_streq(verb, PP_VERB_PUBLISH) == 0 { return pp_usage() } 82 if argc < PP_ARGC_PUBLISH { 83 pv_puts("PUSHBACK-USAGE publish needs <pkg-root> <manifest.nxmod> <community[,community...]>\n" as *u8) 84 return pp_usage() 85 } 86 let root: *u8 = argv[PP_ARG_ROOT] as *u8 87 let mpath: *u8 = argv[PP_ARG_MANIFEST] as *u8 88 let ids: *u8 = argv[PP_ARG_IDS] as *u8 89 var outdir: *u8 = pp_arg(argc, argv, PP_KEY_OUTDIR) 90 if (outdir as i64) == 0 { outdir = pp_under(root, PB_OUTDIR_DEFAULT_NAME) } 91 var grade: *u8 = pp_arg(argc, argv, PP_KEY_GRADE) 92 if (grade as i64) == 0 { grade = pp_under(root, PB_GRADE_DEFAULT_NAME) } 93 var conf: *u8 = pp_arg(argc, argv, PP_KEY_CONF) 94 if (conf as i64) == 0 { conf = PB_CONF_DEFAULT } 95 var jrnl: *u8 = pp_arg(argc, argv, PP_KEY_JRNL) 96 if (jrnl as i64) == 0 { jrnl = PV_JRNL_DEFAULT } 97 let sum: *i64 = sys_mmap(8 * PB_S_N) as *i64 98 let rows: *i64 = sys_mmap(8 * PB_R_N * PB_MAX_IDS) as *i64 99 let got: i64 = pushback_publish(root, mpath, ids, outdir, grade, conf, jrnl, sum, rows) 100 if got < 0 { 101 pv_puts("PUSHBACK-REFUSED rule=" as *u8); pv_puts(pb_err_name(got)) 102 pp_kv("manifest" as *u8, mpath); pp_kv("conf" as *u8, conf); pv_puts("\n" as *u8) 103 pv_puts("PUSHBACK" as *u8); pp_kvn("requested" as *u8, sum[PB_S_REQUESTED]); pp_kvn("published" as *u8, 0) 104 pp_kvn("refused" as *u8, sum[PB_S_REQUESTED]); pp_kvn("identical_manifests" as *u8, 0); pv_puts(" verdict=RED\n" as *u8) 105 return PP_EXIT_REQUEST 106 } 107 // the member paths, for naming the member that refused 108 let lp: *i64 = sys_mmap(16) as *i64 109 let mb: *u8 = sys_read_file(mpath, lp) 110 let m: *i64 = sys_mmap(8 * MM_M_N_SLOTS) as *i64 111 var paths: *i64 = 0 as *i64 112 if (mb as i64) != 0 { if mm_parse(mb, lp[0], m) == MM_OK { paths = m[MM_M_PATHS] as *i64 } } 113 let parts: *i64 = sys_mmap(8 * PB_MAX_IDS) as *i64 114 let k: i64 = mm_split_csv(ids, parts, PB_MAX_IDS) 115 var j: i64 = 0 116 while j < k { 117 let r: *i64 = ((rows as i64) + j * PB_R_N * 8) as *i64 118 let id: *u8 = parts[j] as *u8 119 if r[PB_R_RC] == PB_OK { 120 pv_puts("PUSHBACK" as *u8); pp_kv("community" as *u8, id); pp_kv("kind" as *u8, pb_kind_name(r[PB_R_KIND])) 121 pv_puts(" verdict=PUBLISHED" as *u8); pp_kv("dir" as *u8, r[PB_R_OUTDIR] as *u8) 122 pp_kvn("archive_bytes" as *u8, r[PB_R_ARCHIVE_BYTES]); pp_kv("cid" as *u8, r[PB_R_CID] as *u8) 123 pp_kv("manifest_sha" as *u8, r[PB_R_MANIFEST_SHA] as *u8); pp_kvn("referee_permil" as *u8, sum[PB_S_PERMIL]) 124 pp_kv("transport" as *u8, pb_transport_name(r[PB_R_KIND])); pv_puts("\n" as *u8) 125 } else { 126 let rc: i64 = r[PB_R_RC] 127 pv_puts("PUSHBACK-REFUSED" as *u8); pp_kv("community" as *u8, id); pp_kv("rule" as *u8, pb_err_name(rc)) 128 let mi: i64 = r[PB_R_MEMBER_IDX] 129 if mi >= 0 { if (paths as i64) != 0 { pp_kv("member" as *u8, paths[mi] as *u8) } else { pp_kvn("member" as *u8, mi) } } 130 else { pp_kv("member" as *u8, PB_DASH_S) } 131 if rc == PB_ERR_PROVENANCE { pp_kv("reason" as *u8, pv_reason_name(r[PB_R_REASON])) } 132 else { if rc == PB_ERR_MANIFEST_REFUSED { pp_kv("reason" as *u8, mm_verdict_name(r[PB_R_REASON])) } 133 else { if rc == PB_ERR_NON_REDISTRIBUTABLE { pp_kvn("redist" as *u8, r[PB_R_REASON]) } 134 else { pp_kv("reason" as *u8, PB_DASH_S) } } } 135 pv_puts("\n" as *u8) 136 } 137 j = j + 1 138 } 139 pv_puts("PUSHBACK" as *u8); pp_kvn("requested" as *u8, sum[PB_S_REQUESTED]); pp_kvn("published" as *u8, sum[PB_S_PUBLISHED]) 140 pp_kvn("refused" as *u8, sum[PB_S_REFUSED]); pp_kvn("identical_manifests" as *u8, sum[PB_S_IDENTICAL]) 141 pp_kvn("members" as *u8, sum[PB_S_MEMBERS]); pp_kvn("referee_permil" as *u8, sum[PB_S_PERMIL]) 142 if sum[PB_S_REFUSED] == 0 { pv_puts(" verdict=GREEN\n" as *u8); return PP_EXIT_OK } 143 pv_puts(" verdict=RED\n" as *u8) 144 return PP_EXIT_REFUSED 145}