LIMEN
TESTNET

Documentation

Limen builds agents that can spend on Stellar, and gives each one a boundary the account enforces rather than the agent observes. This is how it works and what it refuses to claim.

TESTNET ONLYNOT AUDITEDCOMPOSITION ONLYNO OWNER CUSTODY

What Limen does

You describe an agent in a sentence. Limen drafts it — the job, the token, a ceiling per period, an expiry — and shows you those limits before anything is signed. When you approve them it deploys the agent onto Stellar in one flow: a Soroban smart account of its own, a signing key registered against that account, and the boundary installed on that key. Then you message the agent, and it acts on your behalf.

The boundary is the part worth reading twice. It is a context rule and a policy contract on the account, checked by the account before a token moves — so what the agent may do is not a rule it has been asked to follow. It is a rule it is unable to exceed, and it stays enforced whether or not Limen is running.

Where a boundary comes from is the other half. Limen would rather read one off a transaction that already happened than ask you to describe one in the abstract: given an observed transfer, it derives the minimum context rule and policy set that would have permitted it — the contracts it touched, the functions it invoked, the outflow that occurred, and a window. The derived cap equals the observed outflow exactly. That equality is the design, not a coincidence — a boundary rounded up to a comfortable number is a boundary somebody chose, and choosing is the step this removes.

What it is not

These limits are stated here rather than discovered later, and they are the same four labels that appear above every screen.

  • Testnet only. Every address, hash and reading in this documentation is Stellar testnet. There is no mainnet build.
  • Not audited. The OpenZeppelin contracts Limen installs are audited. The code that decides what to install — the synthesizer, the lowering, this application — is not, and no third party has reviewed it.
  • Composition only. Every policy is a configuration of an existing audited primitive. No Rust is generated and none is written by hand, which is the claim as a number rather than as a promise.
  • No owner custody. The key that owns your account — a passkey, or a key generated in your browser — never reaches a Limen server, an environment variable, or a log line. Limen cannot move your funds outside the boundary you installed, and cannot remove that boundary.
  • One transaction in. A boundary is derived from a single observed transaction. Deriving from a set of them, and deciding what their union should permit, is not built.

The recorded run

Everything in these pages is described against one run recorded on testnet. Its addresses and hashes are read from deployments/testnet.json, so they cannot drift from what was actually executed.

Smart account
CBNPFNPW…RD3G3V
Context rule
#5
Policy contract
CDWPYL45…TH4CSE
Cap
0.1
Refused
c4fff69b…004b SpendingLimitExceeded#3221

The rest of these docs

  • Deriving a boundaryFrom one observed transaction to the narrowest context rule and policy set that permits it.
  • The authorization pathWhat runs inside __check_auth, in what order, and where a refusal actually comes from.
  • TablesContract error codes, policy primitives, the deny axes, and environment variables.