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

# Best practices

> How to write Agent Application packages that are portable, legible, and safe to operate.

Agent Application packages work best when they describe a real application contract rather than a vague project folder. The goal is to make your package useful across runtimes while keeping it legible to humans.

## Start from the actual CLI

Begin with the real command surface before writing any documentation. Identify:

* what command launches the application
* which subcommands agents may call
* what JSON each command returns
* which actions are destructive
* where the application stores its source-of-truth state

<Tip>
  The strongest packages come from a real executable interface, not a speculative manifest. Write `APP.md` to describe what the CLI already does.
</Tip>

For example, the Agentic To-Do `APP.md` frontmatter declares the entry command and every supported subcommand before the body explains anything:

```yaml theme={null}
entry:
  command: node app/cli.js
commands:
  - add
  - list
  - get
  - update
  - complete
  - remove
```

## Keep the package shape legible

A reader should be able to orient themselves quickly. Each canonical part has a clear role:

| Path       | Purpose                              |
| ---------- | ------------------------------------ |
| `APP.md`   | The application contract             |
| `app/`     | The runnable payload and owned state |
| `skills/`  | Local operating guidance             |
| `schemas/` | Optional output and entity shapes    |

<Warning>
  If the package shape is hard to follow, activation will be hard to follow too. Avoid blurring responsibilities between directories.
</Warning>

Only include `schemas/` when it adds clarity to the contract. It is optional in v1.

## Document state and side effects clearly

Agents need to know what your application owns and how mutations work. In `APP.md`, document:

* the primary state location or state model
* whether commands mutate data
* how IDs are assigned and reused
* what confirmation steps destructive commands require

<Tip>
  If a runtime has to guess what the application owns, the package contract is not clear enough yet. State ownership is one of the most important things `APP.md` communicates.
</Tip>

The Agentic To-Do example makes state ownership explicit:

```md theme={null}
## State

The application stores data in `app/state/todos.json`. IDs are stable and
increment as `td_0001`, `td_0002`, and so on.
```

## Keep `APP.md` and skills separate

`APP.md` should describe the application boundary and command surface. Local `SKILL.md` files should describe reusable operating guidance.

* If you find yourself copying command semantics into every skill, improve `APP.md`.
* If you find yourself copying operating procedures into the body of `APP.md`, move that guidance into a local skill.

<Warning>
  Blending these two concerns makes both harder to maintain. Runtimes that discover skills separately from the full application contract depend on this boundary being clear.
</Warning>

## Prefer stable JSON and stable identifiers

Agents benefit from predictable output. Design your CLI so that:

* successful commands return machine-readable JSON on stdout
* failures return structured JSON errors when possible
* entity IDs remain stable across runs
* human-readable output is opt-in rather than the default

<Tip>
  Stable outputs make packages easier to test and safer to automate. If your CLI changes output shape between runs for the same command, write evals to catch regressions early.
</Tip>

Here is an example of a well-structured success response:

```json theme={null}
{
  "ok": true,
  "command": "list",
  "count": 1,
  "items": [
    {
      "id": "td_0001",
      "title": "Write docs",
      "status": "open",
      "dueAt": "2026-04-05"
    }
  ]
}
```

And a well-structured failure response:

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "CONFIRMATION_REQUIRED",
    "message": "remove requires --confirm."
  }
}
```

## Write defaults, not menus

When several approaches are possible, choose a safe default and state the exception path briefly. That is more reliable than giving an agent an unranked list of options.

<Tip>
  A single recommended path is more useful than an exhaustive list of alternatives with no guidance on when to use each one.
</Tip>

## Validate with real runs

A package is ready to ship when:

* the documented `entry.command` is callable
* `commands` matches the actual runtime surface
* state lives in the application rather than prompt memory
* destructive commands enforce their confirmation rules
* local skills improve operation without contradicting `APP.md`

Use the [optimizing descriptions](/authoring/optimizing-descriptions) and [evaluating packages](/authoring/evaluating-packages) guides to tighten the package over time.
