code wiki / (root) / nx_skills_emit.nx

nx_skills_emit.nx source

↩ module page · 154 lines · 8412 B

1// nx_skills_emit.nx -- MAIN: seed the skill layer for a dish and render its skills surface. 2// 3// Idempotent (rule 10): every seed is a value-compare put. Separate organ from nx_meal_emit so the recipe page 4// and the skills page can each be re-rendered without touching the other's stores. 5// 6// The seeded levels are DELIBERATELY incomplete: this household has been assessed on the knife and the pan but 7// has NEVER braised. That is the common real case, and it exercises the disclosure rather than hiding it -- 8// the cook-from-scratch option becomes unrankable, the page says exactly why, and the recommendation falls to 9// something we can actually compare. 10// 11// argv[1] = output html path (default /tmp/kitchen-skills.html) 12// license_tier: ORIGINAL No hw writes (Rule 26). 13import "_hdl_build/nx_meal_skills_page.nx" 14import "_hdl_build/nx_meal_cost.nx" 15import "_hdl_build/nx_meal_effort.nx" 16import "_hdl_build/nx_skill_video.nx" 17import "_hdl_build/nx_meal_plan.nx" 18import "nx_syscalls.nx" 19const SE_MAGIC_2500: i64 = 2500 20const SE_MAGIC_1800: i64 = 1800 21const SE_MAGIC_2600: i64 = 2600 22const SE_MAGIC_2900: i64 = 2900 23const SE_MAGIC_3600: i64 = 3600 24 25const SE_PAGE: i64 = 262144 26const SE_WARC: i64 = 4194304 27const SE_MODE: i64 = 420 28const SE_SALE_FLOOR: i64 = 50 29const SE_INTAKE_PORT: i64 = 8033 30const SE_RATE: i64 = 2500 // $25.00/hour -- this household's own stated value for an hour 31 32func se_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 33func se_n(v: i64) -> i64 { 34 let b: *u8 = sys_mmap(32) 35 let t: *u8 = sys_mmap(32) 36 var m: i64 = v 37 var k: i64 = 0 38 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 39 if m == 0 { t[0] = 48 as u8; k = 1 } 40 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 41 var i: i64 = 0 42 while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 43 sys_write(1, b, k) 44 return 0 45} 46func se_port_open(port: i64) -> i64 { 47 let fd: i64 = sys_socket(2, 1, 0) 48 if fd < 0 { return 0 } 49 let addr: *u8 = sys_mmap(16) 50 var i: i64 = 0 51 while i < 16 { addr[i] = 0 as u8; i = i + 1 } 52 addr[0] = 2 as u8 53 addr[2] = ((port >> 8) & 255) as u8 54 addr[3] = (port & 255) as u8 55 addr[4] = 127 as u8 56 addr[7] = 1 as u8 57 let r: i64 = sys_connect(fd, addr, 16) 58 sys_close(fd) 59 if r < 0 { return 0 } 60 return 1 61} 62func se_write_file(path: *u8, buf: *u8, n: i64) -> i64 { 63 let fd: i64 = sys_openat_wr(path, SE_MODE) 64 if fd < 0 { return 0 - 1 } 65 sys_write(fd, buf, n) 66 sys_close(fd) 67 return n 68} 69 70func main(argc: i64, argv: *i64) -> i64 { 71 let meal: *u8 = "knowledge/store/meal-" as *u8 72 let inv: *u8 = "knowledge/store/inv-" as *u8 73 let price: *u8 = "knowledge/store/price-" as *u8 74 let vp: *u8 = "knowledge/store/skillvid-" as *u8 75 let curr: *u8 = "knowledge/store/coach-curriculum-" as *u8 76 let warcpath: *u8 = "knowledge/store/meal.warc" as *u8 77 let rid: *u8 = "beefstew" as *u8 78 let unit: *u8 = "wests" as *u8 79 80 var outpath: *u8 = "/tmp/kitchen-skills.html" as *u8 81 if argc > 1 { outpath = argv[1] as *u8 } 82 83 // ---------------- the skill tree: broad -> specific ---------------- 84 ef_add_skill(meal, "knife" as *u8, "Knife skills" as *u8, ef_empty(), "Everything done with a blade on a board" as *u8) 85 ef_add_skill(meal, "dicing" as *u8, "Dicing" as *u8, "knife" as *u8, "Even cubes, consistent size" as *u8) 86 ef_add_skill(meal, "dice-onion" as *u8, "Dice an onion" as *u8, "dicing" as *u8, "Root-on, horizontal then vertical, claw grip" as *u8) 87 ef_add_skill(meal, "chop-veg" as *u8, "Rough-chop vegetables" as *u8, "knife" as *u8, "Carrot and celery to even pieces" as *u8) 88 ef_add_skill(meal, "heat" as *u8, "Heat control" as *u8, ef_empty(), "Reading a pan and adjusting" as *u8) 89 ef_add_skill(meal, "sear" as *u8, "Searing" as *u8, "heat" as *u8, "Dry surface, hot pan, do not crowd" as *u8) 90 ef_add_skill(meal, "braise" as *u8, "Braising" as *u8, "heat" as *u8, "Bare tremble, lid on, low and long" as *u8) 91 92 // ---------------- the dish as ACTIVE steps ---------------- 93 ef_add_step(meal, rid, 0, "Dice the onion" as *u8, "dice-onion" as *u8, 300) 94 ef_add_step(meal, rid, 1, "Chop the carrot and celery" as *u8, "chop-veg" as *u8, 300) 95 ef_add_step(meal, rid, 2, "Brown the chuck in batches" as *u8, "sear" as *u8, 600) 96 ef_add_step(meal, rid, 3, "Build and set the braise" as *u8, "braise" as *u8, 300) 97 98 // ---------------- pace multipliers as DATA (base = a competent cook, level 2) ---------------- 99 ef_set_tmul(meal, 0, SE_MAGIC_2500) 100 ef_set_tmul(meal, 1, SE_MAGIC_1800) 101 ef_set_tmul(meal, 2, 1000) 102 ef_set_tmul(meal, 3, 850) 103 ef_set_tmul(meal, 4, 700) 104 105 // ---------------- this household: assessed on the knife and the pan, NEVER on a braise ---------------- 106 ef_set_level(meal, unit, "dice-onion" as *u8, 1) 107 ef_set_level(meal, unit, "chop-veg" as *u8, 2) 108 ef_set_level(meal, unit, "sear" as *u8, 2) 109 ef_set_timevalue(meal, unit, SE_RATE) 110 111 // ---------------- what it would cost to skip the cooking ---------------- 112 ef_add_alt(meal, rid, "prepped" as *u8, SE_MAGIC_2600, 12, "store deli counter" as *u8, "2026-08-05" as *u8) 113 ef_add_alt(meal, rid, "frozen" as *u8, SE_MAGIC_2900, 10, "freezer aisle" as *u8, "2026-08-04" as *u8) 114 ef_add_alt(meal, rid, "restaurant" as *u8, SE_MAGIC_3600, 0, "neighbourhood bistro" as *u8, "2026-08-06" as *u8) 115 116 // ---------------- who you can learn from ---------------- 117 sv_add_chef(vp, "kenji" as *u8, "J. Kenji Lopez-Alt" as *u8, "@kenji" as *u8, "https://www.seriouseats.com/" as *u8) 118 sv_add_chef(vp, "julia" as *u8, "Julia Child" as *u8, "@juliachild" as *u8, "https://www.pbs.org/food/chefs/julia-child/" as *u8) 119 120 sv_add_video(vp, "kd1" as *u8, "dice-onion" as *u8, "Knife Skills: how to dice an onion" as *u8, "Serious Eats" as *u8, "pro" as *u8, "https://www.seriouseats.com/knife-skills-how-to-dice-an-onion" as *u8, "publisher terms" as *u8, 420, "kenji" as *u8) 121 sv_add_video(vp, "ad1" as *u8, "dice-onion" as *u8, "Dicing onions in a normal kitchen" as *u8, "a home cook" as *u8, "amateur" as *u8, "https://commons.wikimedia.org/wiki/Category:Onion_cutting" as *u8, "CC BY-SA" as *u8, 240, sv_empty()) 122 sv_add_video(vp, "cv1" as *u8, "chop-veg" as *u8, "Rough-chopping mirepoix" as *u8, "Wikibooks Cookbook" as *u8, "pro" as *u8, "https://en.wikibooks.org/wiki/Cookbook:Mirepoix" as *u8, "CC BY-SA 3.0" as *u8, 180, sv_empty()) 123 sv_add_video(vp, "sr1" as *u8, "sear" as *u8, "Why you should not crowd the pan" as *u8, "Serious Eats" as *u8, "pro" as *u8, "https://www.seriouseats.com/the-maillard-reaction" as *u8, "publisher terms" as *u8, 360, "kenji" as *u8) 124 sv_add_video(vp, "br1" as *u8, "braise" as *u8, "Braising, the bare tremble" as *u8, "Wikibooks Cookbook" as *u8, "pro" as *u8, "https://en.wikibooks.org/wiki/Cookbook:Braising" as *u8, "CC BY-SA 3.0" as *u8, 300, sv_empty()) 125 126 se_p(" seed: skills, steps, levels, alternatives, chefs and sources\n" as *u8) 127 128 // ---------------- the shopping total, from the SAME engine the recipe page uses ---------------- 129 let items: *i64 = sys_mmap(8 * 64) as *i64 130 let ni: i64 = mp_items(meal, rid, items) 131 let sum: *i64 = sys_mmap(8 * MC_SLOTS) as *i64 132 mc_meal(inv, "wests" as *u8, price, "seattle" as *u8, items, ni, SE_SALE_FLOOR, sum) 133 let complete: i64 = mc_total_is_complete(sum) 134 se_p(" cost: scratch shopping = " as *u8); se_n(sum[MC_BUY_CENTS]); se_p(" cents, complete=" as *u8); se_n(complete); se_p("\n" as *u8) 135 136 let warc: *u8 = sys_mmap(SE_WARC) 137 var wl: i64 = wa_load(warcpath, warc, SE_WARC) 138 if wl < 0 { wl = 0 } 139 140 let live: i64 = se_port_open(SE_INTAKE_PORT) 141 if live == 1 { se_p(" intake: :8033 answering -- the request form will render\n" as *u8) } else { se_p(" intake: :8033 NOT listening -- request form SUPPRESSED\n" as *u8) } 142 143 let page: *u8 = sys_mmap(SE_PAGE) 144 let n: i64 = msp_render(page, meal, vp, curr, unit, rid, warc, wl, sum[MC_BUY_CENTS], complete, live, "/kitchen.html" as *u8) 145 if se_write_file(outpath, page, n) < 0 { 146 se_p("NX-SKILLS-EMIT FAIL cannot write " as *u8); se_p(outpath); se_p("\n" as *u8) 147 sys_exit(1) 148 return 1 149 } 150 se_p("NX-SKILLS-EMIT OK bytes=" as *u8); se_n(n) 151 se_p(" path=" as *u8); se_p(outpath); se_p("\n" as *u8) 152 sys_exit(0) 153 return 0 154}