All posts

Three windows, and what the assistant is allowed to keep

A transcript for a day, the subjects for a month, personal data anonymised at ninety. Three numbers that used to disagree, and why there will not be a fourth.

September 21, 20264 min readSaytu team

What it keeps

On this page

A shopper asks about a jacket at eleven at night, closes the tab, and comes back the next morning with "anything new?". Answering that well means the assistant remembers something. Answering it responsibly means being exact about what.

There are three retention windows in this product and they hold three different kinds of thing. The numbers are not a policy document written after the fact. They were forced on us by a bug.

The three numbers used to disagree

Before any of this was thought through, three numbers existed in three places and none of them knew about the others.

The widget kept a shopper's session id in the browser for thirty days. The server expired the conversation transcript after twenty-four hours. The durable log anonymised personal data at ninety.

So a shopper returning on day two sent an id the server had already forgotten. The client believed in a conversation the database had dropped, and the assistant met somebody it had every reason to recognise and did not. Nothing errored. It just behaved like a stranger while holding a key that said otherwise.

Fixing that meant deciding which number was authoritative, and the answer was not "make them all the same". It was to separate what is being kept.

The three retention windows side by side, and what each one is not allowed to hold.
The three retention windows side by side, and what each one is not allowed to hold.

Twenty-four hours: the transcript

The conversation itself is short-term working memory. It expires a day after the last message, and it is read twelve messages at a time.

Both of those are deliberate. A model answering a follow-up needs the last few turns, not a month of them, and a longer window would mean keeping the actual words a shopper typed for far longer than they are useful for. Those turns are also competing for room: the whole knowledge budget for one question is about two thousand characters, and the transcript is spending from the same request. Nothing is served by a transcript that outlives the visit.

Thirty days: the subjects, and only the subjects

What survives the night is much smaller. It is a list of the things a shopper asked about, capped at three, each trimmed to sixty characters.

No message text. No name, no email, no order number, nothing that was typed. Only the search subjects that their own questions produced, so that "anything new?" the next morning can be answered about the series they were looking at rather than answered blankly.

This is the one number the browser and the server now share, read from a single constant that is deliberately import-free so the client bundle can use it without pulling in the database layer. One value, two sides, no chance of the disagreement coming back.

Thirty days is generous. It can afford to be, because of what it does and does not cover — a month of remembering that somebody was interested in a series is a different proposition from a month of remembering what they said.

Ninety days: anonymisation, not retention

The third window is not about memory at all. Conversations kept for the merchant's own records have personal data stripped from them at ninety days by a scheduled job. Storefront rows are written already stripped and carry a flag saying so, which is a detail that matters more than it looks: run the redaction rule twice over a row and the second pass erases what the first one produced. The subject list expires long before that, comfortably inside it, so the shorter window is never the thing being relied on.

Why there will not be a fourth

The temptation with a system like this is obvious. Every new feature that wants to remember something arrives with a reason for its own window, and each reason is good on its own. Four numbers is worse than three in a way that is hard to see until somebody has to answer a question about what the product keeps.

So the rule we hold to: a new feature picks one of the three, or it does not remember. If something genuinely cannot fit, that is a conversation about the shape of the retention model, not a fourth constant added quietly next to the others.

The reason is the bug at the top of this post. Three numbers that disagreed did not produce an error. They produced an assistant that acted confused, in a way nobody could diagnose from the outside, because each number was individually correct and the set of them was not.

Keep reading

All posts