This question hasn't seen any responses after almost a day. Maybe the following will get the debate rolling. :)
- I like the notion of having the XS module separate. It's Ok for the PP module to use the XS module if it's available, and to gracefully fall back to PP if not (or if an ENV variable or 'use' flag specifically disallows upgrade to XS). If you don't have creative control over the PP version, you could always create an "any" module to handle the upgrade/fallback logic for users. One good reason for putting the XS version in its own module is that it's generally more of a "sure thing" getting a pure-Perl module installed, so some users may appreciate that they're not prohibited from using the pure-Perl version just because they can't get the XS version to compile (this has become a less problematic issue nowadays, but still may be a consideration).
- _XS: I've seen people mention that it's most useful when the _XS name distinguishes the module from a PP version. If there is not pure-Perl version, the _XS name is less useful. There are plenty of examples of XS modules that aren't named with XS, and of XS modules that are. I don't always expect or need to see it in the name. I usually look at the source to see if XS is in play anyway.
- Regarding stand-alone: It depends on how much of the pure-Perl version you're re-implementing. If you're only overriding one function, it seems silly to cut-and-paste all the rest of the functions when you could simply inherit instead.
- The pure-Perl module needs tests! But the XS module does too. It's possible there is a lot of overlap in what tests make sense for both modules. If the same tests are being run against both the pure-Perl and the XS version, that's great. But there are probably many considerations that only apply to the XS version, and that may not make any sense for the pure-Perl version. XS code is a lot harder to get right. More problematic needs more tests.
I hope some of this has been helpful. Hopefully others will dive in now.