code wiki / _hdl_build / nx_cook_coach.nx
nx_cook_coach.nx source
↩ module page · 145 lines · 9777 B
1// nx_cook_coach.nx -- COOKING as a discipline of the EXISTING curriculum coach. No new engine.
2//
3// nx_coach_curriculum_lib already does the whole loop: serve a framework's required elements, take a
4// SELF-REPORT of which ones you actually did, name what was missing, hand back that element's drill. Its own
5// header says it: "coaching is coaching -- same loop, self-report instead of a sensor." Knife technique is
6// structurally identical to its NVC framework: the required elements are the target chord, what you did is the
7// played notes, missing is the gap. So cooking is ROWS, not code. This file is a data seeder and a self-gate.
8//
9// THE SKILL IDS ARE THE JOIN. dice-onion / chop-veg / sear / braise are the same ids nx_meal_effort uses in its
10// skill tree, so the coach and the opportunity-cost engine talk about the same skill: assessed level drives how
11// long a step takes, which drives whether cooking the dish is the right call at all. Different ids here would
12// have quietly produced two unrelated systems that both looked right.
13//
14// WHY SELF-REPORT AND NOT VIDEO. nx_pose_coach can already compare a pose track to a reference and name the
15// worst joint. What does NOT exist is video -> keypoints: nx_video_pose_coder declares itself PARTIAL_WIRED
16// with VIDEO_DECODE / NEURAL_NET_INFERENCE / POSE_KEYPOINT_DETECTION missing, and nx_pose_estimate caps itself
17// at coarse single-joint classification on our own renders. So the honest coaching surface today is the
18// checklist, and the camera path stays closed until the tracks are real.
19//
20// argv[1] = store prefix (default: the live coach-curriculum plane). Pass a /tmp prefix to gate cleanly.
21// license_tier: ORIGINAL No hw writes (Rule 26).
22import "nx_coach_curriculum_lib.nx"
23import "nx_gate_verdict.nx"
24import "nx_syscalls.nx"
25
26// Seed the cooking frameworks. Same key grammar as every other discipline in this store:
27// <skill>:prompt | <skill>:n | <skill>:elem:<i> | <skill>:drill:<i>
28func cook_seed(prefix: *u8) -> i64 {
29 let w: *i64 = ss_begin()
30
31 // ---- DICE AN ONION (5 elements) ----
32 cc_add(w, "dice-onion:prompt" as *u8, "Dice a yellow onion for the braise. Which of these did you actually do?" as *u8)
33 cc_add(w, "dice-onion:n" as *u8, "5" as *u8)
34 cc_add(w, "dice-onion:elem:0" as *u8, "Root left ON until the end (it holds the layers together)" as *u8)
35 cc_add(w, "dice-onion:elem:1" as *u8, "Claw grip -- knuckles guide the blade, fingertips tucked under" as *u8)
36 cc_add(w, "dice-onion:elem:2" as *u8, "Tip stays on the board, the blade rocks through" as *u8)
37 cc_add(w, "dice-onion:elem:3" as *u8, "Horizontal cuts before the vertical ones" as *u8)
38 cc_add(w, "dice-onion:elem:4" as *u8, "Even thickness -- the pieces finish cooking together" as *u8)
39 cc_add(w, "dice-onion:drill:0" as *u8, "halve the onion and cut TO the root, never through it -- ten cuts, slowly" as *u8)
40 cc_add(w, "dice-onion:drill:1" as *u8, "curl the fingertips under and let the blade ride your knuckles; twenty slow cuts, no speed" as *u8)
41 cc_add(w, "dice-onion:drill:2" as *u8, "plant the tip and rock -- if the whole blade lifts off the board, slow down" as *u8)
42 cc_add(w, "dice-onion:drill:3" as *u8, "hand flat on top, blade parallel to the board, two horizontal cuts before any vertical ones" as *u8)
43 cc_add(w, "dice-onion:drill:4" as *u8, "dice one onion, then find the widest and narrowest piece and close that gap next time" as *u8)
44
45 // ---- ROUGH-CHOP VEGETABLES (4 elements) ----
46 cc_add(w, "chop-veg:prompt" as *u8, "Chop the carrot and celery for the braise. Which of these did you do?" as *u8)
47 cc_add(w, "chop-veg:n" as *u8, "4" as *u8)
48 cc_add(w, "chop-veg:elem:0" as *u8, "Flat side down first -- a round vegetable rolls into your fingers" as *u8)
49 cc_add(w, "chop-veg:elem:1" as *u8, "Claw grip throughout" as *u8)
50 cc_add(w, "chop-veg:elem:2" as *u8, "Pieces sized to the cook time (a braise wants them chunky)" as *u8)
51 cc_add(w, "chop-veg:elem:3" as *u8, "Board stabilised (damp towel underneath)" as *u8)
52 cc_add(w, "chop-veg:drill:0" as *u8, "trim one side flat before any other cut -- make it the first move every time" as *u8)
53 cc_add(w, "chop-veg:drill:1" as *u8, "same knuckle-guide drill as dicing; the grip does not change per vegetable" as *u8)
54 cc_add(w, "chop-veg:drill:2" as *u8, "cut a carrot for a 3-hour braise and one for a stir-fry side by side; feel the difference" as *u8)
55 cc_add(w, "chop-veg:drill:3" as *u8, "wet a paper towel under the board -- if the board slides, nothing above it is safe" as *u8)
56
57 // ---- SEAR (4 elements) ----
58 cc_add(w, "sear:prompt" as *u8, "Brown the chuck before it braises. Which of these did you do?" as *u8)
59 cc_add(w, "sear:n" as *u8, "4" as *u8)
60 cc_add(w, "sear:elem:0" as *u8, "Surface patted DRY (wet meat steams instead of browning)" as *u8)
61 cc_add(w, "sear:elem:1" as *u8, "Pan properly preheated before anything went in" as *u8)
62 cc_add(w, "sear:elem:2" as *u8, "Single layer, not crowded -- browned in batches" as *u8)
63 cc_add(w, "sear:elem:3" as *u8, "Left undisturbed until it released on its own" as *u8)
64 cc_add(w, "sear:drill:0" as *u8, "pat dry, then leave the meat uncovered in the fridge 30 minutes before cooking" as *u8)
65 cc_add(w, "sear:drill:1" as *u8, "heat until a flicked water drop SKITTERS rather than sizzles, then add fat" as *u8)
66 cc_add(w, "sear:drill:2" as *u8, "weigh the meat and brown it in two halves; crowding drops the pan temperature" as *u8)
67 cc_add(w, "sear:drill:3" as *u8, "set a three-minute timer and do not touch it -- it lets go when the crust has formed" as *u8)
68
69 // ---- BRAISE (4 elements) ----
70 cc_add(w, "braise:prompt" as *u8, "Set the braise. Which of these did you do?" as *u8)
71 cc_add(w, "braise:n" as *u8, "4" as *u8)
72 cc_add(w, "braise:elem:0" as *u8, "Liquid partway up the meat, not over the top (that is a boil, not a braise)" as *u8)
73 cc_add(w, "braise:elem:1" as *u8, "Brought to a BARE tremble, never a rolling boil" as *u8)
74 cc_add(w, "braise:elem:2" as *u8, "Lid on, heat low, left alone" as *u8)
75 cc_add(w, "braise:elem:3" as *u8, "Rested before serving" as *u8)
76 cc_add(w, "braise:drill:0" as *u8, "fill to two-thirds up the meat and mark the pot; check it at the same line next time" as *u8)
77 cc_add(w, "braise:drill:1" as *u8, "watch for one bubble every second or two -- if it rolls, the meat goes tough and stringy" as *u8)
78 cc_add(w, "braise:drill:2" as *u8, "lid on and hands off for the first hour; every lift costs you heat and time" as *u8)
79 cc_add(w, "braise:drill:3" as *u8, "rest twenty minutes off the heat before serving, and taste the difference against last time" as *u8)
80
81 return ss_commit(prefix, w, sys_now_ms())
82}
83
84func main(argc: i64, argv: *i64) -> i64 {
85 var prefix: *u8 = CC_PFX
86 if argc > 1 { prefix = argv[1] as *u8 }
87
88 let ctr: *i64 = gv_ctr()
89 gv_head("nx_cook_coach -- cooking as ROWS in the existing curriculum coach, not a second engine" as *u8)
90
91 cook_seed(prefix)
92 let h: *i64 = ss_open(prefix)
93 if (h as i64) == 0 {
94 cc_puts(" curriculum store open FAILED\n" as *u8)
95 sys_exit(1)
96 return 1
97 }
98
99 // ---- T1 the frameworks landed in the shared store, in its own grammar ----
100 var t1: i64 = 1
101 if cc_element_count(h, "dice-onion" as *u8) != 5 { t1 = 0 }
102 if cc_element_count(h, "chop-veg" as *u8) != 4 { t1 = 0 }
103 if cc_element_count(h, "sear" as *u8) != 4 { t1 = 0 }
104 if cc_element_count(h, "braise" as *u8) != 4 { t1 = 0 }
105 gv_check("T1 four cooking frameworks readable through the SHARED engine (5/4/4/4 elements)" as *u8, t1, ctr)
106
107 // ---- T2 a complete attempt advances ----
108 var t2: i64 = 1
109 if cc_missing_mask(h, "dice-onion" as *u8, 31) != 0 { t2 = 0 } // all 5 bits set
110 if cc_missing_mask(h, "sear" as *u8, 15) != 0 { t2 = 0 } // all 4 bits set
111 gv_check("T2 a self-report with every element present grades COMPLETE" as *u8, t2, ctr)
112
113 // ---- T3 the missing element is NAMED, and it is the right one ----
114 // reported doing everything EXCEPT the claw grip (bit 1)
115 let miss: i64 = cc_missing_mask(h, "dice-onion" as *u8, 29)
116 var t3: i64 = 1
117 if miss != 2 { t3 = 0 } // exactly bit 1
118 let ol: *i64 = sys_mmap(16) as *i64
119 let em: *u8 = cc_element(h, "dice-onion" as *u8, 1, ol)
120 if ol[0] == 0 { t3 = 0 }
121 let dr: *u8 = cc_drill(h, "dice-onion" as *u8, 1, ol)
122 if ol[0] == 0 { t3 = 0 }
123 gv_check("T3 the one skipped element is identified by index and carries its own drill" as *u8, t3, ctr)
124
125 // ---- T4 BITE: an unknown skill must never grade as a perfect attempt ----
126 var unk_bad: i64 = 0
127 if cc_missing_mask(h, "souffle" as *u8, 31) < 0 { unk_bad = 1 } // never taught -> refuses
128 var unk_good: i64 = 0
129 if cc_missing_mask(h, "braise" as *u8, 15) < 0 { unk_good = 1 } // taught -> grades
130 gv_bite("T4 an untaught skill REFUSES to grade instead of returning a flawless zero-missing" as *u8, unk_bad, unk_good, ctr)
131
132 // ---- T5 the interpersonal disciplines still work: one store, many disciplines ----
133 var t5: i64 = 1
134 cc_seed(prefix)
135 let h2: *i64 = ss_open(prefix)
136 if (h2 as i64) == 0 { t5 = 0 } else {
137 if cc_element_count(h2, "confront" as *u8) != 4 { t5 = 0 }
138 if cc_element_count(h2, "dice-onion" as *u8) != 5 { t5 = 0 }
139 }
140 gv_check("T5 cooking and the interpersonal frameworks coexist in ONE store -- adoption, not a fork" as *u8, t5, ctr)
141
142 let rc: i64 = gv_verdict("COOK-COACH" as *u8, ctr, "a new discipline cost rows and zero engine; an untaught skill refuses to grade" as *u8)
143 sys_exit(rc)
144 return 0
145}