Apache... You were right, the source was (sort of) .htaccess.
Specifically:
RewriteCond %{REQUEST_URI} !^/site/
RewriteRule ^(.*)$ /site/$1
Which of course allows the site to load from root despite Grav being located in the /site/ subdirectory.
Interestingly this rewrite has been there since the site was launched, though the problem hasn't.
Also, because it only applies to /site/ at the beginning of the URI it would ignore the word site anywhere else, and definitely wouldn't have the capability to rewrite 'site' to 'config' (the word config is not present in any .htaccess in the directory tree).
I confirmed this by changing the redirect to a 301 so I could see what it's doing.
So I guess this is now an edge case bug report 🙂
Anyway, now that I know what's causing it, I can work around it. Thanks for your help!