[Sorry for the long delay in replying -- I recently moved into a new house and have been rather swamped.]
Cap'n Proto follows in the Protobuf philosophy of versioning, which is, there are no versions, or alternatively, versions are a continuous spectrum. As long as each incremental change is made in a backwards-compatible way, then old programs should be able to talk to new programs and vice versa. If you want to make a breaking change, you make a whole new type to represent the new protocol. If you want to put "v2" or whatever in the name of that type, that's up to you.
Cap'n Proto uses 64-bit type IDs to canonically identify a type. Two type definitions are presumed to be versions of the same type if they have the same ID. Hence, type names are merely a convenience for developers writing code, but can freely be changed without breaking compatibility. In pure Cap'n Proto, type IDs are the only global namespace of types, and collisions there are unlikely due to being chosen randomly. In most programming languages we are forced to place type names into some sort of global namespace, but that's up to the language-specific code generator to deal with.
> backwards compatibility of protocol versions can be mechanically validated.
With Cap'n Proto's SchemaLoader (in C++, at least), when you load two types with the same ID, it will automatically check them for compatibility and choose the newer version as the type that the SchemaLoader ultimately gives to the application. This is done by actually comparing the schema contents. If the two versions are inherently incompatible, an exception is thrown. I don't know if version numbers would actually add anything here.
Of course, it's entirely possible that a newer version of some software has changed the interpretation of a schema, without changing the actual definition in any way that is detectably incompatible. Obviously, it's fundamentally impossible to detect such incompatibility in an automated way.
-Kenton