# AGENTS.md

> What to put in your mini app's agent instructions, and why CLAUDE.md is one line long.

Source: https://miniapp.sollar.com/ai/agents-md/

---

`sollar create-mini-app` writes an `AGENTS.md`. This page explains what belongs in it and why the
companion `CLAUDE.md` contains exactly one line.

## The two-file pattern

```
AGENTS.md      ← every instruction
CLAUDE.md      ← @AGENTS.md
```

`AGENTS.md` is the filename Codex, Cursor, Jules, Factory and Aider look for. Claude Code reads
`CLAUDE.md` and does **not** read `AGENTS.md`.

```markdown title="CLAUDE.md"
@AGENTS.md
```

One source, one pointer. The alternative — the same instructions written into both files — drifts
within a month, and nothing tells a reader which copy is current.

## What the scaffold writes

```markdown title="AGENTS.md"
# Acme ERP — a Sollar mini app

## What this is

A mini app that runs inside the Sollar superapp: a signed web package, served from its own
synthetic origin, with capabilities declared in `manifest.json`.

Reference: https://miniapp.sollar.com/llms.txt

## Rules that are not negotiable

- **The client is not an authority.** `sollar.identity.get()` is for drawing UI. Every
  authorisation decision happens on the backend, against the token, every time.
- **The manifest is the ceiling.** A permission or a host not declared in `manifest.json`
  cannot be obtained at runtime. Adding one means a new version, not a code change.
- **No secret reaches this codebase.** No client_secret, no API key, no signing key, no
  refresh token — not in .env, not in a config file, not in a comment. Call
  `sollar.auth.getToken()` before each use.
- **Device capabilities are Web APIs, not bridge methods.** Camera is
  `navigator.mediaDevices.getUserMedia`. Location is `navigator.geolocation`. If you are
  reaching for `sollar.<device thing>()`, it does not exist.
- **There is no payment API.** A mini app cannot take money in-app on either platform.
- **The backend cannot post into an encrypted room.** Use `sollar.message.send()` from the
  user's client, or an agent that is a member of the room.

## Before you write code

Read these, in this order:
1. https://miniapp.sollar.com/reference/manifest.md
2. https://miniapp.sollar.com/reference/bridge-api.md
3. https://miniapp.sollar.com/guides/authentication.md

Do not guess the bridge version. Run `sollar --version`.

## This project

- Backend: https://erp.acme.example — declared in `manifest.network.connect`
- Auth mode: sollar-exchange, audience `acme-erp-backend`
- Actions: see `manifest.json`. Every one needs a handler in `src/actions.js`.

## Before you say you are done

    npx sollar validate --strict
    npm run test:unit
    npx sollar test --conformance

`validate --strict` runs the same checks as the submission gate. If it fails, the work is not
done.
```

## Why each rule is there

Each line in that file corresponds to something an agent gets wrong reliably.

| Rule | The failure it prevents |
|---|---|
| The client is not an authority | An agent reads `app_user_id` from the bridge and authorises on it. It looks correct and is the defining vulnerability of this platform class. |
| The manifest is the ceiling | An agent adds a `fetch` to a new host and cannot understand why it fails. `ERR_HOST_NOT_ALLOWED` is not a bug. |
| No secret in the codebase | An agent asked to "configure the API key" will write it into `.env` unless told otherwise, and it will be committed. |
| Web APIs, not bridge methods | Invented methods are the most common single failure. `sollar.getLocation()` is exactly what a well-trained model expects to exist. |
| No payment API | An agent that knows WeChat will reach for `requestPayment`. |
| Encrypted rooms | The obvious notification design is a server-side post, and it silently does not work. |

## Keep it short

An instruction file competes for context with the code the agent needs to read. A 400-line
`AGENTS.md` is worse than a 60-line one, because the important rules are diluted.

The test for a line: **could the agent derive this from the code?** Directory layout, dependency
list, "this file handles routing" — all derivable, all wasted tokens. What belongs is what the code
does not say: the magic value, the counter-intuitive library behaviour, the product decision, the
lesson from an incident.

## Point at URLs, do not copy

```markdown
Read https://miniapp.sollar.com/reference/bridge-api.md before calling any sollar.* method.
```

Not:

```markdown
The bridge API has the following methods: sollar.identity.get() returns…
```

A copied API surface is a copy that will be wrong after the next release, sitting in a file the agent
trusts. Link to the `.md` twin and it is always current.

## Add what is specific to you

The scaffold cannot know your project. Add:

- **Domain vocabulary.** If "approval" means something specific in your organisation, say so.
- **Authority limits.** "An agent may approve up to €5,000; above that a human approves directly."
- **What is irreversible.** If an action releases an order to a vendor, the agent should know before
  it writes the handler, not after.
- **Anything an incident taught you.** These are the most valuable lines in the file and the ones
  nobody writes down.

## What not to put in it

- **Secrets.** Ever, in any form, including "the key is in 1Password item X" written as a value.
- **Duplicated documentation.** Link to it.
- **Directory listings.** The agent can run `ls`.
- **Instructions that contradict the platform.** "Skip validation to save time" produces a mini app
  that fails at submission, having wasted the time it saved several times over.
