code wiki / (root) / nx_artlicense_gate.nx

nx_artlicense_gate.nx source

↩ module page · 125 lines · 8023 B

1// nx_artlicense_gate.nx -- THE GATE FOR THE LICENSE CHAIN AND ROYALTY LEDGER (nx_artlicense), 2026-08-24. 2// 3// SUBJECT: the nx_artlicense ELF forked for real; its exit code IS the contract (0 SHIP-OK / 3 REVIEW / 4 REFUSE) 4// and every REFUSE must NAME its conjunct. Fixture chain rows in /tmp/nx_artlicense_gate/chain.conf cover one 5// row per refusal reason plus the positive control; the ledger is unlinked at SETUP so idempotency is measured 6// against a state this run established. A guard that refuses everything passes every deny-test, so the ALLOW 7// case (ok / DE-territory) is load-bearing, not decoration. 8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_gate_verdict.nx" 11import "nx_tool_run.nx" 12 13const AG_SUBJECT_DEFAULT: *u8 = "nx_artlicense.elf" 14const AG_DIR: *u8 = "/tmp/nx_artlicense_gate" 15const AG_CONF: *u8 = "/tmp/nx_artlicense_gate/chain.conf" 16const AG_LEDGER: *u8 = "/tmp/nx_artlicense_gate/royalty.tsv" 17const AG_MODE_DIR: i64 = 493 18const AG_MODE_0644: i64 = 420 19const AG_CAPTURE_CAP: i64 = 65536 20const AG_ARGV_SLOTS: i64 = 10 21const AG_SLOT: i64 = 8 22const AG_EXIT_OK: i64 = 0 23const AG_EXIT_REVIEW: i64 = 3 24const AG_EXIT_REFUSE: i64 = 4 25const AG_NOW_INSIDE: *u8 = "1600" 26 27func ag_write_text(path: *u8, s: *u8) -> i64 { 28 var n: i64 = 0 29 while s[n] != (0 as u8) { n = n + 1 } 30 let fd: i64 = sys_openat_wr(path, AG_MODE_0644) 31 if fd < 0 { return 0 - 1 } 32 let wr: i64 = sys_write(fd, s, n) 33 sys_close(fd) 34 if wr != n { return 0 - 1 } 35 return n 36} 37func ag_exists(path: *u8) -> i64 { 38 let lp: *i64 = sys_mmap(AG_SLOT * 2) as *i64 39 let b: *u8 = sys_read_file(path, lp) 40 if (b as i64) == 0 { return 0 } 41 return 1 42} 43// run the subject with up to 6 args 44func ag_run(subject: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8, a6: *u8, out: *u8, outlen: *i64) -> i64 { 45 let av: *i64 = sys_mmap(AG_SLOT * AG_ARGV_SLOTS) as *i64 46 av[0] = subject as i64 47 av[1] = a1 as i64 48 av[2] = a2 as i64 49 av[3] = a3 as i64 50 av[4] = a4 as i64 51 av[5] = a5 as i64 52 av[6] = a6 as i64 53 av[7] = 0 54 return tr_run_capture(subject, av, out, AG_CAPTURE_CAP, outlen) 55} 56 57func main(argc: i64, argv: *i64) -> i64 { 58 let ctr: *i64 = gv_ctr() 59 gv_head("nx_artlicense gate -- the license chain refuses by NAMED conjunct, allows the granted case, and the ledger is append-only and idempotent" as *u8) 60 var subject: *u8 = AG_SUBJECT_DEFAULT 61 if argc >= 2 { subject = argv[1] as *u8 } 62 gv_puts(" subject: " as *u8); gv_puts(subject); gv_puts("\n\n" as *u8) 63 sys_mkdir(AG_DIR, AG_MODE_DIR) 64 sys_unlinkat(AG_LEDGER) 65 let w1: i64 = ag_write_text(AG_CONF, "# fixture chains\nchain|ok|Owner A|rds|1000|4102444800|*|100|yes\nchain|noright|Owner B|rs|1000|4102444800|*|100|yes\nchain|expired|Owner C|rds|1000|1500|*|100|yes\nchain|future|Owner D|rds|1800|2000|*|100|yes\nchain|terr|Owner E|rds|1000|2000|NL,DE|100|yes\nchain|review|Owner F|rds|1000|2000|*|100|no\n" as *u8) 66 gv_check("setup-fixture-chain-written" as *u8, (w1 > 0) as i64, ctr) 67 gv_check("setup-ledger-absent-before-measuring (gate is idempotent)" as *u8, (ag_exists(AG_LEDGER) == 0) as i64, ctr) 68 let cap: *u8 = sys_mmap(AG_CAPTURE_CAP) 69 let olen: *i64 = sys_mmap(AG_SLOT * 2) as *i64 70 71 let rc_ok: i64 = ag_run(subject, "check" as *u8, "ok" as *u8, AG_NOW_INSIDE, "NL" as *u8, AG_CONF, 0 as *u8, cap, olen) 72 gv_puts(" [ok] rc=" as *u8); gv_num(rc_ok); gv_puts(" " as *u8); sys_write(1, cap, olen[0]) 73 gv_check("granted-chain-inside-term-and-territory-is-SHIP-OK (exit 0)" as *u8, (rc_ok == AG_EXIT_OK) as i64, ctr) 74 gv_check("granted-chain-prints-its-royalty-permil" as *u8, tr_contains(cap, olen[0], "royalty_permil=100 verdict=SHIP-OK" as *u8), ctr) 75 76 let rc_nr: i64 = ag_run(subject, "check" as *u8, "noright" as *u8, AG_NOW_INSIDE, "NL" as *u8, AG_CONF, 0 as *u8, cap, olen) 77 gv_puts(" [noright] rc=" as *u8); gv_num(rc_nr); gv_puts(" " as *u8); sys_write(1, cap, olen[0]) 78 var t: i64 = 0 79 if rc_nr == AG_EXIT_REFUSE { if tr_contains(cap, olen[0], "reason=RIGHT-MISSING" as *u8) == 1 { t = 1 } } 80 gv_check("missing-derivative-right-REFUSES-and-names-RIGHT-MISSING" as *u8, t, ctr) 81 gv_bite("neg-control-refuses-missing-right-allows-granted" as *u8, (rc_nr == AG_EXIT_REFUSE) as i64, (rc_ok != AG_EXIT_OK) as i64, ctr) 82 83 let rc_ex: i64 = ag_run(subject, "check" as *u8, "expired" as *u8, AG_NOW_INSIDE, "NL" as *u8, AG_CONF, 0 as *u8, cap, olen) 84 t = 0 85 if rc_ex == AG_EXIT_REFUSE { if tr_contains(cap, olen[0], "reason=EXPIRED" as *u8) == 1 { t = 1 } } 86 gv_check("expired-term-REFUSES-and-names-EXPIRED" as *u8, t, ctr) 87 let rc_fu: i64 = ag_run(subject, "check" as *u8, "future" as *u8, AG_NOW_INSIDE, "NL" as *u8, AG_CONF, 0 as *u8, cap, olen) 88 t = 0 89 if rc_fu == AG_EXIT_REFUSE { if tr_contains(cap, olen[0], "reason=NOT-STARTED" as *u8) == 1 { t = 1 } } 90 gv_check("future-term-REFUSES-and-names-NOT-STARTED" as *u8, t, ctr) 91 let rc_tf: i64 = ag_run(subject, "check" as *u8, "terr" as *u8, AG_NOW_INSIDE, "FR" as *u8, AG_CONF, 0 as *u8, cap, olen) 92 t = 0 93 if rc_tf == AG_EXIT_REFUSE { if tr_contains(cap, olen[0], "reason=TERRITORY" as *u8) == 1 { t = 1 } } 94 gv_check("ungranted-territory-REFUSES-and-names-TERRITORY" as *u8, t, ctr) 95 let rc_td: i64 = ag_run(subject, "check" as *u8, "terr" as *u8, AG_NOW_INSIDE, "DE" as *u8, AG_CONF, 0 as *u8, cap, olen) 96 gv_check("granted-territory-in-a-restricted-chain-is-SHIP-OK" as *u8, (rc_td == AG_EXIT_OK) as i64, ctr) 97 let rc_rv: i64 = ag_run(subject, "check" as *u8, "review" as *u8, AG_NOW_INSIDE, "NL" as *u8, AG_CONF, 0 as *u8, cap, olen) 98 t = 0 99 if rc_rv == AG_EXIT_REVIEW { if tr_contains(cap, olen[0], "reason=NOT-APPROVED" as *u8) == 1 { t = 1 } } 100 gv_check("unapproved-proof-is-REVIEW (exit 3), a person settles it" as *u8, t, ctr) 101 let rc_no: i64 = ag_run(subject, "check" as *u8, "nosuch" as *u8, AG_NOW_INSIDE, "NL" as *u8, AG_CONF, 0 as *u8, cap, olen) 102 t = 0 103 if rc_no == AG_EXIT_REFUSE { if tr_contains(cap, olen[0], "reason=NO-CHAIN" as *u8) == 1 { t = 1 } } 104 gv_check("absent-chain-REFUSES-and-names-NO-CHAIN (silence is never permission)" as *u8, t, ctr) 105 106 // ---- ledger: append, idempotent on sale_id, refused sales book nothing, totals sum ---- 107 let rc_r1: i64 = ag_run(subject, "royalty" as *u8, AG_LEDGER, "ok" as *u8, "S1" as *u8, "12345" as *u8, AG_CONF, cap, olen) 108 gv_puts(" [royalty S1] rc=" as *u8); gv_num(rc_r1); gv_puts(" " as *u8); sys_write(1, cap, olen[0]) 109 t = 0 110 if rc_r1 == AG_EXIT_OK { if tr_contains(cap, olen[0], "ledger=APPENDED sale_cents=12345 royalty_cents=1234" as *u8) == 1 { t = 1 } } 111 gv_check("royalty-appends-integer-cents (12345 * 100 permil = 1234, floor)" as *u8, t, ctr) 112 let rc_r2: i64 = ag_run(subject, "royalty" as *u8, AG_LEDGER, "ok" as *u8, "S1" as *u8, "12345" as *u8, AG_CONF, cap, olen) 113 gv_check("royalty-repeat-of-the-same-sale_id-is-DUPLICATE-not-a-second-row" as *u8, tr_contains(cap, olen[0], "ledger=DUPLICATE" as *u8), ctr) 114 let rc_r3: i64 = ag_run(subject, "royalty" as *u8, AG_LEDGER, "noright" as *u8, "S2" as *u8, "1000" as *u8, AG_CONF, cap, olen) 115 t = 0 116 if rc_r3 == AG_EXIT_REFUSE { if tr_contains(cap, olen[0], "ledger=UNCHANGED" as *u8) == 1 { t = 1 } } 117 gv_check("royalty-on-a-refused-chain-books-nothing" as *u8, t, ctr) 118 let rc_r4: i64 = ag_run(subject, "royalty" as *u8, AG_LEDGER, "ok" as *u8, "S3" as *u8, "5000" as *u8, AG_CONF, cap, olen) 119 let rc_t: i64 = ag_run(subject, "total" as *u8, AG_LEDGER, "ok" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, cap, olen) 120 gv_puts(" [total ok] " as *u8); sys_write(1, cap, olen[0]) 121 gv_check("total-sums-only-this-sku (1234 + 500 = 1734 over 2 rows)" as *u8, tr_contains(cap, olen[0], "rows=2 royalty_cents=1734" as *u8), ctr) 122 123 sys_unlinkat(AG_LEDGER) 124 return gv_verdict("artlicense" as *u8, ctr, "every refusal names its conjunct, the granted case ships, the ledger is idempotent integer cents" as *u8) 125}