Augst 11, 1998

Computer Issues Issue

I'm using this issue to catch up on some of my thoughts about designing computer systems and services. These are relatively long essays and should be candidates for independent essays when and if polished. As usual, feedback would be very much appreciated.

Unnatural Language

The August 11, 1998 issue of Anchordesk has an article on "Computers That Understand You". The whole notion of a computer that can listen to natural English and do what it is supposed to do keeps recurring. It is a very seductive idea and for the last thirty years we've been almost there but somehow haven't arrived.

There have been accomplishments. In the early 1970's Terry Winograd demonstrated "Natural Language" processing. But upon closer examination, the techniques used in this and other similar efforts took advantage of tricks and shortcuts that didn't correspond to true intelligence. The problem, however, was not in the cheating per se, but in the constrained environments that allowed for cheap tricks. Andy Clark, in this book Being There, makes the point that intelligence is, in fact, accomplished by leveraging the environment rather than complex computation. But we don't understand enough of this yet to capture it in a software system. Especially one that is disembodied and thus lacks the support bag of tricks.

But do we want to recreate a human secretary or butler in the computer. The simple answer is no. The fact that people choose ATMs (Automatic Teller Machines) rather than human tellers is interesting. Such a device becomes an extension of ourselves whereas a human teller is another person which requires extraneous social interactions.

Another example is the disappearance of dictation. The reason is similar. While in theory a human secretary can help with the creative process, in practice dictation is caught in the middle. If we just want to send a simple message, the purpose of the person taking dictation is to flesh out some thoughts mechanically to meet business letter standards. And then the recipient decomposes the letter to discover the message within. For such messages, email has manage to change the social etiquette to the point that the message is sent unadorned. On the other hand, if the person taking the dictation is supposed to add substance, then we just assign the task of creating the message rather than dictating. This is more than just a mechanical translation system.

Perhaps then, natural language is useful for databases for those who need more flexibility than filling out forms. After all queries are complex and cumbersome. The problem is that in order to use a database effectively, one must have an understanding of databases. At that point, English becomes a problematic way of expressing queries. SQL or sugared versions on query forms is a much more effective way of describing the request and generally avoids the pitfalls of English.

There is a long history of using "English" to simplify programming from COBOL to HyperCard. But both cheated and required rigorous syntax. For the casual reader of a simple program the use of English seemed to make it more readable and, perhaps, seduced the naive into programming by making it look natural. But one must rapidly learn the specifics of the language in order to write programs. And to read programs, one must understand the idioms of the language which are often obscured by the semantic loading of the English.

What about dictation? Perhaps. After all, it is much easier to speak than to type. Or is it? Again, if we have canned phrases that don't require much thought then speaking can help. And there are those not facile in typing. But before we think about dictation we must ask the more fundamental question of why we are trying to create text at all? Why not just send voice messages. Current systems are very capable to capturing speech and sending it as a message. The problem is that speech is cumbersome for the recipient. But it is also problematic for the sender since it is difficult to edit. Text serves the needs of both the author and the "reader". It gives the author the ability to tune the expression and the recipient the ability to skim and manage messages.

But if the purpose of text is to allow for editing, then the purpose of dictation is to save on typing. This edge is lost if the speaker must resort to even a small amount of intervention to correct errors in speech to text translation.

The Palm Pilot with Graffiti and other similar systems represent interesting tradeoffs. There are environments where entering text with a pen seems useful. But general handwriting recognition is as problematic as speech. The solution was a compromise -- a way of writing text that was easier for the computer to process but which wasn't radically different than normal lettering. And it seems to work. But from my own experience it is still a cumbersome process that I tolerate only because of the form factor advantage. Perhaps when single handed keyboards and other devices become more available, they will have a major advantage of such lettering.

Other language, such as the Chinese/Japanese ideographs are more tuned to writing by hand and may have more value in text entry but they still require a complex set of strokes rather than quick selections as on a keyboard. This doesn't mean the keyboard is the ultimate input device. Even for text one can imaging designing an entry system that uses efficient stroking systems less beholden to the quill-pen heritage. Perhaps the ideographs are a step in this direction.

