Jeff, as some already did I strongly disagree with your Expires header part for a simple reason: latency.
And the fact that most browsers only handle 2 parallel connections by default. This means that everytime a browser has to check the cache headers of the server for two files at the same time, everything is blocked until the requests comes back, a small but significant fraction of a second later, especially over high-latency connections (e.g. 3G or – worse – EDGE).
By using Expires on everything static (images, CSS, JS) you ensure that these won’t even exist and the browsing experience will be much smoother.
I don’t exactly use Yahoo’s rules on the subject though, they suggest putting the Expires in the far future for everything and using version numbers in the names, I usually prefer (unless I have automated the build of the website, which also happens) having a far-future Expires for images (that usually don’t need to be debugged once they’re in prod) and a nearer future for resources that may need evolution/debugging (CSS and JS)