code wiki / _hdl_build / nx_swap_gate.nx

nx_swap_gate.nx source

↩ module page · 158 lines · 10852 B

1// nx_swap_gate.nx -- GATE: gamified community swap + sovereign ads. T1 species catalog + gardeners + empty dex. 2// T2 ask/give matching + AREA isolation (find offers near me, not across the country). T3 THE SWAP exchange 3// (claim an offer -> get the plant by swapping, not buying; dex grows). T4 gamification (XP -> LEVEL up). T5 4// SETS + BADGES ("gotta grow 'em all"; incomplete gardener gets no badge). T6 the sovereign board renders with 5// a CONTEXTUAL ad slot (selected by topic, labelled Sponsored, no tracking / no third-party JS) + ships. 6// license_tier: ORIGINAL 7import "nx_swap.nx" 8import "nx_ads.nx" 9import "nx_publisher.nx" 10import "nx_seg_store.nx" 11import "nx_syscalls.nx" 12 13const SG_SWAP: *u8 = "knowledge/store/swap-" 14const SG_ADS: *u8 = "knowledge/store/ads-" 15const SG_STAGE_FILE: *u8 = "knowledge/staging/swap/board.html" 16const SG_LIVE_FILE: *u8 = "knowledge/publish/swap-live/board.html" 17 18func g_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 19func g_i(v: i64) -> i64 { 20 let bb: *u8 = sys_mmap(28); var m: i64 = v 21 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 22 let t: *u8 = sys_mmap(28); var k: i64 = 0 23 if m == 0 { t[0] = 48 as u8; k = 1 } 24 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 25 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 26} 27func g_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 } 28 29func main() -> i64 { 30 g_p("=== nx_swap_gate (gamified community swap + sovereign ads) ===\n" as *u8) 31 sw_seed_config(SG_SWAP) 32 33 // species catalog (our own "creatures" = real plants) 34 sw_add_species(SG_SWAP, "basil" as *u8, "Basil" as *u8, "herb" as *u8, "common" as *u8) 35 sw_add_species(SG_SWAP, "rosemary" as *u8, "Rosemary" as *u8, "herb" as *u8, "common" as *u8) 36 sw_add_species(SG_SWAP, "thyme" as *u8, "Thyme" as *u8, "herb" as *u8, "common" as *u8) 37 sw_add_species(SG_SWAP, "oregano" as *u8, "Oregano" as *u8, "herb" as *u8, "common" as *u8) 38 sw_add_species(SG_SWAP, "sage" as *u8, "Sage" as *u8, "herb" as *u8, "common" as *u8) 39 sw_add_species(SG_SWAP, "saffron" as *u8, "Saffron Crocus" as *u8, "herb" as *u8, "rare" as *u8) 40 sw_add_set(SG_SWAP, "medherbs" as *u8, "Mediterranean Herbs\tbasil\trosemary\tthyme\toregano\tsage" as *u8) 41 42 // gardeners 43 sw_add_gardener(SG_SWAP, "alice" as *u8, "Alice" as *u8, "TX-Austin" as *u8) 44 sw_add_gardener(SG_SWAP, "bob" as *u8, "Bob" as *u8, "TX-Austin" as *u8) 45 sw_add_gardener(SG_SWAP, "cara" as *u8, "Cara" as *u8, "TX-Austin" as *u8) 46 sw_add_gardener(SG_SWAP, "dan" as *u8, "Dan" as *u8, "CA-LA" as *u8) 47 48 // alice grows the full Mediterranean herb garden and offers all 5 (TX-Austin) 49 sw_post_offer(SG_SWAP, "a_basil" as *u8, "alice" as *u8, "basil" as *u8, "cutting" as *u8, 3, "TX-Austin" as *u8, "fresh" as *u8) 50 sw_post_offer(SG_SWAP, "a_rose" as *u8, "alice" as *u8, "rosemary" as *u8, "cutting" as *u8, 3, "TX-Austin" as *u8, "-" as *u8) 51 sw_post_offer(SG_SWAP, "a_thyme" as *u8, "alice" as *u8, "thyme" as *u8, "seed" as *u8, 50, "TX-Austin" as *u8, "-" as *u8) 52 sw_post_offer(SG_SWAP, "a_oreg" as *u8, "alice" as *u8, "oregano" as *u8, "seed" as *u8, 50, "TX-Austin" as *u8, "-" as *u8) 53 sw_post_offer(SG_SWAP, "a_sage" as *u8, "alice" as *u8, "sage" as *u8, "cutting" as *u8, 2, "TX-Austin" as *u8, "-" as *u8) 54 // cara also offers basil in Austin; dan offers basil in LA (for area isolation) 55 sw_post_offer(SG_SWAP, "c_basil" as *u8, "cara" as *u8, "basil" as *u8, "seed" as *u8, 20, "TX-Austin" as *u8, "-" as *u8) 56 sw_post_offer(SG_SWAP, "d_basil" as *u8, "dan" as *u8, "basil" as *u8, "seed" as *u8, 20, "CA-LA" as *u8, "-" as *u8) 57 // bob asks for basil 58 sw_post_request(SG_SWAP, "b_req1" as *u8, "bob" as *u8, "basil" as *u8, "TX-Austin" as *u8) 59 60 // a contextual ad (indexed under the "herbs" topic, not under any viewer) 61 ads_add(SG_ADS, "seedlib" as *u8, "Nishi heirloom herb seeds" as *u8, "Start your own Mediterranean herb patch with open-pollinated, swap-friendly seed." as *u8, "Nishi Seed Library" as *u8, "herbs" as *u8) 62 ads_add(SG_ADS, "tomatoad" as *u8, "Brandywine tomato starts" as *u8, "-" as *u8, "Nishi Market" as *u8, "tomato" as *u8) 63 64 var pass: i64 = 0 65 var tot: i64 = 0 66 67 // T1 catalog + empty dex 68 let bn: *u8 = sys_mmap(48); sw_species_field(SG_SWAP, "basil" as *u8, 0, bn) 69 let bobdex0: i64 = sw_dex_count(SG_SWAP, "bob" as *u8) 70 g_p("species basil=" as *u8); g_p(bn); g_p(" bob dex=" as *u8); g_i(bobdex0); g_p("\n" as *u8) 71 tot = tot + 1 72 var ok1: i64 = 1 73 if fd_streq(bn, "Basil" as *u8) != 1 { ok1 = 0 } 74 if bobdex0 != 0 { ok1 = 0 } 75 if ok1 == 1 { pass = pass + 1; g_p("PASS T1 species catalog + gardeners; new gardener starts with an empty garden-dex\n" as *u8) } else { g_p("FAIL T1\n" as *u8) } 76 77 // T2 matching + area isolation 78 let m_atx: *i64 = sys_mmap(8 * 64) as *i64 79 let m_la: *i64 = sys_mmap(8 * 64) as *i64 80 let n_atx: i64 = sw_find_offers(SG_SWAP, "basil" as *u8, "TX-Austin" as *u8, m_atx) 81 let n_la: i64 = sw_find_offers(SG_SWAP, "basil" as *u8, "CA-LA" as *u8, m_la) 82 g_p("basil offers: Austin=" as *u8); g_i(n_atx); g_p(" LA=" as *u8); g_i(n_la); g_p("\n" as *u8) 83 tot = tot + 1 84 if n_atx == 2 { if n_la == 1 { pass = pass + 1; g_p("PASS T2 ask/give match + AREA isolation (Austin basil=2: Alice+Cara; LA basil=1: Dan, not mixed)\n" as *u8) } else { g_p("FAIL T2 la\n" as *u8) } } else { g_p("FAIL T2 atx=" as *u8); g_i(n_atx); g_p("\n" as *u8) } 85 86 // T3 THE SWAP: bob claims alice's 5 offers -> gets the plants by swapping 87 let c1: i64 = sw_claim_offer(SG_SWAP, "a_basil" as *u8, "bob" as *u8) 88 sw_claim_offer(SG_SWAP, "a_rose" as *u8, "bob" as *u8) 89 sw_claim_offer(SG_SWAP, "a_thyme" as *u8, "bob" as *u8) 90 sw_claim_offer(SG_SWAP, "a_oreg" as *u8, "bob" as *u8) 91 sw_claim_offer(SG_SWAP, "a_sage" as *u8, "bob" as *u8) 92 let bobdex: i64 = sw_dex_count(SG_SWAP, "bob" as *u8) 93 g_p("after swaps: bob dex=" as *u8); g_i(bobdex); g_p(" has rosemary=" as *u8); g_i(sw_dex_has(SG_SWAP, "bob" as *u8, "rosemary" as *u8)); g_p(" a_basil still open=" as *u8); g_i(sw_offer_open(SG_SWAP, "a_basil" as *u8)); g_p("\n" as *u8) 94 tot = tot + 1 95 var ok3: i64 = 1 96 if c1 != 1 { ok3 = 0 } 97 if bobdex != 5 { ok3 = 0 } 98 if sw_dex_has(SG_SWAP, "bob" as *u8, "rosemary" as *u8) != 1 { ok3 = 0 } 99 if sw_offer_open(SG_SWAP, "a_basil" as *u8) != 0 { ok3 = 0 } // claimed offer is no longer open 100 if ok3 == 1 { pass = pass + 1; g_p("PASS T3 the swap: Bob got 5 herbs incl rosemary by SWAPPING (not buying); offers marked claimed\n" as *u8) } else { g_p("FAIL T3\n" as *u8) } 101 102 // T4 gamification: XP -> level up 103 let bxp: i64 = sw_xp(SG_SWAP, "bob" as *u8) 104 let blv: i64 = sw_level(SG_SWAP, "bob" as *u8) 105 let alv: i64 = sw_level(SG_SWAP, "alice" as *u8) 106 g_p("bob xp=" as *u8); g_i(bxp); g_p(" level=" as *u8); g_i(blv); g_p(" | alice (gave 5) level=" as *u8); g_i(alv); g_p("\n" as *u8) 107 tot = tot + 1 108 var ok4: i64 = 1 109 if bxp != 175 { ok4 = 0 } // 5 x (receive 10 + new-species 25) 110 if blv != 4 { ok4 = 0 } // 1 + 175/50 111 if alv <= 1 { ok4 = 0 } // alice leveled up from giving 112 if ok4 == 1 { pass = pass + 1; g_p("PASS T4 gamification: Bob earned 175 XP -> Level 4; Alice leveled up from giving\n" as *u8) } else { g_p("FAIL T4\n" as *u8) } 113 114 // T5 sets + badges 115 let bcomplete: i64 = sw_set_complete(SG_SWAP, "bob" as *u8, "medherbs" as *u8) 116 let awarded: i64 = sw_award_badge(SG_SWAP, "bob" as *u8, "medherbs" as *u8) 117 let ccomplete: i64 = sw_set_complete(SG_SWAP, "cara" as *u8, "medherbs" as *u8) 118 let cawarded: i64 = sw_award_badge(SG_SWAP, "cara" as *u8, "medherbs" as *u8) 119 g_p("bob set-complete=" as *u8); g_i(bcomplete); g_p(" badge=" as *u8); g_i(sw_has_badge(SG_SWAP, "bob" as *u8, "medherbs" as *u8)); g_p(" | cara complete=" as *u8); g_i(ccomplete); g_p(" badge=" as *u8); g_i(cawarded); g_p("\n" as *u8) 120 tot = tot + 1 121 var ok5: i64 = 1 122 if bcomplete != 1 { ok5 = 0 } 123 if awarded != 1 { ok5 = 0 } 124 if sw_has_badge(SG_SWAP, "bob" as *u8, "medherbs" as *u8) != 1 { ok5 = 0 } 125 if ccomplete != 0 { ok5 = 0 } // cara only has basil 126 if cawarded != 0 { ok5 = 0 } 127 if ok5 == 1 { pass = pass + 1; g_p("PASS T5 set complete -> Bob earns the Mediterranean Herbs badge; Cara (1/5) earns nothing\n" as *u8) } else { g_p("FAIL T5\n" as *u8) } 128 129 // T6 sovereign board + contextual ad + ship 130 let page: *u8 = sys_mmap(65536) 131 let np: i64 = sw_render_board(SG_SWAP, SG_ADS, "TX-Austin" as *u8, "bob" as *u8, "medherbs" as *u8, page) 132 g_p("board = " as *u8); g_i(np); g_p(" bytes\n" as *u8) 133 tot = tot + 1 134 var ok6: i64 = 1 135 if as_has_thirdparty_js(page, np) != 0 { ok6 = 0 } 136 if as_contains(page, np, "Level " as *u8) != 1 { ok6 = 0 } 137 if as_contains(page, np, "5 / 5" as *u8) != 1 { ok6 = 0 } // set progress 138 if as_contains(page, np, "Sponsored" as *u8) != 1 { ok6 = 0 } // ad slot present 139 if as_contains(page, np, "Nishi heirloom herb seeds" as *u8) != 1 { ok6 = 0 } // contextual ad (herbs) 140 if as_contains(page, np, "not who you are" as *u8) != 1 { ok6 = 0 } // privacy stance shown 141 if as_contains(page, np, "from Cara" as *u8) != 1 { ok6 = 0 } // local open offer shown 142 if as_contains(page, np, "from Dan" as *u8) != 0 { ok6 = 0 } // LA offer NOT shown (area) 143 sys_mkdir("knowledge/staging" as *u8, 0x1ed) 144 sys_mkdir("knowledge/staging/swap" as *u8, 0x1ed) 145 let sfd: i64 = sys_openat_wr(SG_STAGE_FILE, 420); if sfd >= 0 { sys_write(sfd, page, np); sys_close(sfd) } 146 pub_init() 147 sys_mkdir("knowledge/publish/swap-stage" as *u8, 0x1ed) 148 sys_mkdir("knowledge/publish/swap-live" as *u8, 0x1ed) 149 pub_submit_to("knowledge/publish/swap-queue.tsv" as *u8, SG_STAGE_FILE, "board.html" as *u8, "nishifoodfamily" as *u8, "nishi-swap" as *u8, "internal" as *u8) 150 pub_run_full("knowledge/publish/swap-queue.tsv" as *u8, "knowledge/publish/swap-ledger.tsv" as *u8, "knowledge/publish/swap-stage" as *u8, "knowledge/publish/swap-live" as *u8, "publish:swap" as *u8) 151 if g_exists(SG_LIVE_FILE) != 1 { ok6 = 0 } 152 if ok6 == 1 { pass = pass + 1; g_p("PASS T6 sovereign gamified board + contextual ad (no tracking, no third-party JS), shipped\n" as *u8) } else { g_p("FAIL T6\n" as *u8) } 153 154 g_p("nx_swap_gate pass=" as *u8); g_i(pass); g_p("/" as *u8); g_i(tot) 155 if pass == tot { g_p(" verdict=GREEN (ask + give plants, gamified + fun, sovereign ads, our own IP, gift economy)\n" as *u8); return 0 } 156 g_p(" verdict=RED\n" as *u8) 157 return 1 158}