guard v0.2.0 · sandbox bike store · 532 products · runs in your tab

Pre-checkout guard for AI shopping agents

Stop the wrong order before your AI agent pays.

A signed payment mandate proves your agent kept to its limits: an allowed shop, an approved item, an amount in range. It never reads what you actually said. AsOrdered does. It stands between “the cart is ready” and “pay”, and answers proceed or ask, with the question to you already written.

ordered“Giro Cadet, black, EU 42. I need to be able to return them if they pinch.”
cartGiro Cadet, black, EU 42 · Cadence Outlet · $148.99 · final sale
mandate✓ signature valid · limits satisfied
guardask: asked to be able to return it, the item is final sale
ASK

532 products · 4 shops · 100 labelled tasks + 50 in loose wording · naive agent on the 100: 80 wrong orders without the guard, 0 with it

The tubes in the margins carry orders to the till. Put the cursor on a tube and the next capsule stops there for a question. Here, you are the guard.

01

Try it

Eight orders from the open set. A naive agent bought the first search result, and the payment would have gone through. Pick an order, read what the guard says, then switch to the right purchase.

asordered · guard.check(cart)

Or write your own

Type an order the way you would say it to a person in a shop. The agent buys the first thing that matches the product words, and the guard checks the cart against all of your words before it pays.

0/300 · bike store only: helmets, tyres, shoes, lights, bottles
agent · sandbox bike storeidle

The agent here is a plain script that takes the first search result, so you can see exactly what the guard catches. Everything runs in this tab with lib/asordered.js; nothing you type leaves the page.

02

The gap

Agent payment mandates bind a purchase to a signed delegation: who said the agent may spend, where, and how much. Everything they check is real, and it verifies. What the person actually said travels along as a free-text summary that no verification code reads.

constraintexpresses
Merchant / Payeewho may be paid
LineItemswhich SKUs, how many
Amount / Budgethow much
Recurrencehow often
Expiryuntil when the mandate holds

None of them can say “in black”, “EU 42”, “returnable if it pinches”, “here by Friday” or “anything but Specialized”. A cart can carry a valid signature, sit inside every limit, and still be the wrong order. That is the whole gap, and it is where people get a size 40 that cannot be sent back.

03

Method

 words ──► parse() ──► facts ──┐
                               ├──► compare() ──┬──► proceed
 cart ─────────────────────────┘    plain code  └──► ask + question
                                    same input,
                                    same answer

Parse. A small, readable parser turns the words into facts: product, brand, colour, size, quantity, budget, deadline, returns, and what the person ruled out. No model sits in this step, so you can read every rule in one sitting and know exactly what it understood and what it did not.

Compare. Plain deterministic code puts those facts next to every line of the cart. The same order and the same cart give the same answer every time, in every browser, on every machine.

Proceed or ask. Either the cart matches and the payment goes ahead, or the agent gets the reasons and a ready question for the person, usually with the right cart already found. If the order says nothing checkable, the guard asks: it fails closed.

The point is the receipt. “The AI thought it was fine” settles nothing. “You asked to be able to return it; Cadence Outlet sells it final sale” settles it, because anyone can check it by hand.

04

Benchmark

The agent shops in an open sandbox store: 532 products from four shops. The traps come from the store itself, as in a real one: the same helmet in another colour at the same price to the cent, the same tyre cheaper at an outlet that never takes returns, the same shoe cheaper at a shop that takes eleven days. Every task carries a label written by its template, never by the parser. Each task runs once without the guard and once with it, here, in your browser, right now.

seed 1 · –
naive agent: buys the first search result · one square per task · the open 100
No guard
– / 100 wrong
With the guard
– / 100 wrong
wrong order paid · wrong cart stopped before payment (–) · right order · right orders stopped for nothing: –
templatetaskswrong, offwrong, onstopped right

Loose wording

The open 100 are written the way the templates write. People do not. The loose set is 50 tasks in the way orders actually get typed: sizes in words, “anything except the white one”, plural model names, deadlines said sideways. It exists to find what the parser misses.

templatetaskswrong, offwrong, onmissed

05

Spec and code

AsOrdered is an open reference, not a product. The guard is one ES module with no dependencies. Import it from this site and put it in front of your agent's payment step; the docs describe every fact it extracts and every reason it can return.

JS
import { Guard } from "https://asordered.vercel.app/lib/asordered.js";

const guard = new Guard("Black Giro Cadet in EU 42, " +
                        "I need to be able to return them.");
guard.check([{ name: "Giro Cadet", brand: "Giro", category: "shoes",
               colour: "White", size: "42", price: 148.99, qty: 1,
               merchant: "Cadence Outlet", returnDays: 0, deliveryDays: 5 }]);
// { decision: "ask", reasons: ["Asked for black, the item is white: …",
//   "Asked to be able to return it, the item is final sale …"], question: "Should I switch to …" }
06

Limitations

07

Token

$ASORDERED

The guard is free, open and runs without it. The coin is for everyone who has ever ordered black in 42 and opened a white 40 marked final sale. Hold it, and the next time an agent says “close enough”, you have a ticker to reply with.