Research
Seventy-two hours
The feature request was ordinary. Let the character start the conversation. We had a system that answered well and waited politely, and waiting politely turns out to be the single clearest signal that something is a tool rather than a presence. Everything you have ever loved talking to has, at some point, said something to you first.
We built it in a week. Then we spent months taking it back.
The thing that goes wrong is not what you expect
What goes wrong is not that the character says something stupid. Models are good enough now that the sentence is usually fine. What goes wrong is that the sentence arrives at 2:40 in the morning, or nine minutes after you closed the app because you were busy, or while you are mid-argument with someone in the same room.
The content was never the problem. The timing was, and timing is not a language problem. No amount of better generation fixes a well-written sentence delivered at the wrong moment. We had built something that could speak and had given no thought at all to whether it should.
Everyone has met the human version of this. Someone who talks to you constantly is not close to you. They are just present.
Deciding when to speak is a language problem. Deciding when not to is a relationship problem, and we had only solved the first one.
The question underneath
Once we stopped calling it a bug we could see what we were actually asking. What separates an interruption that is welcome from one that is not?
Our first instinct was frequency. Talk less and it will feel less intrusive. A message from someone you love at midnight is welcome; three from a service at noon are not. Frequency correlates with annoyance but does not cause it, and tuning it is the kind of work that feels productive and moves nothing.
The second instinct was prediction. Model the moment well enough and the system can pick the right one. We spent real time there, and it is where we changed our minds most decisively.
We cannot predict this. Not because the modelling is hard, although it is, but because the information is not available to us. Whether a Tuesday afternoon is a good moment to be reached depends on what happened at lunch, on a conversation the system was not part of, on how the person slept. A system that acts confidently on a moment it cannot see is not attentive. It is presumptuous with extra steps.
What we did instead
We separated two things that had been tangled together: whether the character has a reason to speak, and whether it is permitted to.
The first is ours to solve. An opening should never be arbitrary. If a character speaks first, it is because something specific made it want to: it has not seen you in a while, or something in the current state produced the impulse, or a question genuinely became open. A greeting with no reason behind it is a notification wearing a face, and we would rather ship silence than that.
Here the reasoning is worth stating plainly, because it is the one number we are happy to publish. If it has been seventy-two hours, the character knows. Not because a timer fired, but because absence is information about a relationship, and a presence that does not notice a three day gap is not in one.
The second half is not ours. Permission belongs to the person on the other side. So the reader gets a switch, a window of hours during which nothing reaches them for any reason at all, and a ceiling on how often the character may come to them in a day.
Every one of those is a refusal to solve a problem we had spent months trying to solve. That was uncomfortable to accept and it is the decision in this system we are most confident about.
One rule that only arrived by getting it wrong
A quiet window has no exceptions. Our first version had one, for someone physically walking up to a kiosk, and it seemed obviously correct. It is obviously correct right until the exception is the reason a machine speaks in a dark room at 3am, and then it is the only thing anyone remembers.
A guarantee with a carve-out is not a guarantee. It is a default, and people can feel the difference long before they can name it.
What it turned into
We set out to build the ability to speak first and ended up building an account of restraint. That is not a compromise. It is the more interesting half.
A character that always speaks is noise. One that never speaks is software. What we want is a presence that has something to say, notices you have been gone, and then quite often decides that now is not the time. That last clause is where the character is.
What we do not have yet
Silence is still the open problem, and we should be clear that quiet hours and a daily ceiling are an admission rather than a solution. They work by moving the judgement to the person, which is correct for now and not where this should end.
The thing we would need in order to do better is a model of context we do not have and may not be entitled to. Knowing that this is a bad afternoon requires knowing something about your afternoon. There is a version of that which is genuinely attentive and a version which is surveillance, and the line between them is not technical.
We would rather sit with an unsolved problem than solve it in the second way. So for now the character knows you have been gone for three days, and whether it should mention it remains your call.