code wiki / _hdl_build / nx_meal_cost.nx
nx_meal_cost.nx
buildroot/runtime/_hdl_build/nx_meal_cost.nx
about
nx_meal_cost.nx -- LIB: the PANTRY x PRICE bridge. nx_pantry knows what a unit already HAS; nx_price knows
what things COST and where. Nothing joined them, so no surface could answer the question a meal planner
exists to answer: "given what is already in my kitchen, what does cooking THIS actually cost me today, and
what is cheap right now?"
TWO HONESTY INVARIANTS, both gate-enforced, because both failures make food look cheaper than it is:
1. AN UNPRICED INGREDIENT IS NEVER WORTH ZERO. An item we hold no observation for is counted in its own
bucket (MC_UNPRICED) and NEVER folded into the total. Summing only what we happen to know the price of
produces a confident, precise, WRONG number -- the most expensive kind.
2. A CHEAP BASKET AT A STORE THAT STOCKS ALMOST NOTHING IS NOT A CHEAP BASKET. pr_basket deliberately
SKIPS items a store does not carry, so a shop stocking 1 of 5 ingredients posts the lowest total and
would win "cheapest store" outright. mc_best_store therefore requires FULL coverage before a store may
compete at all.
"On sale" is MEASURED, never claimed: it means this store's recorded price sits at least `min_delta_cents`
below the area MEDIAN for that item (nx_price's own competitiveness frame). The threshold is a PARAMETER,
never a literal in here (rule 11) -- and a non-positive threshold FAILS CLOSED rather than marking the
whole shop on sale. Prices stay what nx_price says they are: dated observations with a source, surfaced
with mc_price_asof / mc_price_source so a page can never imply live pricing it does not have.
Integer cents throughout, no float. license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 3 imports · 4 importers
imports: nx_pantry.nxnx_price.nxnx_syscalls.nx
imported by: nx_meal_cost_gate.nxnx_meal_emit.nxnx_meal_page.nxnx_skills_emit.nx
structs
| none |
consts
| 29 | const MC_HAVE: i64 = 0 // in the pantry (qty > 0) -- costs nothing to cook today |
| 30 | const MC_BUY: i64 = 1 // must buy, and we DO hold a price observation |
| 31 | const MC_UNPRICED: i64 = 2 // must buy, and we hold NO observation -- never counted as free |
| 34 | const MC_N_HAVE: i64 = 0 |
| 35 | const MC_N_BUY: i64 = 1 |
| 36 | const MC_N_UNPRICED: i64 = 2 |
| 37 | const MC_BUY_CENTS: i64 = 3 |
| 38 | const MC_SALE_CENTS: i64 = 4 |
| 39 | const MC_PANTRY_CENTS: i64 = 5 |
| 40 | const MC_SLOTS: i64 = 6 |
| 42 | const MC_SIDCAP: i64 = 96 |
| 43 | const MC_MAXSTORES: i64 = 256 |
| 46 | const MC_OBS_DATE: i64 = 1 |
| 47 | const MC_OBS_UNIT: i64 = 2 |
| 48 | const MC_OBS_SOURCE: i64 = 3 |
functions
| 51 | func mc_sidbuf() -> *u8 { if MC_SID == 0 { MC_SID = sys_mmap(MC_SIDCAP) as i64 } return MC_SID as *u8 } |
| 56 | func mc_status(inv_prefix: *u8, domain: *u8, price_prefix: *u8, area: *u8, item: *u8) -> i64 |
| 64 | func mc_unit_price(price_prefix: *u8, area: *u8, item: *u8, out_sid: *u8) -> i64 |
| 69 | func mc_sale_delta(price_prefix: *u8, area: *u8, item: *u8) -> i64 |
| 81 | func mc_is_on_sale(price_prefix: *u8, area: *u8, item: *u8, min_delta_cents: i64) -> i64 |
| 89 | func mc_price_obs(price_prefix: *u8, area: *u8, item: *u8, f: i64, out: *u8) -> i64 |
| 94 | func mc_price_asof(price_prefix: *u8, area: *u8, item: *u8, out: *u8) -> i64 { return mc_price_obs(price_prefix, area, item, MC_OBS_DATE, out) } |
| 95 | func mc_price_source(price_prefix: *u8, area: *u8, item: *u8, out: *u8) -> i64 { return mc_price_obs(price_prefix, area, item, MC_OBS_SOURCE, out) } |
| 101 | func mc_meal(inv_prefix: *u8, domain: *u8, price_prefix: *u8, area: *u8, items: *i64, nitems: i64, min_sale: i64, out: *i64) -> i64 called by 2: mainmpg_render calls 6: mc_sidbufmc_statusiv_valuepr_cheapestmc_is_on_salemc_sale_delta |
| 129 | func mc_buy_list(inv_prefix: *u8, domain: *u8, price_prefix: *u8, area: *u8, items: *i64, nitems: i64, out_items: *i64, out_cents: *i64) -> i64 |
| 146 | func mc_have_list(inv_prefix: *u8, domain: *u8, items: *i64, nitems: i64, out_items: *i64) -> i64 |
| 159 | func mc_store_covers(price_prefix: *u8, sid: *u8, items: *i64, nitems: i64) -> i64 |
| 168 | func mc_best_store(price_prefix: *u8, area: *u8, items: *i64, nitems: i64, out_sid: *u8) -> i64 |
| 192 | func mc_total_is_complete(out: *i64) -> i64 |