code wiki / (root) / nx_market_ladder_gate.nx

nx_market_ladder_gate.nx source

↩ module page · 141 lines · 9934 B

1// nx_market_ladder_gate.nx -- THE GATE FOR THE MARKET-ENTRY VERDICT (nx_market_ladder_lib + the CLI), 2026-08-24. 2// 3// SUBJECT: the lib in-process AND the nx_market_ladder ELF forked for real (its exit code is the contract). 4// FIXTURES ARE ASSEMBLED AT RUNTIME in /tmp/nx_market_ladder_gate/: a matrix with two watch rows pointing at a 5// fixture organ, a plan with two rungs and five ladder levels, and the organ declaring ONE of the two symbols. 6// Expected: Open (no requirement) NO-REQUIREMENT; Half (R1,R2) GROW-FIRST binding R2; None (R2) HOLD; Wrong 7// (authored ENTER, requires R2) DISAGREE; Ghost (R9, no such rung) UNRESOLVED -- never a silent ENTER. 8// THE BITE: append the second symbol to the fixture organ and the HOLD level must flip to ENTER (the verdict 9// tracks the SOURCE through the one symbol ruler, not a cached claim). THE NEG-CONTROL for the exit contract: 10// a plan whose authored words all agree exits 0; the plan with a wrong word exits 1. 11// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 12import "nx_syscalls.nx" 13import "nx_gate_verdict.nx" 14import "nx_tool_run.nx" 15import "nx_market_ladder_lib.nx" 16 17const MG_SUBJECT_DEFAULT: *u8 = "nx_market_ladder.elf" 18const MG_DIR: *u8 = "/tmp/nx_market_ladder_gate" 19const MG_DIR_SLASH: *u8 = "/tmp/nx_market_ladder_gate/" 20const MG_MATRIX: *u8 = "/tmp/nx_market_ladder_gate/fx.matrix" 21const MG_PLAN: *u8 = "/tmp/nx_market_ladder_gate/fx.plan" 22const MG_PLAN_OK: *u8 = "/tmp/nx_market_ladder_gate/fxok.plan" 23const MG_MATRIX_OK: *u8 = "/tmp/nx_market_ladder_gate/fxok.matrix" 24const MG_ORGAN: *u8 = "/tmp/nx_market_ladder_gate/fx_organ.nx" 25const MG_MODE_DIR: i64 = 493 26const MG_MODE_0644: i64 = 420 27const MG_CAPTURE_CAP: i64 = 65536 28const MG_ARGV_SLOTS: i64 = 8 29const MG_SLOT: i64 = 8 30const MG_EXIT_OK: i64 = 0 31const MG_EXIT_DISAGREE: i64 = 1 32 33func mg_write_text(path: *u8, s: *u8) -> i64 { 34 var n: i64 = 0 35 while s[n] != (0 as u8) { n = n + 1 } 36 let fd: i64 = sys_openat_wr(path, MG_MODE_0644) 37 if fd < 0 { return 0 - 1 } 38 let wr: i64 = sys_write(fd, s, n) 39 sys_close(fd) 40 if wr != n { return 0 - 1 } 41 return n 42} 43func mg_append_text(path: *u8, s: *u8) -> i64 { 44 var n: i64 = 0 45 while s[n] != (0 as u8) { n = n + 1 } 46 let fd: i64 = sys_openat_append(path, MG_MODE_0644) 47 if fd < 0 { return 0 - 1 } 48 let wr: i64 = sys_write(fd, s, n) 49 sys_close(fd) 50 return wr 51} 52func mg_run(subject: *u8, dom: *u8, dir: *u8, out: *u8, outlen: *i64) -> i64 { 53 let av: *i64 = sys_mmap(MG_SLOT * MG_ARGV_SLOTS) as *i64 54 av[0] = subject as i64 55 av[1] = dom as i64 56 av[2] = dir as i64 57 av[3] = 0 58 return tr_run_capture(subject, av, out, MG_CAPTURE_CAP, outlen) 59} 60 61func main(argc: i64, argv: *i64) -> i64 { 62 let ctr: *i64 = gv_ctr() 63 gv_head("nx_market_ladder gate -- the ENTER / GROW-FIRST / HOLD verdict is computed from the source through the one symbol ruler" as *u8) 64 var subject: *u8 = MG_SUBJECT_DEFAULT 65 if argc >= 2 { subject = argv[1] as *u8 } 66 gv_puts(" subject: " as *u8); gv_puts(subject); gv_puts("\n\n" as *u8) 67 68 sys_mkdir(MG_DIR, MG_MODE_DIR) 69 sys_unlinkat(MG_ORGAN) 70 let w1: i64 = mg_write_text(MG_MATRIX, "@title fixture\n@cols a|b|c|d\nROW A|/tmp/nx_market_ladder_gate/fx_organ.nx|_ABSENT_:fx_sym_a|0|0|0|0|0|n\nROW B|/tmp/nx_market_ladder_gate/fx_organ.nx|_ABSENT_:fx_sym_b|0|0|0|0|0|n\n" as *u8) 71 let w2: i64 = mg_write_text(MG_PLAN, "# fixture plan\nrung|R1|one|fx_sym_a|done|Organ|1|-\nrung|R2|two|fx_sym_b|done|Organ|1|-\nladder|Open|best|have|grow|ENTER now|\nladder|Half|best|have|grow|GROW-FIRST until R2|R1,R2\nladder|None|best|have|grow|HOLD|R2\nladder|Wrong|best|have|grow|ENTER claimed|R2\nladder|Ghost|best|have|grow|HOLD|R9\n" as *u8) 72 let w3: i64 = mg_write_text(MG_PLAN_OK, "rung|R1|one|fx_sym_a|done|Organ|1|-\nrung|R2|two|fx_sym_b|done|Organ|1|-\nladder|Open|best|have|grow|ENTER now|\nladder|Half|best|have|grow|GROW-FIRST until R2|R1,R2\nladder|None|best|have|grow|HOLD|R2\n" as *u8) 73 let w3m: i64 = mg_write_text(MG_MATRIX_OK, "@title fixture\n@cols a|b|c|d\nROW A|/tmp/nx_market_ladder_gate/fx_organ.nx|_ABSENT_:fx_sym_a|0|0|0|0|0|n\nROW B|/tmp/nx_market_ladder_gate/fx_organ.nx|_ABSENT_:fx_sym_b|0|0|0|0|0|n\n" as *u8) 74 let w4: i64 = mg_write_text(MG_ORGAN, "// fixture organ: declares fx_sym_a only\nfunc fx_sym_a(x: i64) -> i64 { return x }\n" as *u8) 75 var setup: i64 = 0 76 if w1 > 0 { if w2 > 0 { if w3 > 0 { if w3m > 0 { if w4 > 0 { setup = 1 } } } } } 77 gv_check("setup-fixtures-written (matrix, plans, organ)" as *u8, setup, ctr) 78 // the fixture must START with fx_sym_b ABSENT, or the HOLD teeth report on a leftover from an earlier run 79 var absent_b: i64 = 0 80 if sd_declared(MG_ORGAN, "fx_sym_b" as *u8) == 0 { absent_b = 1 } 81 gv_check("setup-fixture-organ-lacks-fx_sym_b-before-measuring (gate is idempotent)" as *u8, absent_b, ctr) 82 83 // ---- in-process lib teeth ---- 84 let out: *i64 = sys_mmap(MG_SLOT * ML_OUT_SLOTS) as *i64 85 let c_open: i64 = ml_entry_verdict(MG_MATRIX, MG_PLAN, "" as *u8, out) 86 gv_check("lib-empty-requires-is-NO-REQUIREMENT" as *u8, (c_open == ML_NO_REQUIREMENT) as i64, ctr) 87 let c_half: i64 = ml_entry_verdict(MG_MATRIX, MG_PLAN, "R1,R2" as *u8, out) 88 var t: i64 = 0 89 if c_half == ML_GROW_FIRST { if out[ML_OUT_REQUIRED] == 2 { if out[ML_OUT_LANDED] == 1 { if out[ML_OUT_BINDING_LEN] == 2 { t = 1 } } } } 90 gv_check("lib-one-of-two-landed-is-GROW-FIRST-with-binding-R2" as *u8, t, ctr) 91 let c_none: i64 = ml_entry_verdict(MG_MATRIX, MG_PLAN, "R2" as *u8, out) 92 gv_check("lib-none-landed-is-HOLD" as *u8, (c_none == ML_HOLD) as i64, ctr) 93 let c_all: i64 = ml_entry_verdict(MG_MATRIX, MG_PLAN, "R1" as *u8, out) 94 gv_check("lib-all-landed-is-ENTER" as *u8, (c_all == ML_ENTER) as i64, ctr) 95 let c_ghost: i64 = ml_entry_verdict(MG_MATRIX, MG_PLAN, "R9" as *u8, out) 96 gv_check("lib-unknown-rung-is-UNRESOLVED-never-ENTER" as *u8, (c_ghost == ML_UNRESOLVED) as i64, ctr) 97 gv_check("lib-authored-ENTER-agrees-with-NO-REQUIREMENT" as *u8, ml_agrees(ML_ENTER, ML_NO_REQUIREMENT), ctr) 98 gv_check("lib-authored-ENTER-disagrees-with-HOLD" as *u8, (ml_agrees(ML_ENTER, ML_HOLD) == 0) as i64, ctr) 99 gv_check("lib-prose-never-disagrees" as *u8, ml_agrees(ML_PROSE, ML_HOLD), ctr) 100 // THE ORGAN-PATH RULE (2026-08-24): a matrix organ column is relative to buildroot/. Read verbatim from the 101 // nishihost root, every rung of a real domain measured landed=0 (communitypulse, 12 declared symbols read HOLD) 102 // while this gate stayed GREEN -- its fixtures are absolute /tmp paths, so the rule was never exercised here. 103 let pth: *u8 = sys_mmap(MG_CAPTURE_CAP) 104 ml_organ_path("runtime/fx.nx" as *u8, pth, MG_CAPTURE_CAP) 105 var rel_ok: i64 = 0 106 if tr_contains(pth, ml_slen(pth), "buildroot/runtime/fx.nx" as *u8) == 1 { if ml_slen(pth) == 23 { rel_ok = 1 } } 107 gv_check("lib-relative-organ-path-is-read-under-buildroot (the two-trees law)" as *u8, rel_ok, ctr) 108 ml_organ_path(MG_ORGAN, pth, MG_CAPTURE_CAP) 109 var abs_ok: i64 = 0 110 if tr_contains(pth, ml_slen(pth), MG_ORGAN) == 1 { if ml_slen(pth) == ml_slen(MG_ORGAN) { abs_ok = 1 } } 111 gv_check("lib-absolute-organ-path-passes-through-unchanged (gate fixtures)" as *u8, abs_ok, ctr) 112 113 // ---- the forked subject: exit contract and rows ---- 114 let cap: *u8 = sys_mmap(MG_CAPTURE_CAP) 115 let olen: *i64 = sys_mmap(MG_SLOT * 2) as *i64 116 let rc1: i64 = mg_run(subject, "fx" as *u8, MG_DIR_SLASH, cap, olen) 117 gv_puts(" [subject fx] rc=" as *u8); gv_num(rc1); gv_puts(" bytes=" as *u8); gv_num(olen[0]); gv_puts("\n" as *u8) 118 sys_write(1, cap, olen[0]) 119 gv_check("subject-exits-1-when-an-authored-word-disagrees" as *u8, (rc1 == MG_EXIT_DISAGREE) as i64, ctr) 120 gv_check("subject-row-Open-NO-REQUIREMENT-AGREE" as *u8, tr_contains(cap, olen[0], "level=Open authored=ENTER computed=NO-REQUIREMENT required=0 landed=0 unresolved=0 agreement=AGREE" as *u8), ctr) 121 gv_check("subject-row-Half-GROW-FIRST-binding-R2" as *u8, tr_contains(cap, olen[0], "level=Half authored=GROW-FIRST computed=GROW-FIRST required=2 landed=1 unresolved=0 binding=R2 agreement=AGREE" as *u8), ctr) 122 gv_check("subject-row-None-HOLD" as *u8, tr_contains(cap, olen[0], "level=None authored=HOLD computed=HOLD required=1 landed=0 unresolved=0 binding=R2 agreement=AGREE" as *u8), ctr) 123 gv_check("subject-row-Wrong-DISAGREE-named" as *u8, tr_contains(cap, olen[0], "level=Wrong authored=ENTER computed=HOLD required=1 landed=0 unresolved=0 binding=R2 agreement=DISAGREE" as *u8), ctr) 124 gv_check("subject-row-Ghost-UNRESOLVED" as *u8, tr_contains(cap, olen[0], "level=Ghost authored=HOLD computed=UNRESOLVED required=1 landed=0 unresolved=1" as *u8), ctr) 125 gv_check("subject-last-line-partition levels=5 agree=3 disagree=2" as *u8, tr_contains(cap, olen[0], "verdict=ML domain=fx levels=5 agree=3 disagree=2 prose=0" as *u8), ctr) 126 let rc2: i64 = mg_run(subject, "fxok" as *u8, MG_DIR_SLASH, cap, olen) 127 gv_puts(" [subject fxok] rc=" as *u8); gv_num(rc2); gv_puts("\n" as *u8) 128 gv_check("neg-control-subject-exits-0-when-every-authored-word-agrees" as *u8, (rc2 == MG_EXIT_OK) as i64, ctr) 129 130 // ---- THE BITE: land fx_sym_b in the fixture organ; HOLD must flip to ENTER ---- 131 mg_append_text(MG_ORGAN, "func fx_sym_b(y: i64) -> i64 { return y }\n" as *u8) 132 let c_none_after: i64 = ml_entry_verdict(MG_MATRIX, MG_PLAN, "R2" as *u8, out) 133 var fired_before: i64 = 0 134 if c_none == ML_HOLD { fired_before = 1 } 135 var fired_after: i64 = 0 136 if c_none_after != ML_ENTER { fired_after = 1 } 137 gv_bite("neg-control-verdict-tracks-the-source (HOLD before the symbol lands, ENTER after)" as *u8, fired_before, fired_after, ctr) 138 sys_unlinkat(MG_ORGAN) 139 140 return gv_verdict("market_ladder" as *u8, ctr, "the market-entry verdict is derived from declared symbols through one ruler, disagreement is named, unknown rungs never read ENTER" as *u8) 141}