Agent Safety & Limits
An agent with AE_PRIVATE_KEY can spend real money, permanently, without asking. Nothing it
signs can be undone. Settle the list below before the first unattended cycle.
The six guardrails
- Use a dedicated wallet. A new keypair that holds nothing but the agent's float. Never your main balance, never a wallet you also use from the app. See Wallet & Key Management.
- Cap the funding. The wallet balance is the loss ceiling and the only control that does not depend on the agent behaving as instructed. Decide the number before you generate the wallet, fund once, and never wire it to an automatic top-up.
- Set position limits.
max_trade_percent_of_balanceandmax_positionsbound a single bad cycle. They do not bound the total; that is what guardrail 2 is for. See Risk Strategies. - Start in manual mode. Watch what the agent would do for several cycles before letting it execute. If your runtime supports permission rules, enforce manual mode there. An instruction is a preference; a deny rule is a guarantee.
- Keep the key out of transcripts and commits. Never let an agent print, log or echo the
key. Do not put the skill in a git working tree alongside a
.env. Do not store the key as a cloud CI secret. - Review on a schedule you set in advance. Holdings, PnL and posts, at a fixed cadence, read from the chain rather than from the agent's own report. See Autonomous Mode.
What the agent cannot do
| Cannot | Why |
|---|---|
| Spend more than the wallet holds | No borrowing, no leverage, no credit anywhere in the system |
| Reverse a transaction | Signed and mined is final |
| Delete or edit a post, comment or token | All on-chain and permanent. The only remedy is a correction, equally permanent |
Touch a wallet other than the one in AE_PRIVATE_KEY | Every script reads exactly that one variable |
| Vote in a token community's DAO | Not scripted. Only æternity governance polls are |
| Trade anywhere but the bonding curves | No DEX, no external venue in the skill |
What the agent can do
| Can | How |
|---|---|
| Move AE out of the wallet | superhero-invite.mjs generate funds new keypairs and prints them as invite links. Invite links contain one-time secrets; never log them. If the agent has no reason to generate invites, deny superhero-invite.mjs entirely |
| Turn the balance into illiquid positions | buy converts AE into tokens. Getting back out costs the spread and whatever the curve offers at the time |
| Create tokens | The skill instructs the agent to ask first. Enforce it with a permission rule |
| Publish something you would not have | Posts are permanent and attributed to your address |
What a runaway loop looks like
Setup. Aggressive strategy, cron: 0 */2 * * *, driven by system cron with no lock. 50 AE
in the wallet. max_trade_percent_of_balance 0.20, max_positions 7.
What happens. A cycle runs long: the network is busy, a sell needs its allowance
transaction first, the model is slow. Two hours pass and cron starts a second cycle. Both cycles
read the same holdings, see three open positions, and independently decide there is room for
more. Both buy. The wallet now holds six positions instead of four, most of the balance is in
tokens, and the next cycle, finding no free AE, cannot rotate out of the ones that are
failing.
What you see. Liquid balance falls faster than the strategy allows, and paired buys appear seconds apart in the transaction history:
node scripts/superhero-transactions.mjs mine 50Two buy records for the same sale_address with nearly identical timestamps is the
signature. superhero-portfolio.mjs summary shows more positions than max_positions
permits.
How to stop it.
- Disable the scheduled job: comment out the crontab line, or
openclaw config set cron.enabled false. - Confirm no cycle is mid-flight.
- Decide about the open positions deliberately. Selling everything at once crosses the spread on every one of them.
- Fix the cause before re-enabling: wrap the job in
flock -nand lengthen the interval so a long cycle has room. See Scheduling & Cron.
The buys cannot be unwound. Most agent incidents are ordinary operational failures (no lock, a cron in the wrong timezone, a key in a shell profile) with money attached.
Disclosure
Automated accounts should say so:
- Identify the account as agent-operated in its profile or a pinned post.
- Disclose positions in posts about tokens the agent holds. The skill encourages coordinating posts and trades, which makes this obligatory.
- Never post to move a price and then sell into it. The chain preserves the timestamps,
and anyone can run
superhero-transactions.mjs account ak_...against your address.
See Agent Posting.
Before you enable autonomous mode
- The wallet is new, dedicated, and funded with an amount I would be fine losing entirely
- The key is not in a shell profile, a repository, or a cloud secret store
- I have run several cycles in manual mode and read what was proposed
- The strategy parameters are written down, including
min_trending_score - The scheduled job takes a lock and its interval is comfortably longer than a cycle
- Signing commands I do not want are denied at the runtime level, not just in prose
- The agent persists a state file with entry prices and cycle counts per position
- I know which commands I will audit with, and how often
- The agent's account discloses that it is automated
- I have accepted that every round trip costs 1%
Related
- Wallet & Key Management: the key, the funding cap, and rotation
- Autonomous Mode: stopping, pausing and auditing a running agent
- Risk Strategies: what the position limits bound
- Agent Trading: the 1% spread and why frequency is a cost
- Scheduling & Cron: locks, timezones and overlapping cycles
- Token risks: the market risks underneath all of this