# Deal Alert Worker, free sample: a watch spec template, five rules and a five-check script

Version 1.0, 2026-10-28. By PaperChaseWebb. Works with Grok Bot, Claude Code, Codex and Hermes. Python 3 standard library. Tested on Linux with Python 3.13.5 as described below.

Most price alerts fail in the same ways: a price that was a parsing error, a low price eaten by delivery cost, the same alert every hour, alerts at 3 AM, and, with agent setups, a bot that could buy on its own. This sample gives you the habit that prevents most of that: write the watch down as a small spec and check it before anything runs it. Credit for the idea of one parser shared by a server engine and a browser engine, and for testing on saved real pages, goes to u/kotyzap's Deal Radar write-up: https://www.reddit.com/r/vibecoding/comments/1xe56y8/i_vibecoded_deal_radar_a_browser_extension/

## Five rules

1. Alerts go to the owner only. Not a group, not a team channel.
2. Watch the total, price plus delivery cost, and set a max_total. When delivery cost is unknown, assume a fair amount rather than zero.
3. Ask for two matching reads in a row before an alert. One bad parse is not a deal.
4. Set quiet hours in your own time zone. Deals found at night can wait for a morning batch.
5. Nothing buys on its own. The spec says purchase "owner_only" and has no checkout or auto-buy fields.

## A spec template

```json
{
 "owner": "sam",
 "timezone": "America/Chicago",
 "quiet_hours": {"start": "22:00", "end": "07:00"},
 "alert": {"channel": "ntfy", "to": "owner", "url": "https://ntfy.sh/REPLACE-WITH-A-LONG-RANDOM-TOPIC"},
 "purchase": "owner_only",
 "sources": [{"id": "shop", "kind": "jsonld", "url": "https://shop.example/lamps", "min_interval_min": 30}],
 "watches": [{"id": "lamp", "sources": ["shop"], "keywords_all": ["brass", "lamp"], "keywords_none": ["parts"], "max_total": 50, "confirm_reads": 2, "delivery_if_unknown": 15}]
}
```

Before you add a source, read its robots.txt and terms. If automated reads are not allowed, leave it out.

## A prompt for any of the four harnesses

"Check robots.txt and the terms for each site I list and tell me which allow a plain GET. Then write deal.watch.json for {item} under {total} delivered, with alerts to me only, two confirm reads, quiet hours 22:00 to 07:00 in my time zone, a delivery_if_unknown guess, and purchase owner_only. Run python3 deal_mini.py deal.watch.json until it prints 0 findings, then show me the spec. Do not start any watch and do not buy anything."

## deal_mini.py

```python
#!/usr/bin/env python3
"""Deal Alert Worker, free sample: five checks on one deal.watch.json. Read-only, standard library.
  python3 deal_mini.py deal.watch.json
Exit 0 clean, 1 findings, 2 file missing or not JSON."""
import json, re, sys

def main(p):
    try:
        spec = json.load(open(p, encoding="utf-8"))
    except Exception as e:
        print("cannot read %s (%s)" % (p, type(e).__name__)); return 2
    f = []
    if (spec.get("alert") or {}).get("to") != "owner":
        f.append("M1 alerts must go to the owner only")
    for w in spec.get("watches") or []:
        if not isinstance(w.get("max_total"), (int, float)):
            f.append("M2 watch %s has no max_total (price plus delivery cost)" % w.get("id"))
        if int(w.get("confirm_reads", 2)) < 2:
            f.append("M3 watch %s alerts on one read; ask for two matching reads" % w.get("id"))
    qh = spec.get("quiet_hours") or {}
    if not all(re.match(r"^([01]\d|2[0-3]):[0-5]\d$", str(qh.get(k, ""))) for k in ("start", "end")):
        f.append("M4 quiet_hours missing or not HH:MM")
    if spec.get("purchase", "owner_only") != "owner_only" or re.search(r"auto_?buy|checkout", json.dumps(spec), re.I):
        f.append("M5 nothing buys on its own; purchase must be owner_only")
    for x in f:
        print(x)
    print("%d findings" % len(f))
    return 1 if f else 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1] if len(sys.argv) > 1 else "deal.watch.json"))
```

## Worked example

The spec below has five problems:

```json
{
 "owner": "sam",
 "timezone": "America/Chicago",
 "alert": {"channel": "webhook", "to": "group-chat", "url": "https://hooks.example/abc"},
 "purchase": "auto_buy_under_max",
 "sources": [{"id": "shop", "kind": "jsonld", "url": "https://shop.example/lamps"}],
 "watches": [{"id": "lamp", "sources": ["shop"], "keywords_all": ["brass", "lamp"], "price_under": 50, "confirm_reads": 1}]
}
```

Tested on 2026-10-28: python3 deal_mini.py before.watch.json printed 5 findings (alerts to a group, a price limit with no delivery cost, a single read, no quiet hours, an auto-buy setting) and exited 1. The template above printed 0 findings and exited 0. A missing file exits 2.

## The full pack

Deal Alert Worker ($19) adds the runner that reads JSON-LD, JSON and RSS within robots.txt on a timer, a Cloudflare Worker and a browser extension that share one tested core, dedupe with re-arm, a morning batch after quiet hours, a watch-broken alert so a tracker never goes quiet on you, owner approvals tied to hashes, a buy-check that confirms the total before you pay, skill files for Claude Code, Codex and Hermes and a rules block for Grok Bot, fifteen checks on a seeded fixture, and a labeled eval set.

PaperChaseWebb 💸
