Standing spend rules for the house.
Alexa+ filled a $250 cart and added things people excluded. A yes on checkout does not stop the next restock. Latch is the rule that stays after the chat dies.
Grant a cap. It restocks inside that cap. A price jump holds. You undo until 9pm. You revoke, and it stops.
Not a shopping chatbot. Not “confirm this one order.” Not a booking receipt.
Amazon Developer Hackathon · Alexa+ track · 23 Oct 2026. Product name is Latch.
- Grant: Hill’s Science Diet 15lb, max $40, fire at 3 days left, hold if price jumps 15 percent, undo until 9pm. Card shows LCH-14.
- Time-skip to 3 days. It buys at $28. Card shows LED-8821 and mock order ORD-440.
- Kill the tab. “What did you buy?” Same IDs.
- Mutate the fixture to $33. Trigger. Hold. No charge.
- Undo the $28 buy. Ledger is
undone. - Revoke. Next trigger is
denied.
Speech is illegal without entry_id and provider_ref. Empty ledger → it says it failed.
Local: npm run dev then open the printed URL. Buttons on the left are the tape.
| # | Case | Pass |
|---|---|---|
| 1 | Grant then trigger → commit under cap | committed + LED- + ORD- |
| 2 | Excluded SKU (Sony under a Hill’s rule) | denied / excluded_sku |
| 3 | Price +18% | held / price_jump |
| 4 | Undo before 9pm | undone |
| 5 | Undo after deadline | rejected |
| 6 | Revoke then trigger | denied / rule_revoked |
| 7 | New session | same entry_id |
| 8 | Empty ledger | cannot say “bought” |
| 9 | Qty 2 when max 1 | denied / qty_exceeded |
| 10 | Clock advance, no grant | no buy |
npm test
- MCP 2025-11-25 Streamable HTTP at
POST /mcp - Tools:
grant_latch,get_latch,run_triggers,undo_entry,revoke_latch - Demo-gated:
advance_clock,set_catalog_price - Cards:
/apps/grant.html,/apps/hold.html,/apps/ledger.html(resourceUrion mutating results) - State: D1 rules + ledger. Catalog: KV fixture
hills-15lb/sony-headphones - Household:
X-Latch-Household. No MCP session id required. - Privacy / terms:
/privacy,/terms
Friction Amazon asked for: FRICTION.md.
Needs Node and Wrangler. No Token Factory key. No model.
npm install
npx wrangler types
npx wrangler d1 migrations apply latch --local
npm test
npm run dev
Deploy only when you want a public URL:
npx wrangler d1 create latch
npx wrangler kv namespace create CATALOG
# put the real ids in wrangler.jsonc, then:
npx wrangler types
npx wrangler d1 migrations apply latch --remote
npx wrangler deploy
Custom hostname later: mcp.latch.<your-domain>.
- No runtime LLM
- No real Amazon cart
- No VoiceCart
confirmed=truecheckout - No restaurant booking
- No Alexa or Amazon in the product name
Law: PRODUCT.md. Design: DESIGN.md.