This is a long, deep, technical post. The goal is to share Greasemonkey's history, to help explain how the decisions made in Greasemonkey 1.0 were reached. Hopefully if you have any interest in user scripting, and especially if you are a script author, you'll find it enlightening.
Greasemonkey is at least seven and a half years old (version 0.2.5 was released on March 28, 2005; version 0.2 seems to date from January 14th, version 0.1 from way back on December 6th, 2004). Greasemonkey in particular and user scripting in general, not to mention the browser platforms they rely upon, have come a long way in the past eight years or so.
One of the early great scripts was Book Burro, which allowed users to compare book prices at Amazon, Barnes & Noble, and others, right on the existing web page. This was possible only because GM_xmlhttpRequest allowed the user script to break the same origin policy that would be applied to a normal XMLHTTPRequest call made by a web page. The ability to store persistent values and use them at next run also enabled things like adding a search history to GMail.
These features aren't provided to normal scripts on web pages, because they can be dangerous. They were provided to scripts, because the user has much more control over which scripts they choose to install. Links clicked online can point to any web site, with any potentially malicious goal, so they're much harder to control ahead of time. It was in July of 2005 that Mark Pilgrim pointed out the giant unfortunate security hole in the way that Greasemonkey gave user scripts access to these more powerful APIs, which made it possible for malicious pages to access and use them.
This is when Greasemonkey's security sandbox came into being. Greasemonkey version 0.3 was public at the time that this security problem became evident. Version 0.4 was in development, but was scrapped to build 0.5 which contained the security fix, later in the same month. It was right at this time that Mozilla was implementing XPCNativeWrappers into Firefox. This formed the core of the execution model that Greasemonkey has used ever since, until the release of Greasemonkey 1.0, a span of over seven years. An entire article, at least this long, could be written just on the repercussions of this change. In short, as the linked page says, "
The Greasemonkey Hacks O'Reilly book which was in progress at the time needed to be completely rewritten, as many of the scripts it contained would no longer function properly. As part of this rewrite, the Avoid Common Pitfalls section was added, based on the author's insight from reading and re-writing dozens of scripts to deal with the issues this security focused change caused. (And the pitfalls commonly tripped up script authors.)
This was the only intentional backwards-incompatible change (anything else was a bug, and fixed) in Greasemonkey's eight year history, until version 1.0. I bring this up primarily to stress the point that we really do care about maintaining compatibility. We broke it again in version 1.0, and not lightly, but rather because after years of experience (and changes around us), we decided it was the right thing to do.
Let's not forget unsafeWindow. This beast was created back when the legacy security sandbox was added. Some times, you just need to poke at the content scope. With the legacy sandbox, sometimes unsafeWindow is the only way to do this. But that name wasn't picked lightly. The unsafeWindow object is unsafe! Back in 2008, I figured out a way around the security sandbox, for any script that used unsafeWindow for any purpose. That particular hole has been patched, and we're not aware of any others. But that doesn't mean they don't exist.
Unfortunately, usage of unsafeWindow is extremely widespread. My API usage survey showed it to be the most commonly used Greasemonkey feature, where using none at all was the only more common case. Nearly one of five scripts use it. And there's always the chance that it could cause real security or privacy issues, through some avenue which we simply aren't aware of yet. If so any site that a script accesses via unsafeWindow could gain all of the Greasemonkey APIs. Which means GM_xmlhttpRequest, and the ability to interact with any site you're logged into, whether it's Facebook or your bank.
The way we chose to do this is to make the APIs an opt-in feature, rather than on by default for everybody like they always were before. This is what the @grant metadata does. It says "I really need it, so I want this special API for my script" and, as a result, I'm willing to deal with the limitations of the security sandbox it will be put into.
But for the past eight years, this hasn't existed, so nobody has used it. What about all the scripts written in that time? In Greasemonkey 1.0, simple content sniffing is performed on the script. If it looks like it calls an API function, then Greasemonkey acts like the appropriate @grant line was given, even if it wasn't. If you want the new execution mode where everything (besides the privileged APIs) works for sure, you simply specify @grant none in your metadata.
Examining every existing script hosted at userscripts.org shows that not a single one does this (assigning a value to a property of window) today (so they won't get different broken semantics). Unfortunately, jQuery does, so it needs to be fixed. But the fix is the standard and documented jQuery feature for such a case. On the other hand, if the page you run on already includes jQuery, then you can just use it! You have direct read access to the global content scope!
Eventually, @grant none will become the default. At that point, we will stop sniffing and faking grants that were not specified. And at that point you will be required to specify the grant for any API that you do still actually want to use. Only time will tell when we're comfortable enough making that change.
Finally, don't forget about the grant-none-shim.user.js, which provides an emulation layer for most of the Greasemonkey APIs on top of standard browser features. If you (for example) use getValue/setValue or xmlhttpRequest, but only on a single origin, you can switch to this and get the thin sandbox goodness of a grant none style script, and everything will generally work as it always did, at little to no cost. Just note that existing stored values will no longer be readable.