chadtmiller.com/knotless
git that lives in your Atmosphere account
/favicon.ico goes to the pages' icon, not a handle's profile
MergedThis routes GET /favicon.ico in web::pages to a permanent redirect to /favicon.svg. That is the icon app.html names. The route sits before the fallback, so the pages never see the request or look up a handle named favicon.ico. The test checks the 308 and the Location header without following the redirect. docs/design/serve.md is updated as AGENTS.md asks. I found nothing that needs changing. I did not run the checks, and I did not confirm that a favicon.svg file exists in the pages' static assets. The only reference I found is the <link> in app.html. crates/knotless/tests/oauth.rs also requests /favicon.ico. It most likely goes through a different front, so I left it alone.
8 passed, 2 skipped
Crawlers ask for
/favicon.icowhatever a page names, and the pages drew it as the profile of a handlefavicon.ico, which sent a lookup to every handle resolver: one on prod took 35 s at Bluesky's. Now serve answers it with a 308 to/favicon.svg. A quick look will do.Claude Opus 5.5 · high
What changes
web::pagesroutesGET /favicon.icoto a permanent redirect to/favicon.svg, the iconapp.htmlnames, before the fallback that hands everything else to the pages.docs/design/serve.md(Crawlers) says so.Why
Prod's
admin_logs, trace6dc00c12beb91862601e84f7f26e52c9(Nov 9, 11:50): ameta-externalagentcrawler's/favicon.icowent to the pages, which askedgetProfileandgetActorReposforactor=favicon.ico.favicon.icois a valid handle by syntax, so it was looked up:/.well-known/atproto-did(DNS fails at once), thencom.atproto.identity.resolveHandleatpublic.api.bsky.app, which answered 400 after 35,364 ms. The page itself answered 404 in 217 ms, butgetActorReposheld its request the whole time.How it was checked
pages_drawn_elsewhereintests/web.rsasks the front for/favicon.icowithout following redirects: 308 to/favicon.svg, never handed to the app. Left to CI.Shortcomings
Any other single path segment that is a valid handle by syntax still goes to the profile page and is looked up. The resolver at Bluesky has no timeout of ours: it is a configured service, and a 35 s answer was seen once.