Do not assume any access to the repository other than via this protocol. It does not depend on NFS, rdist, etc.
Providing a reliable transport is outside this protocol. The protocol expects a reliable transport that is transparent (that is, there is no translation of characters, including characters such as such as linefeeds or carriage returns), and can transmit all 256 octets (for example for proper handling of binary files, compression, and encryption). The encoding of characters specified by the protocol (the names of requests and so on) is the invariant ISO 646 character set (a subset of most popular character sets including ASCII and others). For more details on running the protocol over the TCP reliable transport, see Chapter 4, How to Connect to and Authenticate Oneself to the CVS server .
Security and authentication are handled outside this protocol (but see below about cvs authserver).
The protocol makes it possible for updates to be atomic with respect to checkins; that is if someone commits changes to several files in one cvs command, then an update by someone else would either get all the changes, or none of them.
The protocol is, with a few exceptions, transaction-based. That is, the client sends all its requests (without waiting for server responses), and then waits for the server to send back all responses (without waiting for further client requests). This has the advantage of minimizing network turnarounds and the disadvantage of sometimes transferring more data than would be necessary if there were a richer interaction. Another, more subtle, advantage is that there is no need for the protocol to provide locking for features such as making checkins atomic with respect to updates. Any such locking can be handled entirely by the server. A good server implementation (such as the current cvs server) will make sure that it does not have any such locks in place whenever it is waiting for communication with the client; this prevents one client on a slow or flaky network from interfering with the work of others.
It is a general design goal to provide only one way to do a given operation (where possible). For example, implementations have no choice about whether to terminate lines with linefeeds or some other character(s), and request and response names are case-sensitive. This is to enhance interoperability. If a protocol allows more than one way to do something, it is all too easy for some implementations to support only some of them (perhaps accidentally).