> **In short.** The most dangerous AI agent failure is not an action that clearly failed. It is an
> action that may have succeeded while its confirmation was lost. The invoice may already exist in
> 1C, the email may have reached the customer, or the price may have changed in the seller account,
> while the agent sees only a timeout. A blind retry turns recovery into a duplicate. A reliable
> agent therefore needs four separate abilities: remember its place in the task, detect a stopped
> process, avoid performing the same write twice, and stop honestly when the outcome cannot be
> proved. Here is how those abilities work in Samreshuuu, and why a Retry button fixes none of them
> on its own.

You asked an agent to issue an invoice to a customer. 1C accepted the request, created the document,
and began sending a response. At that moment, the connection disappeared.

As far as 1C is concerned, the job is complete: the invoice exists. As far as the agent is
concerned, it is not: no response arrived. Repeating the command may create a second invoice. Not
repeating it may leave the task unfinished. Merely telling the user that there was an error may send
someone off to create the invoice manually, with the same risk of duplication.

This is not a rare edge failure. It is an ordinary state of any work performed over a network. The
request and the response travel separately, and losing the response says nothing about the fate of
the request.

A chat can end with “please try again.” A coworker that owns a piece of work cannot. It first has to
answer a different question: **what has already happened?**

## A failure has three outcomes, not two

Most interfaces draw two states: success and failure. That is not enough for an action that changes
something.

| What the agent sees | What may have happened in the system | Is a retry safe? |
|---|---|---|
| The service rejected the request before execution | Nothing changed | Yes, if the cause is temporary |
| The service confirmed success | The change happened | No retry is needed |
| The response was lost | The change may or may not have happened | Only after obtaining evidence |

The third state is the expensive one. Everyday interfaces have no good name for it, so they often
hide it behind the word “error.” But a connection failure and an operation rejection are different
events. A timeout says only that the response did not arrive in time. It does not say whether the
server managed to take a payment, create an order, or send an email.

In distributed systems, this is an operation with an **unknown fate**. In business language, the
rule is simpler: **do not do it again until you have checked the first attempt.**

## Why an ordinary retry is dangerous here

Retries work well for reads. If the order list did not load, request it again. If a report did not
open, wait and read it again. The outside state does not change.

Writes are different:

- creating an invoice again produces two documents;
- sending an email again gives the customer two identical demands;
- submitting a payment again may charge the account twice;
- changing a price again may apply the same adjustment a second time;
- clicking Submit again in a browser may send an already completed form twice.

AWS frames the problem in much the same way: retries are useful only while several transmissions of
one request still lead to one result. Stripe therefore accepts an idempotency key on creation
requests. A retry carrying the same key returns the result of the first operation instead of
creating a second one.

But the key solves only one part of the problem. The agent must still remember **which assignment**
it was doing, **how far** it had progressed, and **why** it decided to repeat this particular call.
Reliability is therefore assembled from four layers, not enabled by one setting.

## Layer one: the task remembers where it stopped

If the entire course of work exists only in a process's memory, losing the process also erases the
work. A new worker receives the original assignment and starts from the beginning: it reads the
documents again, builds the table again, and eventually reaches the same write again.

A long-running task in Samreshuuu stores checkpoints. After a working step, the agent state, its
findings, created files, and current iteration are persisted. Execution and state live separately:
the process can be lost without losing the work it has already completed.

This is not merely a saved answer. It is a bookmark in a case file. It records not only the page
where work stopped, but also which sources have been read, which tools have been called, and what
they returned.

Temporal describes the same idea as durable execution: a stream of work survives the loss of its
worker and is restored in another process from persisted state. The important part is not a
particular technology. It is the separation of two things that an ordinary chat joins together:
**the task lives longer than the process executing it right now.**

## Layer two: something must notice the stop

A checkpoint is useless if nobody notices that the work stopped.

Every running task has a heartbeat, a small signal that says “I am still working.” A separate
process watches that signal and the current execution owner rather than trusting a reassuring label
in the interface. If a worker disappears or stops responding, the execution returns to the queue
and continues from its latest checkpoint.

There is another unpleasant race here. The old worker may not be entirely dead. It can wake up
after another worker has already continued its task. Two processes now believe they own the same
execution.

That is why every new run receives an attempt number. A result is accepted only from the current
attempt. The late process may finish its computation, but it cannot overwrite the result of the
worker that has already taken over. This does not make the model smarter. It stops two equally smart
models from controlling the same row at the same time.

## Layer three: a repeated call must not become a repeated action

A checkpoint answers “where were we?” Idempotency answers a different question: “have we already
done exactly this?”

Before a mutating call, Samreshuuu constructs its signature from the task phase, tool name, and
arguments. One durable slot exists for an identical action within the same phase.

There are three possible outcomes:

1. The call is new: the agent claims the slot and executes it.
2. The call has already completed: the agent receives the stored result and does not execute it again.
3. The call is still running: a second executor is not allowed to enter concurrently.

This protects against more than network retries. A model can produce the same call again after its
context has been restored. The outside system does not care why: two identical calls would still be
two actions.

Local protection cannot, however, rewrite the rules of somebody else's API. If the external service
accepted a request and our process disappeared before storing the result, an internal slot alone is
not enough. The other half of the contract has to come from the service: an idempotency key, or a
way to find the created object unambiguously by a business key.

A request with an unknown fate may therefore be repeated only when safety can be proved:

- the method does not change state;
- the external API accepts an idempotency key;
- or a separate read can first confirm that the action has not happened.

At the transport layer, Samreshuuu automatically repeats a lost request only in the first two
cases. In the third case, repetition is a new agent decision made after reading the system. Without
evidence, the agent does not guess: it leaves the outcome unknown and asks a person.

