04 / 04 Interfaces

A face for a program

A small face can make an interface feel present. It also creates an obligation to separate expression from evidence.

Design note

HALO is my agent, built around recursive self-improvement, with a dry sense of humor and a feral streak. The intended character has the energy of a caffeinated raccoon. The face is its interface, not the extent of the project.

This note looks specifically at that interface. HALO's face is drawn on a 32-by-32 canvas. Its eyes blink and glance using a small procedural driver. The visible behavior is simple; what a visitor might infer from it is less simple.

A face could make a program feel approachable, attentive, or present. Those are design hypotheses, not observations from a user study. The interesting problem is how to explore them without allowing an expressive interface to make claims the system cannot support.

Every movement invites an interpretation

A blink does not prove that a program is waiting patiently. A glance does not prove that it noticed something. An animation can be decorative while a visitor reads it as a response.

Small resolution does not remove this ambiguity. A few pixels can still suggest intention. The design question is therefore not how little detail makes a face honest. It is which behavior should depend on a real event, and how that relationship becomes clear.

A useful distinction is between ambient character and operational state. Ambient character gives the interface personality. Operational state says what the system is doing and what the visitor can do next. The second should never depend on interpreting the first correctly.

A worked hypothetical: the unanswered question

Imagine that a visitor sends a question. The request reaches the server, but the model does not answer before the connection times out.

If the eyes continue to move and the input stays disabled, the interface may look busy indefinitely. If the face smiles, the failure could look like a completed exchange. Neither behavior gives the visitor the information needed to act.

Instead, the interface could preserve the question, show a plain “No answer received” message, and offer a retry. The face can remain present. Its animation should not be the only evidence that a request is pending, complete, or unavailable.

Now consider a late response arriving after the retry. The interface also needs to know which request owns that response. Expressive polish cannot fix an ambiguous state model.

Keep personality separate from confidence

A confident expression beside an answer may be read as a judgment of that answer's reliability. Unless the system has a defensible way to estimate reliability, that mapping adds information it does not possess.

I would start with expression tied to directly observable events: a new request, a received response, or an unavailable connection. Leave the answer's strength to its content, sources, and stated uncertainty. An idle blink can remain an idle blink.

The existing canvas redraws when its driver changes state, while a timer checks that driver. That is a concrete implementation choice, not a claim that the face costs nothing to run. Performance should be measured in the context of the whole page.

Test the interpretation

A useful study could compare a plain text interface, a face with ambient movement, and a face whose movements accompany explicit state labels. Give each version the same successful answers, delayed responses, and failures.

Ask participants what they think the system is doing and what they expect to happen next. Measure whether they identify failure and recover from it, alongside any change in approachability. A face that feels pleasant but makes an unavailable system look attentive has solved only half the problem.