Here are some departures from the picture painted here.

Kernel Practice

The 100,000 or so bytes of the kernel are divided into three largely equal parts: Bill Frantz wrote the I/O code which was about 40% of the kernel but first wrote "pseudo code" in Algol68 for which we had a compiler that enforced Algol68's very strong type checking. The I/O code was conventional in that we could afford normal procedural abstraction. Interrupt code, on the other hand is never trivial. The interface to the I/O was well specified in English. The English specifications for the sub-components of the I/O system were much less complete.

I wrote the domain logic and Charlie Landau wrote the kernel object code. These two parts were very hard to describe routine by routine. Instead we wrote a very extensive and rather accurate kernel invarient in English. Even more important we wrote code (called CHECK) which would occasionally check that the invarients held. After any non-trivial change to the kernel the frequency of running check was increased. We ran check before each checkpoint. The code CHECK was by nature easy to read and in sometimes easier than reading the contorted (if accurate) English version of the invarients.

Domain Practice

The only clear disadvantage that I see in KeyKos domain programming is that type checking for capabilities is largely at run time instead of compile time. I think that KeyKos is like SmallTalk in this regard. Our assignment of order codes made it highly likely that type confusions would be caught at first object reference. Unlike Java we do not depend on type safety for system integrity. Space Banks and meters assigned responsibility for resource usage to those in a position to respond. Space leaks could be found by interposing extra space banks to determine where the leak was. The only disadvantage of this is that space leaks were often trailing bugs, i.e. fixed late in the development cycle. They were easy to find when they did show themsevles, however.