I think I understand this Mach kernel overview and I thus set out to build an architecture map between Mach and Keykos.
Keykos key <-> Mach port
+Unidirectional,
+Can designate object implemented in kernel or user code (task in Mach, domain code in Keykos)
+Used as addresses for a message. When a message is sent a port is specified to identify the recipient.
?Note text: "typical object such as a message queue". I shudder to think that a message queue is a typical object. Nothing wrong with message queues but taking it as a typical object greatly confuses one who is trying to guess whether a queue is an integral part of every port.
-Ports can deliver messages to different tasks at different times, unlike gates (a kind of key) that always deliver to the same domain. We considered a mutable map from key to domain but judged it was not worth the hair. It seemed to provide some convenience but no fundamental advantages.
They speak of passing a port to a task so that the task can receive messages. Note text "Tasks have permissions to access ports in certain ways". This suggests an image of two ended ports; they talk like Joule!

I think the most accurate map is to say that a key corresponds to send rights on a port. Keykos provides nothing like receive rights on ports for each key designates a constant domain which might be said to have implicit receive rights on that key. Being constant, we have no need for such talk. It is port rights that may be sent in messages, not ports.

See Ports, Port Rights, Port Sets, and Port Namespaces for more port details.

Keykos Domain <-> Mach (Thread or Process)?
"c-list" is a generic term that may be used do talk about any good capability system. The Keykos c-list is numbered 0 thru 15. The indexes are determined explicitly by the code that sends and receives messages. This is conceived as a parallel to how code allocates machine registers. Unlike machine registers, many domains never overflow their c-list; many do.
The Mach c-list length is conceptually 232 and is clearly mostly unallocated. The kernel allocates slots in the c-list upon message receipt and notifies recipient of the index. (I need to check this.) Threads within a process share a c-list. Keykos builds such an expanded c-list in user code and a few important domains use it.

This is one of two possible mappings (The alternate map is Mach process) There is no fact of the matter, either map is usuable different maps will elucidate different usage patterns in the two systems.
-The thread does not belong to a client between invocations. I think a Mach user must own a whole Mach process in order to keep abstracted state.
+Domains and Threads are the multi programming support in their respective systems.
-Modularization: Domains abstract, Threads don't
-Locks: Domains exclude, Threads don't
-Portection: Domains are the site of authority, The Mach process owns the c-list.

The above differences suggest we try the alternate map

Keykos Domain <-> Mach Process
Mach has several threads per task. All threads share same address space and c-list.

Mach at MIT, Mach manual at Wayne State, MIT’s manual,
something to do with initial capabilities.