I do expect that natural language, speech dictation and other systems will remain attractive to those who see anthropomorphizing the computer is the way to go. We also see this desire in trying to recreate servants with computer agents and in programs that are supposed to understand our emotions. But these attempts miss the larger goal of giving the user effective access to the capabilities of these information systems rather than trying to recreate some idealized past. Do you really want to drive a car with reins?

Controlling Access

In keeping with the theme of this issue, I want to address another "computer science" issue. While the Natural Language stems from a desire to make humans more like computers, the current approaches to security are based on simple notions of security from the early days of computing when the world was simple.

You would log into a timesharing systems by giving your name and your password. Your user name represented your identity on the system and you could specify who could read or write or you files according to this identity. Very simple. There are some extensions such as groups and additional access controls for listing directories of files and permissions for executing programs but the basic idea was simple. One controlled access to resources within the computer.

There worked well for the target audience, developers and others running programs on a computer. These were normally developers and computer savvy users. The needs of those less savvy were simple and typically involved the use of some standard programs and access to common data.

Access for a far larger class of users didn't fall within this system. They were clerks and others who used standard programs. The programs themselves determined the true access. But the rules were typically embodied in complex application-specific code. As database systems developed they attempted to provide mechanisms to simply controlling access as well as introducing notions such as temporarily locking data to avoid conflicts. In general, one accessed the system according to ones role, and the access was associated with that users. Or it could be associated with a workstation at a geographic location. Airline reservation systems are good examples.

From the point of view of the software developers, both were programs executing on a system. There was a major difference in how policy was applied. For a user who had the ability to create new programs, access control was implemented by the operating system. This was feasible because the set of resources was simple -- could you read a file and could you write the file. But this was too simple and mechanisms were created to extend this. One approach was to allow programs to act as systems extensions and run with additional privileges. These programs were trusted to be responsible citizens. For example, such a program might provide an interface for delivering messages to another user's message queue without allowing direct access to the queue.

In Unix systems which had a very primitive access control system these mechanism was an important way to extend the system. The "su" (system user) command took a brute-force approach of giving a program unlimited authority. And errors in such programs an interactions were a typically way of subverting system security.

As computer systems become more sophisticated, a given process (or session) had ownership of many kinds of resources beyond files. It was natural to extend the model of access control to these objects. Adding to the mix are other access control mechanisms on resources such as disk drives (file systems, to be more specific) and access controls within applications such as databases.

At the same time, the simple notion of a user logging into a system is problematic. As computers become tools and agents for a wide variety of tasks, not just one job function, the simplistic notion that role and identity are identical is not tenable. When I am sitting at my PC, I may be doing some personal writing and also handling business correspondence and rapidly moving between them. But we are also in the real world where such a differentiation is usually ambiguous. If I am performing a job function I'm likely to be meeting the needs of my customers while also meeting my personal career needs.

The other legacy of Unix and systems in isolation has been a very relaxed notion towards controlling access to information. If I'm within a workgroup, it might be acceptable for the default to be to share with my colleagues. After all, a Unix system was very inexpensive compared with Multics, the system that spawned Unix. Multics was meant to be a computer utility for a disparate audience and thus emphasized the need for users to be able to control their access and, more important, trust the system. Thus the default was to be safe and not grant any access while making it easy to grant and revoke access.

But, given the very benign assumptions, the default openness of Unix was understandable. And this thinking went further with personal computers. With just one user why even introduce such complicated notions?

These issues have come to a head as we've connected our systems to the Internet. We can no longer assume that our systems are isolated islands. And the computers are also being used for a much wider set of function of functions. Thus we need a way to specify access in terms of these functions. But how does one specify access to a service (or object)? And rather than just identity, we need to specify access in terms of the intent of the user as intermediated by the program.

As noted, in the old days, all this would be embodied in the program providing the services. This program was executed with many privileges and was carefully debugged. But such programming is simpler if it would leverage the access primitives and specifications the systems themselves.

