1 Commits
Author SHA1 Message Date
clawbot 9e7e87b68d Rewrite TODO.md sentence by sentence (part of #157)
check / check (push) Canceled after 0s
Every sentence of TODO.md is rewritten from scratch against the rules
of #157: about 30 words at
most, one idea each, subject and verb early, identifiers in backticks.
Status and Next Step describe the repo as the tracker shows it now.
Every Completed Steps entry keeps its date, its facts and its issue
reference, checked against the commit it names. The Workflow section
keeps its meaning. The entry for this rewrite is added.

Model: fable-5-1
2026-11-02 03:55:01 +00:00
+49 -44
View File
@@ -12,12 +12,12 @@
RouteWatch is pre-1.0, with no git tags. `main` last took `next` on 2026-10-27,
through https://git.eeqj.de/sneak/routewatch/pulls/166.
https://git.eeqj.de/sneak/routewatch/pulls/202 carries the twelve commits since
then into `main`. It is labelled `merge-ready` and waits for sneak.
https://git.eeqj.de/sneak/routewatch/pulls/202 carries the commits since then
into `main`. It is labelled `merge-ready` and waits for sneak.
The linter and the tests are phases of the Docker build. The Gitea workflow runs
`script/cibuild` on every push. That script checks the formatting of the Go code
and the markdown. Then it builds the image, which runs the two phases.
`script/cibuild` on every push. That script runs the two phases and checks the
formatting of the Go code and the markdown. Then it builds the image.
The image sets memory ceilings for a 5 GiB container (README "Memory"). README
"Running under upaas" says how to run it.
@@ -37,15 +37,15 @@ https://git.eeqj.de/sneak/routewatch/issues/222, which the third fix brought up.
A 24-hour run of `26d939a` on the live feed is checking whether any handler
still drops updates.
The README rewrite, https://git.eeqj.de/sneak/routewatch/pulls/210, is paused
until sneak has reviewed it. It is part of
The README rewrite, https://git.eeqj.de/sneak/routewatch/pulls/210, has failed
three reviews. It is paused until sneak has reviewed it. It is part of
https://git.eeqj.de/sneak/routewatch/issues/157.
Two questions wait for sneak: which history the prefix page keeps
(https://git.eeqj.de/sneak/routewatch/issues/161), and which fields the IP
lookup answer gains (https://git.eeqj.de/sneak/routewatch/issues/203).
The state of what remains is kept on
The order of the project's remaining work is kept on
https://git.eeqj.de/sneak/routewatch/issues/86.
# Next Step
@@ -62,11 +62,12 @@ problem the run finds.
Steps entry keeps its date, its facts and its issue. Status and Next Step
describe the repo as the tracker shows it (part of #157)
- 2026-11-02: A skipped WHOIS lookup now makes the fetcher wait longer before
the next one, as a failed lookup does. A lookup is skipped when its registry
is paused. The longest wait is one minute. The status page does not count a
skip as a failure. A skip used to leave the wait as it was. Each lookup asks
IANA before it finds its registry paused. So while most stale ASes belonged to
a paused registry, the fetcher could ask IANA every second (closes #222)
the next one, as a failed lookup does. A lookup is skipped when its RIR is
paused. An RIR is one of the five regional Internet registries. The longest
wait is one minute. The status page does not count a skip as a failure. A skip
used to leave the wait as it was. Each lookup asks IANA which RIR holds the AS
before it finds that RIR paused. So while most stale ASes belonged to a paused
RIR, the fetcher could ask IANA every second (closes #222)
- 2026-11-02: A peer's session going down no longer stops the prefix handler.
The handler runs the routing table's `PeerDown` on a goroutine of its own, one
peer at a time. Meanwhile it goes on taking messages. `PeerDown` holds the
@@ -77,15 +78,16 @@ problem the run finds.
number, `HandleMessage` waits until one of them is applied. When `Stop` runs
past its deadline, it logs how many held-back messages were not applied
(closes #216)
- 2026-11-02: RouteWatch pauses a registry's WHOIS server for an hour after the
server refuses a query. The registries are the five RIRs (the regional
Internet registries) and NIC.br. A refused or reset connection is a refusal.
So is an answer with an `%ERROR:201:` or `%ERROR:202:` line. Lookups at the
other servers go on. An AS whose registry is paused is looked up after the
pause. IANA is never paused, because a pause of IANA would stop every lookup.
A refusal by IANA is an ordinary failure. NIC.br is also paused for an hour
after it says RouteWatch has passed its query limit. Before, the fetcher asked
a server again within seconds of a refusal (closes #218)
- 2026-11-02: RouteWatch pauses an RIR's or NIC.br's WHOIS server for an hour
after the server refuses a query. NIC.br is Brazil's registry. A refused or
reset connection is a refusal. So is an answer with an `%ERROR:201:` or
`%ERROR:202:` line. Lookups at the other servers go on. An AS whose RIR is
paused is looked up after the pause. While NIC.br is paused, a Brazilian AS
gets the details from LACNIC's answer. IANA is never paused, because a pause
of IANA would stop every lookup. A refusal by IANA is an ordinary failure.
NIC.br is also paused for an hour after it says RouteWatch has passed its
query limit. Before, the fetcher asked a server again within seconds of a
refusal (closes #218)
- 2026-11-02: The AS handler never waits for a database write. Its batch holds
one entry per AS, with the earliest and the latest time of its updates. So the
batch no longer grows with the feed's rate. It used to hold one entry for each
@@ -96,15 +98,15 @@ problem the run finds.
host. Five of them gave `HandleMessage` two seconds to apply a full prefix
batch. Under the race detector that can take longer. A test now waits up to 15
seconds for each step it expects. The tests of the handlers' limits now give
the handlers small limits. So the whole package runs well inside its 90-second
the handlers small limits. So the package no longer runs past its 90-second
limit (closes #213, #215)
- 2026-10-27: The server works out the home page's cards every minute until it
stops. It used to work them out only once, at startup. The end of the context
given to `Start` stopped the refreshes (closes #211)
- 2026-10-27: README "Rationale" says why RouteWatch exists. It answers our
other services' questions about IP addresses, from its own routing table and
the WHOIS details it keeps. The section still says what RIS Live does not give
(closes #204)
- 2026-10-27: README "Rationale" says why RouteWatch exists. RouteWatch answers
our other services' questions about IP addresses, from its own routing table
and the WHOIS details it keeps. The section still says what RIS Live does not
give (closes #204)
- 2026-10-27: Every JSON answer carries `@meta`. A panic on a JSON route answers
500 with the JSON error body. `/status.json` and the health check answer 405
with the JSON error body to any method they do not take. The 500 and the 405
@@ -184,23 +186,24 @@ problem the run finds.
uses it yet (part of #122)
- 2026-10-27: Each result of the IP lookup lists the public blocklists the
address is on, in `blocklists`. The lists are DShield, Feodo Tracker, two
FireHOL lists, Spamhaus DROP and the Tor exit list. RouteWatch downloads each
list on its own schedule and answers from copies in memory. The copies are
also kept in the state directory's `blocklists` directory. IP lookup answers
carry `Cache-Control`. An address with no route now has a result too, without
route fields. So the IP lookup no longer answers 404 (closes #158)
FireHOL lists, two Spamhaus DROP lists and the Tor exit list. RouteWatch
downloads each list on its own schedule and answers from copies in memory. The
copies are also kept in the state directory's `blocklists` directory. IP
lookup answers carry `Cache-Control`. An address with no route now has a
result too, without route fields. So the IP lookup no longer answers 404
(closes #158)
- 2026-10-27: The home page has an IP information API card. It shows the `curl`
command that looks up the visitor's own address at `/ip/{addr}`. It also shows
that command's live answer (closes #156)
- 2026-10-27: On the AS page, a click on the heading of the IPv4 or the IPv6
prefix list folds or unfolds the list. Both lists start open (closes #155)
- 2026-10-27: The AS page lists its IPv4 and its IPv6 prefixes by mask length,
shortest first. Prefixes of one mask length are listed by address. The lists
used to be in address order alone (closes #153)
- 2026-10-27: On `/` and `/status`, a spinner beside the status turns one frame
each time the stats show more messages than the time before. After three
refreshes with no new messages, the page shows "stale" in red instead. Next to
it is the time since the last fresh answer (closes #152)
shortest first. Prefixes of one mask length are listed by address. They used
to be sorted by address first, then by mask length (closes #153)
- 2026-10-27: The connection status on `/` and `/status` gets a spinner. It
turns one frame each time the stats show more messages than the time before.
After three refreshes with no new messages, the page shows "stale" in red
instead. Next to it is the time since the last fresh answer (closes #152)
- 2026-10-27: The WHOIS details of a Brazilian AS keep their accented letters.
LACNIC's answer for such an AS is NIC.br's answer with each accented letter
replaced. NIC.br is Brazil's registry. The details now come from NIC.br's own
@@ -226,8 +229,8 @@ problem the run finds.
and stored. RIPE and APNIC send Latin-1 (closes #165)
- 2026-10-27: The Age column on the AS and prefix pages reads in words, such as
"5 minutes ago" or "2 weeks ago". It used to print Go durations such as
"360h0m0s ago". An age under a minute reads in seconds. An age over a month
reads in months or years instead of a date (closes #163)
"360h0m0s ago". An age under a minute reads "now" or in seconds. An age over a
month reads in months or years instead of a date (closes #163)
- 2026-10-26: A write to a stored AS, peering or peer keeps the earlier of the
two first-seen times. It keeps the later of the two last-seen times. An old
update from a collector catching up on a backlog no longer moves last seen
@@ -382,8 +385,9 @@ problem the run finds.
- 2026-09-21: `make test` skips the live feed test, with `-short`. So
`make check` no longer depends on the network (closes #2)
- 2026-07-07: The scripts-to-rule-them-all layout is adopted. `script/` holds
the entrypoints, and the `Makefile` targets call them. README gains an
"Entrypoints" section
the entrypoints. The `Makefile` targets `check`, `test`, `lint`, `fmt` and
`fmt-check` call them. So do `bootstrap`, `setup`, `docker` and `hooks`.
README gains an "Entrypoints" section
- 2026-02-22: The repo is brought in line with the repo policies. The required
policy files are added. `.gitignore` is updated. The `Makefile` gains
`fmt-check`, `check`, `docker` and `hooks` targets. The Go code is formatted
@@ -404,6 +408,7 @@ problem the run finds.
# Future Steps
- Merge https://git.eeqj.de/sneak/routewatch/pulls/210 once sneak has reviewed
it. The last PR for https://git.eeqj.de/sneak/routewatch/issues/157 to merge
closes that issue.
- Finish https://git.eeqj.de/sneak/routewatch/pulls/210 as sneak's review
directs. It merges once a review passes. Of the two PRs for
https://git.eeqj.de/sneak/routewatch/issues/157, the one that merges last
closes the issue.