# Transactions and Compensation

Many business operations are not safe as one opaque tool call. A payment,
booking, CRM mutation, or account change may need validation, approval, commit,
reconciliation, and a compensating action.

AIP models those stages explicitly so every connector follows the same
lifecycle.

## Execution Modes

| Mode | Meaning |
|---|---|
| `execute` | Perform the operation normally |
| `dry_run` | Validate or simulate without intended side effects |
| `plan` | Produce a durable plan bound to exact input and policy |
| `commit` | Execute a previously created plan |
| `compensate` | Run the declared compensating operation |
| `reconcile` | Resolve a provider outcome that is currently unknown |
| `rollback_not_supported` | State explicitly that reversal is unavailable |

The capability contract declares which modes exist and the fidelity of a dry
run. Schema-only validation is not equivalent to a provider simulation.

## Plan and Commit

A transaction plan binds:

- transaction, plan, action, and capability ids;
- the canonical input hash and optional snapshot;
- the requesting principal and trusted identity context;
- predicted side effects;
- approval and compensation contracts;
- creation and expiration timestamps.

Commit must reference the plan id. The runtime rejects a commit when the input,
capability, identity, policy, expiration, or transaction binding no longer
matches. This prevents a valid approval for one operation from authorizing a
different mutation.

## Commit Ownership

Only one action may acquire commit ownership for a plan. Storage must provide an
atomic claim with fencing so two workers cannot both perform the provider
mutation after a timeout or restart.

An idempotency record and a transaction claim solve related but different
problems: the first deduplicates a caller request; the second owns the business
commit.

## Unknown Outcomes

The most dangerous failure occurs when the provider may have committed but its
response was lost. AIP records this as `outcome_unknown` and retains the provider
operation reference.

The runtime must then:

1. stop automatic commit retry;
2. query or reconcile the provider using its operation id;
3. record the definitive outcome;
4. only then decide whether retry or compensation is allowed.

Treating an unknown outcome as a normal temporary error can duplicate a payment,
message, or booking.

## Compensation

Compensation is a new governed operation that attempts to offset a committed
side effect. It is not database rollback across independent systems.

The capability contract declares one of four modes:

- `not_required`;
- `supported` with a compensating capability;
- `best_effort`;
- `rollback_not_supported`.

Compensation may have its own approval, idempotency, and failure behavior. The
receipt chain should link it to the action being compensated.

## Transaction States

The wire model includes planned, prepared, committing, committed, compensating,
compensated, requires-human, cancelled, `rollback_not_supported`, failed,
`outcome_unknown`, reconciling, and reconciled states. Operators should query the
transaction view rather than infer transaction state from the action result
alone.

## Design Checklist

- Use a stable provider operation id when the provider offers one.
- Require idempotency for commit and compensation where supported.
- Persist plan, approval, commit claim, provider reference, result, and receipts
  atomically at their ownership boundaries.
- Never advertise `dry_run` as full simulation unless the provider executes the
  same validation path without commit.
- Do not promise rollback for an irreversible provider operation.
- Reconcile unknown outcomes before retrying.
