> ## Documentation Index
> Fetch the complete documentation index at: https://docs.defiloops.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How it works

> From a sentence to transactions on a chain, what happens in between, and what each part is trusted with

A strategy described in one sentence becomes transactions on several chains,
running for hours or days on an account only you own, without you holding
anything open. This page is what does that: which processes run, what each is
allowed to do, and where the boundaries are.

**The work is not the transactions. It is knowing where to send them.**

A strategy that reads as one sentence: borrow against this, move it, put it to
work: is a dozen sites in practice. Which chain has the rate today, which bridge
to cross with and what it costs, which market has room, what to approve, and in
what order any of it can happen without stranding money halfway. That knowledge
is the barrier, not the clicking, and it is why DeFi stays with the people who
already have it.

Here you name the outcome. The route is worked out for you: the chain, the
market, the pool, the approvals, and the order they have to happen in.

**Then it runs whether or not you are there.** Some steps settle in seconds and
some do not: a limit order might fill this afternoon, or halfway, or never; a
transaction can sit unmined and need sending again at a higher fee. So a run is
not a request that returns an answer. It has to survive you closing the tab, and
survive a deploy, a restart, or a crash nine steps into a fourteen-step plan. A
program holding the plan in its memory would lose it at the first of those.

**Every step is written down as it happens, and a run is rebuilt from that record
rather than remembered.** That is the whole design, and it is why this runs as
its own infrastructure with its own database rather than inside the 0xequity
backend: the only coupling is HTTP reads from that API.

## What a request actually becomes

A person says something in words. Six translations later it is a transaction on
a chain, and each one narrows what is possible:

| stage            | what it is                                         | what it can no longer do                                          |
| ---------------- | -------------------------------------------------- | ----------------------------------------------------------------- |
| **conversation** | a turn in the console, model plus tools            | nothing yet                                                       |
| **pipeline**     | a document of versioned adapter invocations        | name an operation the catalogue does not hold                     |
| **compile**      | typed intents, one per step                        | carry an amount that was never checked against a decimal          |
| **group**        | consecutive steps batched into atomic transactions | let an approval outlive the step it was for                       |
| **sign**         | an EIP-712 intent signed by key B                  | express a destination or calldata: the *type* has no field for it |
| **submit**       | a transaction paid for and broadcast by key R      | authorise anything; R pays gas and nothing else                   |

The narrowing is the product. Each stage is allowed to refuse, and a refusal is
recorded as carefully as an approval, because a refusal is evidence.

See [Adapters](/adapters) for the vocabulary that second row is written in, and
[Kernel](/kernel) for what the last two rows mean about whose money it is.

## What runs, and what each part is trusted with

The parts worth knowing are the ones that hold something.

|              | holds         | and therefore                                                                                                                                                 |
| ------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **signer**   | key B         | a separate process with one method, `SignIntent`, so the thing that authorises is not the thing that decides                                                  |
| **relayer**  | key R and gas | pays for transactions and authorises nothing, see [Kernel](/kernel)                                                                                           |
| **worker**   | nothing       | does the waiting: it is the process that survives a deploy mid-bridge                                                                                         |
| **postgres** | the record    | the replay guard, submission idempotency and the audit log, held as `PRIMARY KEY`s so they survive a restart rather than depending on a process staying alive |

Around those sit the console and its server side, the tool server the model
talks to, a quoting service, a simulator that runs every non-bridge step before
it is broadcast, and the durable-execution engine holding the workflow
histories. One container is reachable from outside; everything else answers only
on the internal network.

The Go services are built from **one image** with a variable choosing which one
runs, so they share every compiled constant: adapter addresses, the intent
schema, the chain tables. That is why they are deployed together and never
singly: two of them on different builds derive account addresses two different
ways, and every group is then refused.

## Why a forked mainnet, not a testnet

Testnets lack the dependencies this system needs: CCTP, lending markets, DEX
depth. So the substrate is a **fork pinned to a block**: a run spends fork
money and settles against real mainnet state, against the same contracts and the
same liquidity that production would meet.

## Durable waiting, and the two things it buys

**Stuck transactions are replaced, never re-sent.** A transaction that does not
mine within its window is replaced at a higher fee **reusing its nonce**, up to
a bump limit, and then goes to a STUCK state for a human. Reusing the nonce is
the whole point: a "retry" on a *fresh* nonce would leave the original still
valid and still pending, both could confirm, and the recipient would be paid
twice. Measured on a fork with mining disabled: four broadcasts, one nonce,
exactly one winner.

**Retries cannot double-send**, because three layers have to agree: the nonce
lease is keyed on the task id so a retry rebuilds an identical transaction, the
submission claim returns the original hash before any broadcast, and the node's
"already known" is treated as success.

## Amending a plan that already moved money

Step 1 lands, step 2 fails, somebody proposes a change, steps 2 and 3 run. That
is a normal outcome, not an exception.

Automatic retry is deliberately minimal: a fee bump for a stuck transaction,
and a couple of attempts for a revert whose cause can clear by itself. Beyond
that the system stops guessing and **parks**, because most real failures need a
decision rather than another attempt at the same thing.

**An amendment may change the future and never the past.** Every step in the
execution log must reappear, unchanged, in order. Altering or dropping an
executed step is refused; so is reusing its task id, and so is resubmitting the
failed step unchanged.

Who proposed it is recorded for **attribution after the fact, not
authorisation**. An owner can be socially engineered and a model can be
prompt-injected, so the validation is identical either way: nothing is trusted
because of who sent it.

Two details that prevent surprises at approval time:

* **Step ids are names, not positions.** If they were indices, inserting a step
  during an amendment would silently repoint every later reference.
* **Symbolic amounts resolve to actual, not requested.** Step 1 asked for 1000
  and delivered 997; step 2 gets 997. A diff reports which steps a human edited
  and which merely *followed*, because "you edited one step and three others
  moved" is the sentence that has to be said out loud.

## Where the boundaries are drawn, and where they are not yet

The calldata invariant is enforced today: the relayer *builds* calldata from
typed parameters and there is no input to that function capable of expressing an
arbitrary call.

The signing invariant is now load-bearing on the paths that move money: the
adapter recovers the agent's signature on chain and refuses anything not signed
by the account's appointed agent, and the relayer is sender of the outer
transaction only rather than holder of the assets.

Two gaps remain named rather than rounded up, because a security document that
describes the design as though it were the build is worse than no document. The
agent guard is a **denylist, not an allowlist**; it blocks control takeover but
not every value movement, and nothing constrains what the relayer *key* signs
once someone holds it. [Kernel](/kernel) says exactly where both bite.


## Related topics

- [FAQ](/faq.md)
- [DeFiLoops](/index.md)
- [Adapters](/adapters.md)
- [The tool server](/tools.md)
- [Running it without you](/automation.md)
