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, 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. through https://git.eeqj.de/sneak/routewatch/pulls/166.
https://git.eeqj.de/sneak/routewatch/pulls/202 carries the twelve commits since https://git.eeqj.de/sneak/routewatch/pulls/202 carries the commits since then
then into `main`. It is labelled `merge-ready` and waits for sneak. 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 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 `script/cibuild` on every push. That script runs the two phases and checks the
and the markdown. Then it builds the image, which runs the two phases. 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 The image sets memory ceilings for a 5 GiB container (README "Memory"). README
"Running under upaas" says how to run it. "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 A 24-hour run of `26d939a` on the live feed is checking whether any handler
still drops updates. still drops updates.
The README rewrite, https://git.eeqj.de/sneak/routewatch/pulls/210, is paused The README rewrite, https://git.eeqj.de/sneak/routewatch/pulls/210, has failed
until sneak has reviewed it. It is part of three reviews. It is paused until sneak has reviewed it. It is part of
https://git.eeqj.de/sneak/routewatch/issues/157. https://git.eeqj.de/sneak/routewatch/issues/157.
Two questions wait for sneak: which history the prefix page keeps Two questions wait for sneak: which history the prefix page keeps
(https://git.eeqj.de/sneak/routewatch/issues/161), and which fields the IP (https://git.eeqj.de/sneak/routewatch/issues/161), and which fields the IP
lookup answer gains (https://git.eeqj.de/sneak/routewatch/issues/203). 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. https://git.eeqj.de/sneak/routewatch/issues/86.
# Next Step # Next Step
@@ -62,11 +62,12 @@ problem the run finds.
Steps entry keeps its date, its facts and its issue. Status and Next Step 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) 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 - 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 the next one, as a failed lookup does. A lookup is skipped when its RIR is
is paused. The longest wait is one minute. The status page does not count a paused. An RIR is one of the five regional Internet registries. The longest
skip as a failure. A skip used to leave the wait as it was. Each lookup asks wait is one minute. The status page does not count a skip as a failure. A skip
IANA before it finds its registry paused. So while most stale ASes belonged to used to leave the wait as it was. Each lookup asks IANA which RIR holds the AS
a paused registry, the fetcher could ask IANA every second (closes #222) 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. - 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 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 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 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 past its deadline, it logs how many held-back messages were not applied
(closes #216) (closes #216)
- 2026-11-02: RouteWatch pauses a registry's WHOIS server for an hour after the - 2026-11-02: RouteWatch pauses an RIR's or NIC.br's WHOIS server for an hour
server refuses a query. The registries are the five RIRs (the regional after the server refuses a query. NIC.br is Brazil's registry. A refused or
Internet registries) and NIC.br. A refused or reset connection is a refusal. reset connection is a refusal. So is an answer with an `%ERROR:201:` or
So is an answer with an `%ERROR:201:` or `%ERROR:202:` line. Lookups at the `%ERROR:202:` line. Lookups at the other servers go on. An AS whose RIR is
other servers go on. An AS whose registry is paused is looked up after the paused is looked up after the pause. While NIC.br is paused, a Brazilian AS
pause. IANA is never paused, because a pause of IANA would stop every lookup. gets the details from LACNIC's answer. IANA is never paused, because a pause
A refusal by IANA is an ordinary failure. NIC.br is also paused for an hour of IANA would stop every lookup. A refusal by IANA is an ordinary failure.
after it says RouteWatch has passed its query limit. Before, the fetcher asked NIC.br is also paused for an hour after it says RouteWatch has passed its
a server again within seconds of a refusal (closes #218) 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 - 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 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 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 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 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 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) limit (closes #213, #215)
- 2026-10-27: The server works out the home page's cards every minute until it - 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 stops. It used to work them out only once, at startup. The end of the context
given to `Start` stopped the refreshes (closes #211) given to `Start` stopped the refreshes (closes #211)
- 2026-10-27: README "Rationale" says why RouteWatch exists. It answers our - 2026-10-27: README "Rationale" says why RouteWatch exists. RouteWatch answers
other services' questions about IP addresses, from its own routing table and our other services' questions about IP addresses, from its own routing table
the WHOIS details it keeps. The section still says what RIS Live does not give and the WHOIS details it keeps. The section still says what RIS Live does not
(closes #204) give (closes #204)
- 2026-10-27: Every JSON answer carries `@meta`. A panic on a JSON route answers - 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 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 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) uses it yet (part of #122)
- 2026-10-27: Each result of the IP lookup lists the public blocklists the - 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 address is on, in `blocklists`. The lists are DShield, Feodo Tracker, two
FireHOL lists, Spamhaus DROP and the Tor exit list. RouteWatch downloads each FireHOL lists, two Spamhaus DROP lists and the Tor exit list. RouteWatch
list on its own schedule and answers from copies in memory. The copies are downloads each list on its own schedule and answers from copies in memory. The
also kept in the state directory's `blocklists` directory. IP lookup answers copies are also kept in the state directory's `blocklists` directory. IP
carry `Cache-Control`. An address with no route now has a result too, without lookup answers carry `Cache-Control`. An address with no route now has a
route fields. So the IP lookup no longer answers 404 (closes #158) 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` - 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 command that looks up the visitor's own address at `/ip/{addr}`. It also shows
that command's live answer (closes #156) 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 - 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) 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, - 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 shortest first. Prefixes of one mask length are listed by address. They used
used to be in address order alone (closes #153) to be sorted by address first, then by mask length (closes #153)
- 2026-10-27: On `/` and `/status`, a spinner beside the status turns one frame - 2026-10-27: The connection status on `/` and `/status` gets a spinner. It
each time the stats show more messages than the time before. After three turns one frame each time the stats show more messages than the time before.
refreshes with no new messages, the page shows "stale" in red instead. Next to After three refreshes with no new messages, the page shows "stale" in red
it is the time since the last fresh answer (closes #152) 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. - 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 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 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) 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 - 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 "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 "360h0m0s ago". An age under a minute reads "now" or in seconds. An age over a
reads in months or years instead of a date (closes #163) 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 - 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 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 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 - 2026-09-21: `make test` skips the live feed test, with `-short`. So
`make check` no longer depends on the network (closes #2) `make check` no longer depends on the network (closes #2)
- 2026-07-07: The scripts-to-rule-them-all layout is adopted. `script/` holds - 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 the entrypoints. The `Makefile` targets `check`, `test`, `lint`, `fmt` and
"Entrypoints" section `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 - 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 policy files are added. `.gitignore` is updated. The `Makefile` gains
`fmt-check`, `check`, `docker` and `hooks` targets. The Go code is formatted `fmt-check`, `check`, `docker` and `hooks` targets. The Go code is formatted
@@ -404,6 +408,7 @@ problem the run finds.
# Future Steps # Future Steps
- Merge https://git.eeqj.de/sneak/routewatch/pulls/210 once sneak has reviewed - Finish https://git.eeqj.de/sneak/routewatch/pulls/210 as sneak's review
it. The last PR for https://git.eeqj.de/sneak/routewatch/issues/157 to merge directs. It merges once a review passes. Of the two PRs for
closes that issue. https://git.eeqj.de/sneak/routewatch/issues/157, the one that merges last
closes the issue.