## Layer four: the audit log records what happened, not what the agent thought

A chat transcript is poor investigation material. It mixes reasoning, intermediate data, service
responses, and the explanation given to the user. It is hard to prove from that mixture whether a
particular write took place.

A mutating action therefore receives a separate audit entry. It records:

- which tool was called;
- which area and connected account the action concerned;
- whether human approval was required;
- how the call ended;
- which execution and tool call performed it;
- whether a reverse action can be constructed.

This is not a screen recording of the agent or a feed of its private reasoning. The log answers a
narrower question: **which changes did the agent leave behind?**

Braintrust describes observability as an active loop: find recurring failures in production
traces, understand their cause, turn the cases into evaluations, and measure the next version. For
a business owner, the bottom layer of that loop is simpler. If a coworker changed something, there
must be a record from which the result, decision, and reason can be recovered.

## Consider that invoice in 1C

Suppose the task says: “Every weekday, find shipments without an invoice, prepare the invoices in
1C, and show them to me before emailing customers.”

A normal run looks like this:

1. The agent reads shipments and existing invoices.
2. It saves the identified shipment, customer, and amount combinations.
3. Before creating a document, it records a specific intent.
4. It creates the invoice.
5. It reads the new document back and saves its identifier.
6. It requests approval before emailing the customer.

Now the network disappears during step four.

A poor agent sees a timeout and calls Create invoice again.

A reliable agent distinguishes two situations. If the connector returned an explicit rejection
before execution, the request can follow the ordinary retry ladder. If the response was lost after
the request had been transmitted, its fate is unknown. The agent first reads invoices for the same
customer, contract, amount, and period. If it finds exactly one matching document, it continues
from there. If it finds none, it creates one. If it finds two, or cannot prove the relationship, it
stops and presents the evidence to a person.

The next boundary is even stricter. A sent email cannot be “sent back,” so the absence of a
confirmation after sending is not a reason to send it again. The agent first checks the Sent folder
or the provider's delivery status. If neither can be checked, the correct result is not “sending
failed.” It is “I could not prove whether the email was sent, so I did not send it again.”

That answer sounds less confident. It also avoids turning technical uncertainty into two emails to
the customer.

## Why the browser is a separate case

An API request can carry an identifier. A click cannot.

Two calls to Press Enter may be an accidental repeat, or they may submit two different forms. The
same coordinates and keys prove nothing about the result. Samreshuuu therefore does not apply the
same deduplication to browser gestures that it applies to connector calls.

If a browser operation is interrupted, the agent receives an honest instruction: the action may
have run, so inspect the current page state first. After clicking Pay, it looks for confirmation and
a new order status instead of clicking again merely because it missed the success animation.

This is an important boundary for every agent with a computer. Giving it a browser of its own and
the ability to resume after a failure does not make every action repeatable. Sometimes recovery is
not repeating the step. It is observing again.

## “Exactly once” is not a property of the whole task

The phrase exactly once sounds like a promise that an agent will never duplicate anything. That is
not an honest promise for distributed work.

You can allow only one process into a local section. You can store the result of a call. You can
give an external service a key and receive its promise not to create a second object. You can read
the state after an uncertain response. But if the outside system accepts no key, exposes no
operation history, and has no unique business identifier, uniqueness cannot be proved from outside.

A reliable system therefore makes three narrower promises:

- **repeat where repetition is safe;**
- **verify where the result can be read;**
- **stop where the outcome cannot be proved.**

The last item is not an agent weakness. It is a boundary of authority that a human coworker should
also observe.

## What to ask an AI agent vendor

Demos almost always run without failures. Reliability is therefore better tested with five
questions than with a demonstration.

**What happens if a worker disappears ten minutes into a task?** “The task starts again” is worse
than “it continues from its saved step.”

**How does the system distinguish a temporary rejection from a lost response?** If both are called
a retryable error, mutating requests will eventually be duplicated.

**Where is the result of an already completed action stored?** The message history is not enough.
There must be an address for the particular call and its result.

**What happens when two executors believe they own one task?** A queue alone does not protect
against a worker that wakes up after its work has been handed to another.

**What does the user see when the result cannot be proved?** A good answer contains the state, the
last confirmed action, and a safe next step. “Something went wrong, try again” is not an answer for
a system allowed to write.

## Reliability begins after the first failure

While an agent only reads data and writes advice in a chat, it can be judged by answer quality. The
moment it receives a schedule and permission to change working systems, it acquires a second
criterion: how it handles unfinished work.

A reliable agent still fails. Networks still flicker, services return 500 errors, processes
restart, and browsers close between the click and its confirmation. The difference appears
afterwards:

- it remembers where it stopped;
- a new executor does not fight the old one for the same task;
- a completed action is not executed again;
- an unknown outcome is not renamed as a failure;
- a person is asked only when the system runs out of evidence.

This is where a chat becomes a coworker: not when it learns to press a button, but when it learns
not to press it a second time without a reason.

---

**Last updated:** September 4, 2026.

**Sources:** [n8n — How To Build Reliable Workflows With API Idempotency](https://blog.n8n.io/idempotency-api/);
[Temporal — The thread is the Workflow: Durable AI agents without changing Agent code](https://temporal.io/blog/manetu-the-thread-is-the-workflow);
[Braintrust — One connected system for agent observability](https://www.braintrust.dev/blog/active-observability-loop-patterns-debugger);
[AWS Builders' Library — Making retries safe with idempotent APIs](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/);
[Stripe — Idempotent requests](https://docs.stripe.com/api/idempotent_requests).