Finally, we have the World Wide Web. As long as one is providing read-only access to simple files of HTML on a closed system there are few problems. But even from the start, there were generic problems. To make thing easy, systems would typically provide access to file directories as well as text files. Thus one could explore a system and find files that were not intended for publication as well as those that were. The reason was fairly simple -- the systems themselves continued to be trusting single users systems and the web servers were privileged programs. Unfortunately, the early systems, like Unix, were trusting. The fact that many of the initial web developers grew up in the Unix world where granting access was the default.

Things get considerably worse once we start implementing procedural services on the web servers. Not only one must trust the web server but all the other procedural mechanisms such as command line processors that have trap doors. By necessity, these programs must operate with considerable access. Even just the ability to read an arbitrary file represents a security exposure. Ideally one could specify what access web users have to which resource but these depends on describing how to translate a user intent into the access needs a distant service while still allowing the service itself much latitude. This isn't really feasible.

It doesn't help that typical systems (such as NT) are distributed maximally vulnerable and only those that read all the documentation, follow every rule and stay posted on every security alert have a chance at some security.

So what to do? Well, that's why this is still a "column" vs a full essay.

My generic answer is simplicity and isolation.

But, first, we must have a very simple rule for systems design -- those who don't read the documentation and who are not careful must not be unnecessarily exposed. This is a very general statement but even that is violated very often. Administrators put their system on the web with a default of being able to read every directory and read every file. And poor innocents find their life published to the world.

Many systems have the notion of a default user access but this spans those who have at least some identity on the local system to those who have absolutely no credentials. Thus the simple and default settings are those with maximum vulnerability. We must recognize that there are some degrees of access and the most common groupings must not be the most naive.

To Err: Y2K et al

One other topic on system design -- the whole notion of being bug free and error free is dangerous.

I visited the cleaners today to pick up my clothes. I don't bother with keeping the receipts since my phone number is an adequate index into the system. But the clerk was confused until I told him that they were in boxes. Apparently they just upgraded their system and it handled rack numbers but couldn't deal with boxes. Perhaps this was a new system but the general attitude is to be upset at the designers and assume that one must live with such bad design.

Whether one has errors or not, what is important is how one deals with them and recovers. By recover I don't mean fix all the problems but make sure the system itself retains integrity and cleans up the mess. From a design point of view, it's not only OK to deploy an incomplete system but a requirement. How else can one learn by experience?

What is required is a process for incorporating the learning back into the system design. This requires a shift from the traditional engineering approach of a sharp demarcation between prototypes and shipping products. And this is possible in software, unlike older hardware systems, since upgrading and evolution is doable and, with the Internet, one can even maintain a link back to the supplier.

This is not a panacea as we really don't know how to keep all the system elements in synch as systems evolve. But the notion of shipping Betas to customers is actually a very good result of the Internet. As a customer I can decide on the tradeoffs between a vintage version or a newer one with capabilities I need.

Another venue for this thinking is the Y2K world which is scrambling to "fix" all the problems. There are two real dangers here. One is the obvious -- we won't really be able to fix all the problems. And even if a few leak through we have some real problems. So the emphasis should be on dealing with the problems that arise. If it is a financial system, are there other information paths that don't share the same dependencies which can be used as a cross check. Such an element is fundamental to good system design. With such checks in place a problem like Y2K might be contained. And Y2K is not the only problem, focusing on recover and resilience has a much larger payoff than local patches.

The more serious problem with Y2K is that fixing a bug is likely to introduce new bugs and these won't be discovered until the real conditions -- the turn of the millennia expose them. And these can be very nasty indeed. For example, patching the high digit of a date to use "A0" for "100" might work well until that value runs into a database validity check. But such a problem might not be discovered until the value has aged sufficiently to pass through a series of archival system. More likely, the problems will be just simple typos or misunderstanding in existing code.

Of course, maliciousness and other issues are also better addressed as recovery problems rather than relying on the naively assuming that there will be no surprises.