hey.food

BACKEND / MENU FRESHNESS

Watch a menu, not a webpage

Menu Watch turns a restaurant and a local cadence into a recurring, identity-checked menu acquisition. It compares canonical snapshots, not page markup, so a redesigned website is not itself a menu change.

heyfood ask "Show me this week's menu at Abby Jane Bakeshop in Dripping Springs, Texas"

The Abby Jane proof

Abby Jane Bakeshop inspired the feature: a rotating bakery menu in Dripping Springs, Texas should not require someone to remember to check every Thursday. In a live engineering probe, the public marketing site resisted ordinary acquisition, but the locate-and-extract service followed the restaurant to its Toast ordering source and recovered 63 items across 8 sections with prices on every item.

/restaurants
find Abby Jane Bakeshop in Dripping Springs, Texas
watch every Thursday at 09:00 local time

That slash-command sequence is the planned interactive TUI surface, not a command contract in native v0.4.1. The active release can ask for the current menu through heyfood ask; native watch management remains under qualification.

From restaurant name to change event

  1. 01

    Locate the current menu

    Resolve the restaurant, rank candidate sources, reject obvious junk, and follow the strongest candidate through a bounded extraction path.

  2. 02

    Gate on restaurant identity

    Retain the evidence connecting the selected source to the restaurant. Strong evidence can activate automatically; a plausible low-confidence source needs explicit confirmation; a mismatch cannot be overridden.

  3. 03

    Freeze a local cadence

    Derive an IANA timezone from restaurant coordinates, store it with the watch, and compute each run in restaurant-local time so daylight-saving changes do not move the intended hour.

  4. 04

    Acquire without duplicate work

    Select due watches, reserve a dedicated scheduled-work budget, coalesce concurrent work for the same restaurant, and route the fetch through the same canonical acquisition gateway used elsewhere.

  5. 05

    Persist and compare

    The first successful run establishes a baseline. Later canonical snapshots produce a durable diff covering additions, removals, modifications, and price movement.

  6. 06

    Signal only a real change

    An unchanged fetch is silent. A non-empty diff can write a 30-day quick-read change event while the authoritative snapshot pair and diff remain persisted.

Subscription contract

POST   /v1/menu/watch
GET    /v1/menu/watch
DELETE /v1/menu/watch/{watch_id}

{
  "restaurant_id": "…",
  "cadence": { "weekday": 3, "hour": 9 },
  "notify": true,
  "confirm_menu_url": true
}

Watches are owned by an authenticated account or device principal. CLI sessions need the narrow menu:watch scope. Creation records the restaurant, resolved timezone, next run, notification preference, and the identity decision used to activate the watch.

What counts as a change

EventBehavior
First successful acquisitionStores the baseline; sends no change signal.
Same canonical contentKeeps the prior snapshot; sends no change signal.
New canonical snapshotPersists a snapshot-pair diff for added, removed, modified, and price-changed items.
Budget temporarily unavailableReschedules the watch for a later tick instead of dropping it.