Andy Matuschak seems to indicate that Sparkle can actually handle 'download only' gracefully for you. In his own words, just leave the <enclosure> out of your <item> and add a <sparkle:version>2.0</sparkle:version> element as a child of the <item>.
Read his comment here: https://github.com/sparkle-project/Sparkle/issues/227#issuecomment-13192723
Just like Fermat before him, he left out one piece of information. But unlike the theorem, we have access to Sparkle source code, in particular SUAppcastItem.m. Thanks to the code, I figured out the missing piece was a <link> tag. Here is an example appcast:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>FooBar</title>
<link>http://foobar.com/appcast.xml</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>FooBar 2.0</title>
<sparkle:releaseNotesLink>http://foobar.com/release-notes-special.html</sparkle:releaseNotesLink>
<sparkle:minimumSystemVersion>10.9.0</sparkle:minimumSystemVersion>
<pubDate>2014-04-14T18:40:44+02:00</pubDate>
<sparkle:version>2013</sparkle:version>
<sparkle:shortVersionString>2.0</sparkle:shortVersionString>
<link>http://foobar.com/release-notes-special.html</link>
</item>
</channel>
</rss>
In the sandbox app that receives that appcast and cannot be updated otherwise, the 'Install Update' is gone, and in its place is a 'Learn More' button that will bring the user to the URL in that <link>. This is a good place to have instructions for the download.
In the next version of your app, you could then use a different URL for the appcast, so that the above appcast only applies to older versions (assuming you fixed things and now use the non-official XPC trick with Sparkle).