code wiki / (root) / nx_asset_prov_clock_cli_candidate_t346.nx

nx_asset_prov_clock_cli_candidate_t346.nx source

↩ module page · 76 lines · 4202 B

1// nx_asset_prov.nx -- THE PER-ASSET PROVENANCE ROW, as a command (/compare/modding MD9, 2026-09-06). A thin caller of 2// nx_asset_prov_lib so the command line and every export door prove the SAME verdict code. 3// usage: nx_asset_prov row <file> <source_url> <licence_id> <origin> [jrnl=<path>] hash the file, append its row, print the verdict 4// nx_asset_prov verdict <file> [jrnl=<path>] hash the file, print the verdict 5// nx_asset_prov verdict-sha <sha256hex> [jrnl=<path>] the verdict for a known sha 6// exits: 0 SHIP_OK | 2 usage | 3 REVIEW | 4 REFUSE (the reason is on the line) | 5 the file could not be read 7// The journal defaults to knowledge/provenance/assets.jrnl; a gate passes its own. 8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_asset_prov_clock_candidate_t346.nx" 11 12const AP2_EXIT_USAGE: i64 = 2 13const AP2_EXIT_UNREADABLE: i64 = 5 14const AP2_JRNL_KEY: *u8 = "jrnl=" 15const AP2_JRNL_KEY_LEN: i64 = 5 16 17func ap2_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 } 18func ap2_has_prefix(s: *u8, p: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { if s[i] != p[i] { return 0 } i = i + 1 } return 1 } 19func ap2_usage() -> i64 { 20 pv_puts("usage: nx_asset_prov row <file> <source_url> <licence_id> <origin> [jrnl=<path>] | verdict <file> [jrnl=<path>] | verdict-sha <sha256hex> [jrnl=<path>]\n" as *u8) 21 return AP2_EXIT_USAGE 22} 23// the trailing jrnl=<path> is a SCAN over argv, so the positional contract is untouched 24func ap2_jrnl(argc: i64, argv: *i64) -> *u8 { 25 var i: i64 = 1 26 while i < argc { 27 let a: *u8 = argv[i] as *u8 28 if ap2_has_prefix(a, AP2_JRNL_KEY, AP2_JRNL_KEY_LEN) == 1 { return a + AP2_JRNL_KEY_LEN } 29 i = i + 1 30 } 31 return PV_JRNL_DEFAULT 32} 33func main(argc: i64, argv: *i64) -> i64 { 34 if argc < 3 { return ap2_usage() } 35 let verb: *u8 = argv[1] as *u8 36 let jrnl: *u8 = ap2_jrnl(argc, argv) 37 let sha: *u8 = sys_mmap(PV_SHA_HEX + 1) 38 let res: *i64 = sys_mmap(8 * PV_RES_N) as *i64 39 if ap2_streq(verb, "row" as *u8) == 1 { 40 if argc < 6 { return ap2_usage() } 41 let path: *u8 = argv[2] as *u8 42 let n: i64 = pv_hash_file(path, sha) 43 if n < 0 { pv_puts("ASSET-PROV-REFUSE unreadable: " as *u8); pv_puts(path); pv_puts("\n" as *u8); return AP2_EXIT_UNREADABLE } 44 let epoch: i64 = pv_now() 45 if epoch <= 0 { pv_puts("ASSET-PROV-REFUSE clock unavailable; journal unchanged\n" as *u8); return AP2_EXIT_UNREADABLE } 46 let w: i64 = pv_row_write(jrnl, sha, argv[3] as *u8, argv[4] as *u8, argv[5] as *u8, epoch) 47 if w < 0 { pv_puts("ASSET-PROV-REFUSE journal not writable: " as *u8); pv_puts(jrnl); pv_puts("\n" as *u8); return AP2_EXIT_UNREADABLE } 48 pv_puts("ASSET-PROV-ROW sha=" as *u8); pv_puts(sha) 49 pv_puts(" bytes=" as *u8); pv_putn(n) 50 pv_puts(" source=" as *u8); pv_puts(argv[3] as *u8) 51 pv_puts(" lic=" as *u8); pv_puts(argv[4] as *u8) 52 pv_puts(" origin=" as *u8); pv_puts(argv[5] as *u8) 53 pv_puts(" epoch=" as *u8); pv_putn(epoch) 54 pv_puts(" row_bytes=" as *u8); pv_putn(w) 55 pv_puts(" jrnl=" as *u8); pv_puts(jrnl); pv_puts("\n" as *u8) 56 let rc: i64 = pv_verdict(jrnl, sha, res) 57 pv_print(sha, rc, res) 58 return rc 59 } 60 if ap2_streq(verb, "verdict" as *u8) == 1 { 61 let path: *u8 = argv[2] as *u8 62 let n: i64 = pv_hash_file(path, sha) 63 if n < 0 { pv_puts("ASSET-PROV-REFUSE unreadable: " as *u8); pv_puts(path); pv_puts("\n" as *u8); return AP2_EXIT_UNREADABLE } 64 let rc: i64 = pv_verdict(jrnl, sha, res) 65 pv_print(sha, rc, res) 66 return rc 67 } 68 if ap2_streq(verb, "verdict-sha" as *u8) == 1 { 69 let s: *u8 = argv[2] as *u8 70 if pv_is_sha_hex(s) != 1 { pv_puts("ASSET-PROV-REFUSE not a sha256 hex: " as *u8); pv_puts(s); pv_puts("\n" as *u8); return AP2_EXIT_USAGE } 71 let rc: i64 = pv_verdict(jrnl, s, res) 72 pv_print(s, rc, res) 73 return rc 74 } 75 return ap2_usage() 76}