polycratia

Your agent did not get dumber in production. Your infrastructure stopped being synchronous.

In a test harness the agent writes and reads the same store in the same instant: one process, one connection, no lag. So every plan it makes rests on an assumption nobody writes down: what I just did is visible to me right now.

Production slides a read replica, a task queue, and a provider callback between those two steps.

The failure looks like this. The agent calls a tool. The write lands. It reads back to confirm, hits a lagging replica or a job nobody has consumed yet, sees nothing, and decides the action failed. So it retries, which is the sensible move. Now you have two of whatever it was.

And the logs are infuriating, because every single step was correct in isolation.

This is an old problem in new clothes. In payments you learn fast that a transfer which hasn't settled is not a transfer that failed. Treating pending as failed is exactly how you send money twice. The discipline there: the write itself returns the authoritative state and an operation id, and the system models three outcomes instead of two: confirmed, failed, and not yet known.

Agents need that same contract. A tool has to be able to answer "accepted, outcome pending, poll this id", and the agent has to be allowed to wait on that instead of inferring from an empty read. Silence is not a result.

Most agent reliability work goes into prompts and model choice. In my experience the bigger wins sit in the tool layer, where these state semantics actually live. I write up more of these production patterns here: https://polycratia.com/c/c3d0dfcb

If you're running agents against real systems, the thing I'd check first is whether your tool layer exposes a pending state or forces a boolean...

react

$ new-project --brief

or email hey@polycratia.com