# Create an agent

Create a workspace, write a local layer, add published layers, compose them, build, run, and push.

This path needs a `rig` whose `rig help` lists `rig new` and `rig add`, Nix with flakes, and network access to https://repo.slopkit.dev. Install the CLI on [Getting started](https://rig.slopkit.dev/start/) if you do not have it. `rig update` re-runs that installer.

Do not catalog published images. `git` and `unslop` here are samples. Browse others at https://repo.slopkit.dev.

## Create a workspace

In an empty directory, run:

```
rig new workspace
```

Match:

```
created workspace → rig-workspace
```

Then:

```
cd rig-workspace
```

The flake is:

```
{
  description = "rig workspace";
  inputs.rig.url = "git+https://gitlab.techtailors.net/slopkit/rig?ref=main";
  inputs.nixpkgs.follows = "rig/nixpkgs";
  outputs = args: args.rig.lib.workspace args;
}
```

A destination that exists and is not empty exits 1 with `exists and is not empty`.

## Write a layer

Run:

```
rig new layer notes
```

Match a line that starts with `created layer notes`. The file is `layers/notes/default.nix`. The name is the directory. The file is the module body. There is no `agent.layers.notes` wrapper.

Replace that file with:

```
{ pkgs, ... }:
{
  description = "Scratch notes conventions.";
  packages = [ pkgs.jq ];
  files."AGENTS.md" = {
    source = ./AGENTS.md;
    mergeable = true;
  };
}
```

Create `layers/notes/AGENTS.md`:

```
Keep notes in markdown. Prefer short sentences.
```

`packages` puts Nix packages on PATH. `files` writes into the agent home. `AGENTS.md` is mergeable even when `mergeable` is unset. Later compose entries override on conflict. Mergeable files concatenate.

`skills` pin a local path or a GitHub repo. Sandbox, MCP, secrets, triggers, services, harness tools, hooks, and models are in https://rig.slopkit.dev/raw/layer.md.

Run:

```
rig inspect ./layers/notes
```

Match:

```
=== layer: notes ===
source: local workspace
path: …/layers/notes
description: Scratch notes conventions.
depends: (none)
skills: (none)
mcp: (none)
sandbox: allowNet=0 denyNet=0 writeAllow=0
files: AGENTS.md
hooks: (none)
```

The `path` line is the absolute directory.

## Add published layers

`rig add` pulls the image and adds a flake input. It does not edit agent files. It does not add layers named in that layer's own `compose` list.

Run:

```
rig add git@latest
rig add unslop@latest
```

Match:

```
added layer git → https://repo.slopkit.dev/layers/git@latest/flake.tar.gz
added layer unslop → https://repo.slopkit.dev/layers/unslop@latest/flake.tar.gz
```

The card must include a flake archive. If it does not, add exits with `layer '<name>' has no flake archive; rig pull still works for run`.

`git` is a CLI and a git skill. `unslop` is a pinned skill and an `AGENTS.md` slice.

Run:

```
rig inspect git
```

Match a block that starts with `=== layer: git ===` and includes `source: local workspace` and `skills: git`.

## Compose the agent

Run:

```
rig new agent writer
```

Match a line that starts with `created agent writer`. The scaffold already lists every local `layers/*/default.nix` name. It does not list flake inputs.

Replace `agents/writer/default.nix` with:

```
{ layers, ... }:
{
  name = "writer";
  description = "What this agent is for.";
  compose = [
    layers.notes
    layers.git
    layers.unslop
  ];
}
```

`compose` is a list of modules. Later entries override on conflict. Do not list `base`. Eval prepends it.

Run:

```
rig inspect writer
```

Match:

```
=== agent: writer ===
source: local workspace
description: What this agent is for.
compose (declared): notes → git → unslop
compose (resolved): base → notes → git → unslop
skills: agentfile-base, git, unslop
harnesses: claude, flue
layers:
  base: skills=1 mcp=0 hooks=0
  notes: skills=0 mcp=0 hooks=0
  git: skills=1 mcp=0 hooks=0
  unslop: skills=1 mcp=0 hooks=0
```

## Build the agent

From the workspace directory:

```
rig build writer
```

That is `nix build .#agents-writer -o .agent`. Match:

```
build writer: base → notes → git → unslop (flake .#agents-writer)
```

Then a materialized line with `.agent`, a store path, and counts. Observed: `files=13 skills=3 mcp=0`.

Unknown harness exits 1. Missing name exits 1 with `error: build requires an agent name`.

## Run the agent

From the same workspace:

```
rig session create --agent writer --backend nix --prompt "Hello."
```

Create starts a local runtime when one is not already up. Match `running` on the session print. The login query is a one-time token. Your ticket, id, and session name may differ.

```
writer  running
https://127.0.0.1:7443/sessions/writer?login=<ticket>
agent    writer
backend nix
id       <id>
```

Open the printed URL in a browser.

## Push the image

Needs secretspec credentials for `scopes.s3`.

```
rig push repo.slopkit.dev/writer:latest
```

`image` is required. Image ref forms are in https://rig.slopkit.dev/raw/cli.md.

## Check

```
rig list-agents
```

Match:

```
Agents:
  writer           compose: base notes git unslop
```

```
rig list-layers
```

includes `base`, `git`, `notes`, and `unslop`.

## Undo

Delete the `rig-workspace` directory. That removes the flake, local modules, and added inputs.

`rig add` does not create those directories. Removing only the `inputs."git".url` and `inputs."unslop".url` lines from `flake.nix` drops those layers from the workspace catalog. The dest-store pull stays until `rig layer remove`.

A session keeps running after you delete the workspace. `rig session list` still shows it.
