docker-build-push / build-push (push) Successful in 5s
The first real pre-block in production exposed this. Timeline from the logs: 00:24:54.53 Mastodon calls (signup form render) 00:24:55.33 ipapi.is answers (cold lookup, new range) 00:24:55.89 ip_blocks POST 200 <- block installed, 1.35s in 00:24:56.47 statuses POST 200 <- moderator DM, 582ms 00:24:56.53 Mastodon gives up at its 2.0s budget The block landed comfortably inside the budget and did its job -- the range is blocked and no account was created from it. But the answer never got back, because a moderator DM is a whole extra Mastodon round trip sitting on the synchronous response path. Nothing the caller acts on depends on that DM. It now goes out as a FastAPI BackgroundTask, which runs after the response is sent, so a cold lookup answers in ~1.35s instead of ~1.95s. Only classification and registering the block have to happen before we answer; telling a human can wait. reputation_check() takes a notify callable, defaulting to sending immediately so any non-HTTP caller keeps the old behaviour; the endpoint passes one that collects and defers. Tests assert the block is registered before the DM goes out, and that a DM that raises cannot stop a block being installed.