I believe I have found the answer.
Two things were bothering me about this:
Firstly, I knew I wasn't handling static files as efficiently as I could have been, it was a job I hadn't gotten around to yet but the static files were being delivered via routing code in the main go script rather than declared in the app.yaml
Using the latter method would let app engine do the work rather than my script and hopefully save a few precious processor cycles.
Secondly I wasn't exactly sure how index.html was being served when the path was "/", it was just working. I know that various web servers (Apache, IIS, etc) have a default page and app engine seemed to be working the same way.
So when I was deciding that each request didn't require any dynamic script I would simply serve it with the following code:
http.ServeFile(w, r, r.URL.Path[1:])
This magically turned "/" into "/index.html" for me but appears to have the caching bug described above. I will take this up with the Go community.
As for the fix, adding the page as a static file to the app.yaml made this work:
- url: /
static_files: index.html
upload: index.html
I will make sure I add all the other static folders too.