/** * checkout-reading-input.ts, accepting a checkout reading from the model. * * ══ Why the model reads the page ══════════════════════════════════════════ * * Browser control is general. The model reads a page, decides, clicks and * types; a checkout is the same primitive as a signup form. A table of * per-merchant selectors would be scaffolding that thinks for the model, and it * is brittle in the way that matters most, merchants rewrite their markup * constantly, so a selector table is a permanent maintenance tax that buys * nothing the model cannot already do. * * So the model reports what it read as STRUCTURED VALUES, per-line label, * quantity and unit price, the tax line, each fee, each delivery option, the * currency, and the daemon does everything the model cannot be trusted to do * with them. * * ══ What "cannot be trusted" means here, precisely ════════════════════════ * * Not that the model is adversarial. That the numbers came off a page, and a * page is written by whoever runs it. By the time a value reaches this module * it has been through a process that read attacker-chosen text, so it carries * that text's authority, which is none. * * The split that follows from it: * * THE MODEL finds the values on the page and reports them. * THE DAEMON parses them to integers with its own parser, checks the * cart against what the owner asked for, looks for a * recurring charge, applies the budget, renders the owner's * message from its own integers, runs the window, fills the * card and records the purchase. * * Every number the owner reads is one the daemon computed. A string the model * reported never reaches the owner's phone, and a number it reported never * reaches a budget comparison without being re-parsed here first. * * ══ Why these numbers are not taint-checked ═══════════════════════════════ * * Deliberately, and taint-gate.ts already documents the reasoning: the price, * tax, fees and delivery costs are READ FROM THE MERCHANT by definition, so * taint-checking them would refuse every purchase, and a check that is * permanently tripped gets removed. * * Their defence is the BUDGET. A page that inflates a price hits the daily item * budget or the per-purchase ceiling and needs an approval, and that approval * shows our own re-rendered number beside the budget it would consume. * * What IS taint-checked stays taint-checked: the merchant, the checkout url, * the item and any stated limit come from the owner or the purchase is refused. * The owner names what they want and where from; the page only gets to say * what it costs, and only within a limit they set. */ import type { RawCheckoutReading } from './checkout-extraction.js'; export type ReadingInputResult = { readonly ok: true; readonly reading: RawCheckoutReading; } | { readonly ok: false; readonly reason: string; readonly field: string; }; /** * Validate a checkout reading supplied over the control plane. * * Shape and bounds only, this does not interpret a single value. Meaning is * `extractCheckout`'s job, and keeping the two apart is what lets the parser be * strict without this layer having to guess what a caller meant. */ export declare function readCheckoutReadingInput(params: Record): ReadingInputResult; //# sourceMappingURL=checkout-reading-input.d.ts.map