Project 01, 2026
WatchTower
Describe something on the web in plain words and get one alert when it happens.
Checking…All services


How it works: describe it, the agent sets up the watch, checks run quietly, and you get one alert.

The live log of a check: fetch, compare with the last snapshot, rules, then the AI judge with its confidence.

What an alert looks like: the details pulled from the page, its source, and a follow-up waiting for approval.

Everything in the app is also a JSON API with webhooks.
Interactive explainer
How a watch works
Type what you want watched to see the rule it becomes, then run checks to see how each one stops at the cheapest step that can rule it out.
This is a small model of one part of WatchTower: how a sentence becomes a watch rule, and the cost ladder each check goes down. It runs in your browser on sample data and doesn't fetch anything or call an AI model, so it isn't the app itself.Use the real WatchTower ↗
Watch rule
One scheduled check
- Fetchone shared fetch for every subscriber
- Hash gateskip if the page bytes are identical
- Noise filterignore counters, clocks and ads
- Rulescheap checks like price < 50000
- Triage modelsmall, fast model: worth a closer look?
- Judge modelmust quote evidence from the page
Each check stops at the first step that can rule it out.
Checking job portals, exam sites and price pages by hand is tedious, and plain change detectors fire on every counter and clock. WatchTower decides whether the condition you described is really met.
The hard part
Deciding whether a changed page really meets a plain-English condition without paying for an LLM call on every check. Each check walks a cost ladder and stops as early as it can, and the judge at the top has to quote the page word for word, which is verified before any alert goes out. If the model is down or over budget, the run is deferred instead of guessed.
In numbers
- ~150test functions across unit, integration, agent, security, end-to-end and load suitessource ↗
- 40+SSRF bypass attempts the URL guard is tested againstsource ↗
- 70+real queries in the intake test setsource ↗
Figures as stated in the repo. Evals are small samples, and the repo says so.
What I built
WatchTower lets you describe something on the public web in plain language, such as “tell me when this exam notice changes”, and keeps watching it for you. Agents turn the sentence into a tested watch, check the page on a schedule, decide whether the condition is actually met, do any follow-up work, and send one complete notification. Watches can be shared, so one check serves every subscriber.
How it works
Four LangGraph agents do the work: intake (screen, analyse, discover sources, dry run, create), evaluation, act, and refinement. The API is stateless and the scheduler and workers scale as replicas. Postgres is the source of truth, and Redis only holds queues, caches, streams and rate-limit state, so flushing it loses nothing.
Each scheduled check goes down a cost ladder and stops as early as it can: shared fetch, hash gate, learned noise filter, rules, a fast triage model, and finally the smart judge model. Progress streams to the browser over SSE.
Decisions worth noting
- The scheduler claims due checks with
FOR UPDATE SKIP LOCKEDand leases, so no leader election is needed. - The judge has to return a verbatim evidence quote. It is verified against the page and rejected if it cannot be found.
- LLM outages or budget limits defer a run without updating state, so a change is never silently swallowed.
- Redis mirrors Groq’s per-model request and token limits across all processes, and 15% of daily requests are reserved for interactive intake.
- Page text is treated as hostile: hidden DOM is stripped, content is fenced with an HMAC nonce, and links and dates must be grounded in the page.
- Alerts and deliveries are unique per fingerprint and channel, so a notification can’t go out twice.