1) My problem with sending error messages (STAs) is that afeatures are opt-out so: a) there must be pointless lines of code just to say 'we know these features are in the protocol, but we don't support them' and, b) clients and hubs need to respect the error messages e.g. a recent version of DC++ (maybe even the current version) didn't respect an error message from my bot when a user tried to connect to it, it just kept trying to connect, despite the protocol indicating that I was sending the appropriate error message.
The issue of respect is crucial in low-bandwidth situations e.g. mobile devices, where bandwidth is expensive. If protocol features are opt-in then these devices are much better catered for.
A limitation to this approach may arise in the case of 10k user hubs, where filtering messages based on supported features may take too much time where the hub filters by iterating all users and examining their feature support. The obvious enhancement to this is, when the hub is in a high-volume situation, create lists per-feature containing the users which support them, and then iterate through the list for that feature. This increases memory usage, but should reduce processor load.
2) Yes we have 33,696 fourcc's (26*36*36), but the readability and relevance to functionality will increase if we actually use them as fourcc's + version number, rather than integrating the version number (useless benefit, we'd have 1.2 million fourcc's). For example, what will ADCS be at version 2? ADC2 by convention, so you just lost the key descriptive word in the feature name because you needed to put the version number there, and now it looks like it could be confused with the core protocol by an observer who isn't paying attention. Alos, the ZLIB feature has ZLIF and ZLIG as the two 'supports' fourcc's, but how do you create a new version of them? In both cases it will be ZLI2, so you need a new first three characters for one of them, at least.
The expansive versioning is designed to let ADC live forever

One possible use of major/minor versioning that I did mention was that you could use that x.0 version for core functionality, and x.1 for optional functionality, and then just keep the same pattern as you increase the version number in regards to odd/even. This could be useful for clients rapidly adding support for the core of a new feature, and then taking a bit more time to work through the more challenging/time-consuming elements. For example, in the MSTR extension I proposed (and still need to produce a revised draft because it's too complex), the BAN command has an option for the parameters to be treated as regular expressions if you pass the flag RX. MSTR/1.0 could include the simpler version of BAN, and MSTR/1.1 could add regular expression support to BAN.