The problem with Backbone.js and Spine.js gracefully degrading History API routing to hash fragment routing is that it’s entirely reasonable to want to use both the History API and hash fragments together in an AJAX app.
You might want to use them together, the History API to manage the state of the apps dominant view, and hash fragments to manage sidebar navigation (an UI style that’s very common in iPad apps, for example).
Not to mention the fact that by using hash fragments for graceful degradation you are committing to maintaining two versions of all of the app’s urls for a very, very long time.
It means you need to maintain support for all of the hash fragment urls in your js code.
The server doesn’t even get to see the hash so it can’t route you to the correct content, it has to send the reader a js app, which then decides what to fetch and load via ajax. The server can’t do any redirection because it never even sees the hash fragment.
So, when you use the History API with a fallback to hashChange, you end up maintaining:
All of the regular URLs on the server, for search engine crawlers, those who navigate directly, via bookmarks, etc.
JS routing for all of the regular URLs for whatever fancy History API-based navigation effect you need it for.
JS routing for all of the hash fragment versions of the URLs for all legacy browsers (which will be around for a very very long time).
Also, remember, the hash fragment versions don’t get any benefit from basic HTTP features, such as redirects.
You could leave it all to the framework you’re using (and you probably should), but all of this adds to the complexity of the app, reduces its flexibility and thus makes it more likely to be buggy and brittle.
The sensible thing, for content sites, would be to gracefully degrade from History API support to just no ajax whatsoever, and always maintain the purity of the URL. Apps that don’t need to be crawled (like Gmail) can OTOH stick to using hash fragments to maintain state.