Recommended guardrail
Make every side-effecting agent tool idempotent under retry
Give each tool an agent or model can call that moves money, sends a message or creates a record an idempotency key derived from the tool call or task, or deduplicate on a natural key, so a retried or repeated call has its effect once. Detect tool functions that create payments, refunds, transfers, messages, orders or tickets with no idempotency key or deduplication.
This is TwinEthos's opinion of what a responsible AI integration does anyway. It is never a legal or standards requirement; where binding law applies, the law governs.
The recommended-guardrail rule files are open under CC BY 4.0; attribution and scope are in the terms.
Informational data, not legal advice. Summaries and rules have not been reviewed by a lawyer: always verify official law text for decisions. A suggested guard is intended to address each rule; adding it is not a statement of compliance to that law.
Trust and provenance
- Lane
- TwinEthos recommendation (not law) TwinEthos recommendation, not law
- Official source
- TwinEthos's own derivation record (from the corpus gap analysis and the incident registry), not an official source. The law, standards and incidents it cites are listed on this page with their own links.
- Data release
- Data release 2026.10.03.4, data as of 3 Oct 2026, schema 0.3.10. This page also reflects corpus changes made after that release; they ship in the next one.
- Legal review
- Not reviewed by a lawyer. Written by TwinEthos as its own recommendation: opinion, never law. No TwinEthos rule has been legally reviewed yet.
- Audit standard
- Audit-grade: meets all 11 checks of the TwinEthos audit standard that apply to it. The audit standard is TwinEthos's own quality bar for provenance, dates, applicability, detectors, fixtures, remediation and licences; it is not a legal review.
- Detectors
1 detector (data flow), experimental: written from the rule's text and not yet measured for precision on real code, so treat a hit as a lead to verify.
Known limits:
- Side effects behind an app-specific helper name; generic HTTP POSTs are not counted as side effects here.
- A downstream wrapper that adds the idempotency key is not seen; confirm the helper before reporting.
Evidence grade
Ahead of the law: TwinEthos opinion, no law, standard or incident yet
0 graded incidents.
TwinEthos recommendation, not law. Where binding law applies, the law governs. No binding law in the corpus requires this control yet. 0 graded incidents cited. Context: binding law on related controls in the family “AI controls are not preserved under cost, latency, or model-change pressure” is in force in 1 jurisdiction (US-IL).
Family “AI controls are not preserved under cost, latency, or model-change pressure”: binding law on related controls is in force in Illinois (US-IL). Context only: it does not change this guardrail's grade.
The guard to add
Give every side-effecting tool an idempotency key derived from the tool call, so a retry has its effect once.
In each tool function that changes an external system (payments, refunds, transfers, e-mail, SMS, chat sends, order or ticket creation), derive an idempotency key from the run and the tool-call id (or from the business key, such as order id plus action) and pass it to the downstream API (Stripe idempotency_key=, an Idempotency-Key header, SQS MessageDeduplicationId), or record the key in your own store and return the stored result when it is seen again. Do the same for framework-level retries (LangGraph RetryPolicy, tenacity @retry) around those tools.
Example (Python + Stripe tool), before:
@tool
def refund_order(order_id: str, amount: int) -> str:
stripe.Refund.create(payment_intent=lookup(order_id), amount=amount)
return 'refunded'After:
@tool
def refund_order(order_id: str, amount: int, tool_call_id: str) -> str:
stripe.Refund.create(payment_intent=lookup(order_id), amount=amount,
idempotency_key=f'refund:{order_id}:{tool_call_id}') # a retry refunds once
return 'refunded'Control: Side-effecting agent tool not idempotent when the call is retried. Engineering guidance, not legal advice.
Why
Retries are normal in agent systems: HTTP clients retry on timeouts, orchestration frameworks retry failed steps, and models call a tool again when a result is slow or ambiguous. A tool that refunds, charges or sends without an idempotency key turns each of those retries into a second refund, charge or message. Idempotency keys are long-established practice in payment and messaging APIs. No law or published standard in the corpus addresses tool idempotency, so this guardrail rests on TwinEthos's own engineering judgement.
Class: operational integrity · set: operational integrity · maturity: reviewed · confidence: medium · id guardrail.opint-idempotent-side-effecting-tools
Informational data, not legal advice. Summaries are TwinEthos's own words and rules have not been reviewed by a lawyer: check the official text before relying on any of it. A guard addresses an item; adding it is not a statement that your code meets any law.