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

# Build your first agent

> The full path from an idea to a package that has run end to end — plan, commit, build, conform, dry run.

This guide builds one real agent from scratch. It goes deeper than the [quickstart](/quickstart): it explains what each stage produces and what to look at before moving on.

The example agent posts a daily digest of failed payments to Slack.

## Prerequisites

* The `jstm` CLI, signed in. `jstm whoami` should show your workspace.
* An interactive terminal for the planning chat.

<Steps>
  <Step title="Decide what the agent is for">
    Before opening the chat, be able to answer four questions. Joyvis will ask them anyway, and having answers makes the conversation short.

    * **Who needs progress?** The billing team.
    * **What situation creates the need?** Failed payments accumulate overnight and nobody sees them until a customer complains.
    * **What outcome means it worked?** The billing channel has an accurate digest by 09:00, every weekday.
    * **What proves it?** A message in `#billing` listing exactly the payments that failed since the previous digest.

    That last answer matters most. It becomes the evidence the agent is judged against.
  </Step>

  <Step title="Plan it">
    ```bash theme={null}
    jstm agent plan --new
    ```

    Describe the agent, then let Joyvis interrogate the gaps:

    ```text theme={null}
    Every weekday morning, pull yesterday's failed payments from Stripe
    and post a summary to our #billing Slack channel.
    ```

    Expect questions about which Slack workspace, what counts as a failure, whether to include retries, and what to do if Stripe is unreachable. Those answers become boundaries and error policies in the spec.

    Type `/` at the start of a message to search the skills catalog and reference one by name.

    When the plan looks right, press <kbd>Ctrl</kbd>+<kbd>C</kbd>. Copy the session id it prints.
  </Step>

  <Step title="Commit it">
    ```bash theme={null}
    jstm agent plan done 5f3a5c81-2d44-4e0b-9a17-0c9d3b7e9b21
    ```

    This creates the agent and prints its work tree. Read the tree — it's the first chance to see whether the plan matches what you asked for.

    If the tree is wrong, resume the chat and keep refining. Committing again is cheap.
  </Step>

  <Step title="Build a package">
    ```bash theme={null}
    jstm agent build
    ```

    Build compiles the committed spec into an immutable, versioned package. The receipt names the version.

    From here the version is fixed. Any change means a new version, which is what makes every later run traceable to exactly what ran.
  </Step>

  <Step title="Check it against the spec">
    ```bash theme={null}
    jstm agent conform ./failed-payment-digest
    ```

    Exit `0` means the package is clean. Exit `1` means at least one blocking problem, each one citing the spec clause it breaks.

    Most findings are mechanical — a missing field, a bad enum, a dangling file reference. Fix and re-run. For findings you've decided to accept, see [Acknowledging flags](/features/conformance/ignores).
  </Step>

  <Step title="Check it can actually run">
    ```bash theme={null}
    jstm agent readiness failed-payment-digest
    ```

    Readiness answers a different question from conformance. Conformance asks whether the package is well-formed. Readiness asks whether the skills it needs can actually execute here — are the MCP servers reachable, are the credentials present.

    If there are blockers, the command exits non-zero and names them. Many have a targeted fix:

    ```bash theme={null}
    jstm agent readiness-fix failed-payment-digest --action fix-credential
    ```
  </Step>

  <Step title="Dry-run it">
    ```bash theme={null}
    jstm agent dry-run failed-payment-digest --input '{"date":"2026-08-03"}'
    ```

    The agent executes end to end with side-effecting actions held back. Nothing is posted to Slack; nothing is changed in Stripe.

    Progress streams story by story. Add `--verbose` to see an output preview for each step.
  </Step>

  <Step title="Read the evidence">
    ```bash theme={null}
    jstm agent run show failed-payment-digest/runs/1
    jstm ticket list --agent-id failed-payment-digest
    ```

    `run show` gives you the run's status, its stories, its output, and the exact versions that executed. `ticket list` gives the same work in business language.

    Now compare against the answer you wrote down in step one. Did it identify the right payments? Would the digest have been accurate? That comparison — not the absence of an error — is what tells you whether the agent works.
  </Step>
</Steps>

## What you have

An agent that exists as a versioned package, is provably well-formed, can reach its dependencies, and has completed a full execution without touching anything real.

It is still at Dry Run. That is where it stays until you decide the evidence justifies moving on.

## Next

<Columns cols={2}>
  <Card title="Promote to production" href="/guides/promote-to-production" icon="rocket">
    Move through Pilot to Live.
  </Card>

  <Card title="Connect a service" href="/guides/connect-a-service" icon="plug">
    Give the agent real Stripe and Slack credentials.
  </Card>
</Columns>
