code wiki / _hdl_build / nx_swap_reward_gate.nx

nx_swap_reward_gate.nx source

↩ module page · 154 lines · 10863 B

1// nx_swap_reward_gate.nx -- GATE (capstone): the gamified swap pays REAL rewards. Composes nx_swap (the fun 2// activity) + nx_price (real store prices) + nx_rewards (real payout) at the edge (rule 22, no lib coupling). 3// When a gardener completes the Mediterranean-Herbs set by SWAPPING (not buying), the achievement pays out the 4// REAL money those herbs cost at the store + a REAL capability -- exactly "real rewards, real positives, real 5// capabilities", not a dumb badge. A non-completer earns nothing (no participation trophy). license_tier: ORIGINAL 6import "nx_swap.nx" 7import "nx_rewards.nx" 8import "nx_price.nx" 9import "nx_publisher.nx" 10import "nx_seg_store.nx" 11import "nx_syscalls.nx" 12import "nx_gate_verdict.nx" 13 14const CR_SWAP: *u8 = "knowledge/store/swrw-swap-" 15const CR_REWARD: *u8 = "knowledge/store/swrw-reward-" 16const CR_PRICE: *u8 = "knowledge/store/swrw-price-" 17const CR_STAGE_FILE: *u8 = "knowledge/staging/swrw/earned.html" 18const CR_LIVE_FILE: *u8 = "knowledge/publish/swrw-live/earned.html" 19 20func 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 } 21func g_i(v: i64) -> i64 { 22 let bb: *u8 = sys_mmap(28); var m: i64 = v 23 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 24 let t: *u8 = sys_mmap(28); var k: i64 = 0 25 if m == 0 { t[0] = 48 as u8; k = 1 } 26 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 27 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 28} 29func g_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 } 30 31// THE COMPOSITION (app-edge logic): completing a swap set awards the badge AND pays the real reward + capability. 32// Returns 1 if the gardener completed the set (and was paid), 0 otherwise. No completion -> no reward. 33func complete_and_reward(swap_pfx: *u8, reward_pfx: *u8, gid: *u8, setid: *u8, value_aid: *u8, cap_aid: *u8, day: i64) -> i64 { 34 if sw_set_complete(swap_pfx, gid, setid) == 0 { return 0 } 35 sw_award_badge(swap_pfx, gid, setid) 36 rw_grant(reward_pfx, gid, value_aid, day) 37 rw_grant(reward_pfx, gid, cap_aid, day) 38 return 1 39} 40 41func main() -> i64 { 42 g_p("=== nx_swap_reward_gate (capstone: the gamified swap pays REAL rewards) ===\n" as *u8) 43 44 // swap setup 45 sw_seed_config(CR_SWAP) 46 sw_add_species(CR_SWAP, "basil" as *u8, "Basil" as *u8, "herb" as *u8, "common" as *u8) 47 sw_add_species(CR_SWAP, "rosemary" as *u8, "Rosemary" as *u8, "herb" as *u8, "common" as *u8) 48 sw_add_species(CR_SWAP, "thyme" as *u8, "Thyme" as *u8, "herb" as *u8, "common" as *u8) 49 sw_add_species(CR_SWAP, "oregano" as *u8, "Oregano" as *u8, "herb" as *u8, "common" as *u8) 50 sw_add_species(CR_SWAP, "sage" as *u8, "Sage" as *u8, "herb" as *u8, "common" as *u8) 51 sw_add_set(CR_SWAP, "medherbs" as *u8, "Mediterranean Herbs\tbasil\trosemary\tthyme\toregano\tsage" as *u8) 52 sw_add_gardener(CR_SWAP, "alice" as *u8, "Alice" as *u8, "TX-Austin" as *u8) 53 sw_add_gardener(CR_SWAP, "bob" as *u8, "Bob" as *u8, "TX-Austin" as *u8) 54 sw_add_gardener(CR_SWAP, "cara" as *u8, "Cara" as *u8, "TX-Austin" as *u8) 55 sw_post_offer(CR_SWAP, "a_basil" as *u8, "alice" as *u8, "basil" as *u8, "cutting" as *u8, 3, "TX-Austin" as *u8, "-" as *u8) 56 sw_post_offer(CR_SWAP, "a_rose" as *u8, "alice" as *u8, "rosemary" as *u8, "cutting" as *u8, 3, "TX-Austin" as *u8, "-" as *u8) 57 sw_post_offer(CR_SWAP, "a_thyme" as *u8, "alice" as *u8, "thyme" as *u8, "seed" as *u8, 50, "TX-Austin" as *u8, "-" as *u8) 58 sw_post_offer(CR_SWAP, "a_oreg" as *u8, "alice" as *u8, "oregano" as *u8, "seed" as *u8, 50, "TX-Austin" as *u8, "-" as *u8) 59 sw_post_offer(CR_SWAP, "a_sage" as *u8, "alice" as *u8, "sage" as *u8, "cutting" as *u8, 2, "TX-Austin" as *u8, "-" as *u8) 60 sw_post_offer(CR_SWAP, "c_basil" as *u8, "cara" as *u8, "basil" as *u8, "seed" as *u8, 20, "TX-Austin" as *u8, "-" as *u8) 61 62 // real store prices -> the real value of those herbs 63 pr_add_store(CR_PRICE, "herbmart" as *u8, "Herb Mart" as *u8, "Herb Mart" as *u8, "TX-Austin" as *u8, "TX" as *u8, "receipt" as *u8) 64 pr_set_price(CR_PRICE, "herbmart" as *u8, "basil" as *u8, 300, "2025-06-20" as *u8, "plant" as *u8, "receipt" as *u8) 65 pr_set_price(CR_PRICE, "herbmart" as *u8, "rosemary" as *u8, 320, "2025-06-20" as *u8, "plant" as *u8, "receipt" as *u8) 66 pr_set_price(CR_PRICE, "herbmart" as *u8, "thyme" as *u8, 280, "2025-06-20" as *u8, "plant" as *u8, "receipt" as *u8) 67 pr_set_price(CR_PRICE, "herbmart" as *u8, "oregano" as *u8, 260, "2025-06-20" as *u8, "plant" as *u8, "receipt" as *u8) 68 pr_set_price(CR_PRICE, "herbmart" as *u8, "sage" as *u8, 300, "2025-06-20" as *u8, "plant" as *u8, "receipt" as *u8) 69 let items: *i64 = sys_mmap(8 * 8) as *i64 70 items[0] = "basil" as *u8 as i64; items[1] = "rosemary" as *u8 as i64; items[2] = "thyme" as *u8 as i64; items[3] = "oregano" as *u8 as i64; items[4] = "sage" as *u8 as i64 71 let basket: i64 = pr_basket(CR_PRICE, "herbmart" as *u8, items, 5) 72 73 // real rewards (value grounded in the real basket; capability = a real unlock) 74 rw_def_achievement(CR_REWARD, "herb_selfsuff" as *u8, "Herb self-sufficient" as *u8, "swap" as *u8, "VALUE" as *u8, basket, "-" as *u8, "price observations" as *u8) 75 rw_def_achievement(CR_REWARD, "swap_master" as *u8, "Swap Master" as *u8, "swap" as *u8, "CAPABILITY" as *u8, 0, "host_seed_library" as *u8, "completed a swap set" as *u8) 76 77 g_p("real herb basket = " as *u8); g_i(basket); g_p("c\n" as *u8) 78 79 var pass: i64 = 0 80 var tot: i64 = 0 81 82 // Bob plays: swaps for all 5 herbs (instead of buying them) 83 sw_claim_offer(CR_SWAP, "a_basil" as *u8, "bob" as *u8) 84 sw_claim_offer(CR_SWAP, "a_rose" as *u8, "bob" as *u8) 85 sw_claim_offer(CR_SWAP, "a_thyme" as *u8, "bob" as *u8) 86 sw_claim_offer(CR_SWAP, "a_oreg" as *u8, "bob" as *u8) 87 sw_claim_offer(CR_SWAP, "a_sage" as *u8, "bob" as *u8) 88 89 // T1 Bob completed the set by swapping (the fun activity) 90 let done: i64 = sw_set_complete(CR_SWAP, "bob" as *u8, "medherbs" as *u8) 91 tot = tot + 1 92 if done == 1 { if sw_dex_count(CR_SWAP, "bob" as *u8) == 5 { pass = pass + 1; g_p("PASS T1 Bob completed the Mediterranean Herbs set by SWAPPING 5 herbs (not buying)\n" as *u8) } else { g_p("FAIL T1 dex\n" as *u8) } } else { g_p("FAIL T1 not complete\n" as *u8) } 93 94 // T2 the real reward value = the real store basket (grounded, not invented) 95 tot = tot + 1 96 if basket == 1460 { if rw_ach_int(CR_REWARD, "herb_selfsuff" as *u8, 3) == basket { pass = pass + 1; g_p("PASS T2 the reward is grounded in REAL prices: herb basket $14.60 = the reward value\n" as *u8) } else { g_p("FAIL T2 mismatch\n" as *u8) } } else { g_p("FAIL T2 basket=" as *u8); g_i(basket); g_p("\n" as *u8) } 97 98 // T3 COMPOSITION: completing the swap set pays the REAL reward (money he didn't spend at the store) 99 let paid: i64 = complete_and_reward(CR_SWAP, CR_REWARD, "bob" as *u8, "medherbs" as *u8, "herb_selfsuff" as *u8, "swap_master" as *u8, 200) 100 let bobval: i64 = rw_value_total(CR_REWARD, "bob" as *u8) 101 g_p("paid=" as *u8); g_i(paid); g_p(" bob real value=" as *u8); g_i(bobval); g_p("c badge=" as *u8); g_i(sw_has_badge(CR_SWAP, "bob" as *u8, "medherbs" as *u8)); g_p("\n" as *u8) 102 tot = tot + 1 103 var ok3: i64 = 1 104 if paid != 1 { ok3 = 0 } 105 if bobval != 1460 { ok3 = 0 } 106 if sw_has_badge(CR_SWAP, "bob" as *u8, "medherbs" as *u8) != 1 { ok3 = 0 } 107 if ok3 == 1 { pass = pass + 1; g_p("PASS T3 the gamified achievement paid a REAL reward: $14.60 saved by swapping instead of buying\n" as *u8) } else { g_p("FAIL T3\n" as *u8) } 108 109 // T4 + a REAL capability unlocked (not cosmetic) 110 tot = tot + 1 111 if rw_can(CR_REWARD, "bob" as *u8, "host_seed_library" as *u8) == 1 { pass = pass + 1; g_p("PASS T4 + a real capability unlocked: Bob can now host a community seed-library node\n" as *u8) } else { g_p("FAIL T4\n" as *u8) } 112 113 // T5 NO participation trophy: Cara (only basil) completes nothing -> no badge, no real reward 114 let cpaid: i64 = complete_and_reward(CR_SWAP, CR_REWARD, "cara" as *u8, "medherbs" as *u8, "herb_selfsuff" as *u8, "swap_master" as *u8, 200) 115 let cval: i64 = rw_value_total(CR_REWARD, "cara" as *u8) 116 g_p("cara paid=" as *u8); g_i(cpaid); g_p(" value=" as *u8); g_i(cval); g_p(" badge=" as *u8); g_i(sw_has_badge(CR_SWAP, "cara" as *u8, "medherbs" as *u8)); g_p("\n" as *u8) 117 tot = tot + 1 118 var ok5: i64 = 1 119 if cpaid != 0 { ok5 = 0 } 120 if cval != 0 { ok5 = 0 } 121 if sw_has_badge(CR_SWAP, "cara" as *u8, "medherbs" as *u8) != 0 { ok5 = 0 } 122 if rw_can(CR_REWARD, "cara" as *u8, "host_seed_library" as *u8) != 0 { ok5 = 0 } 123 if ok5 == 1 { pass = pass + 1; g_p("PASS T5 no participation trophy: Cara (1/5) earns no badge, no value, no capability\n" as *u8) } else { g_p("FAIL T5\n" as *u8) } 124 125 // T6 ship Bob's real-rewards page 126 let page: *u8 = sys_mmap(65536) 127 let np: i64 = rw_render_rewards(CR_REWARD, "bob" as *u8, page) 128 tot = tot + 1 129 var ok6: i64 = 1 130 if as_has_thirdparty_js(page, np) != 0 { ok6 = 0 } 131 if as_contains(page, np, "$14.60" as *u8) != 1 { ok6 = 0 } 132 if as_contains(page, np, "host_seed_library" as *u8) != 1 { ok6 = 0 } 133 sys_mkdir("knowledge/staging" as *u8, 0x1ed) 134 sys_mkdir("knowledge/staging/swrw" as *u8, 0x1ed) 135 let sfd: i64 = sys_openat_wr(CR_STAGE_FILE, 420); if sfd >= 0 { sys_write(sfd, page, np); sys_close(sfd) } 136 pub_init() 137 sys_mkdir("knowledge/publish/swrw-stage" as *u8, 0x1ed) 138 sys_mkdir("knowledge/publish/swrw-live" as *u8, 0x1ed) 139 pub_submit_to("knowledge/publish/swrw-queue.tsv" as *u8, CR_STAGE_FILE, "earned.html" as *u8, "nishifoodfamily" as *u8, "nishi-swrw" as *u8, "internal" as *u8) 140 pub_run_full("knowledge/publish/swrw-queue.tsv" as *u8, "knowledge/publish/swrw-ledger.tsv" as *u8, "knowledge/publish/swrw-stage" as *u8, "knowledge/publish/swrw-live" as *u8, "publish:swrw" as *u8) 141 if g_exists(CR_LIVE_FILE) != 1 { ok6 = 0 } 142 if ok6 == 1 { pass = pass + 1; g_p("PASS T6 Bob's real-rewards page (the $14.60 he saved + his new capability) shipped\n" as *u8) } else { g_p("FAIL T6\n" as *u8) } 143 144 g_p("nx_swap_reward_gate pass=" as *u8); g_i(pass); g_p("/" as *u8); g_i(tot) 145 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 146 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 147 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 148 let ctr__dry: *i64 = gv_ctr() 149 ctr__dry[0] = pass 150 ctr__dry[1] = tot 151 let rc__dry: i64 = gv_verdict("SWAP-REWARD-GATE" as *u8, ctr__dry, "swap basil/rosemary instead of buying -> the reward is the REAL money you saved + a real capability)" as *u8) 152 sys_exit(rc__dry) 153 return rc__dry 154}