# Agent
> Reference for ivar agent: schedule codex, claude or opencode on cron in a sandboxed container or on the host under Landlock, inspect runs and record feedback.
Source: https://ivar.run/docs/reference/agent

`ivar agent` schedules the files in `agents/` as systemd user timers and runs
each one in a container, or on the host with `runtime: host`. Linux with systemd only.

## `ivar agent sync`
```sh
ivar agent sync
```
Installs, updates and removes the timers so they match `agents/*.md`. Touches only units ivar created. Refuses an invalid file, naming the file and the field.

## `ivar agent status`
```sh
ivar agent status --json
```
One entry per agent: `name`, `schedule`, `on_calendar`, `next_run`, `last_run_id`, `last_outcome`, `sync.state` (`in_sync`, `not_installed`, `stale`, `binary_missing`, `invalid`).

## `ivar agent run`
```sh
ivar agent run triage
```
Runs now, through the path the timer uses. Prints the receipt; outcomes are `succeeded`, `failed`, `blocked`, `skipped`, `timed_out`.

## `ivar agent logs`
```sh
ivar agent logs triage --run 20261019T070000Z-ab12cd34
```

## `ivar agent feedback`
```sh
ivar agent feedback 20261019T070000Z-ab12cd34 --rating down --comment "missed the flaky test"
```

## Agent file fields
| Field | Default | Rule |
| --- | --- | --- |
| `schedule` | required | 5-field cron or `@hourly`/`@daily`/`@weekly`/`@monthly`/`@yearly` |
| `tool` | — | `codex`, `claude`, `opencode` |
| `model` | tool default | passed through |
| `image` + `command` | — | replace `tool` |
| `access` | `read` | `read` or `feature` |
| `runtime` | `docker` | `docker` or `host` (installed `tool` with a private copy of your login in `.ivar/agents/state/<agent>/<tool>/`, refreshed logins written back, your own tool config not writable; writes confined by Landlock, reads and network not; no `image`, `command` or `network`) |
| `workdir` | `/workspace` | repo-relative; required for `feature` |
| `write` | `[]` | `runtime: host` only: extra writable paths, absolute, `~/…` or hall-relative; each must exist; refused when it would expose the home, the hall, the tool's login or a guarded hall file |
| `env` | `{}` | `runtime: host` only. Literal variables for the tool's process, such as `{TMPDIR: /tmp, XDG_CURRENT_DESKTOP: KDE}` (with `/tmp` also in `write`: the run writes only its scratch, its state directory and the `write` paths). Names match `^[A-Z_][A-Z0-9_]*$`; `PATH`, `HOME`, any `GIT_*`, the state variables of every tool (`CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME`, `XDG_CONFIG_HOME`, `XDG_CACHE_HOME`) whatever `tool` is set, `OPENCODE_CONFIG_CONTENT` and names in `secrets` are refused. Values stay in the agent file as written and are not redacted: never put a secret here |
| `network` | `[]` | allowed hostnames |
| `secrets` | `[]` | names from `.ivar/secrets/agents.env` |
| `notify` | — | `http(s)://` URL for a JSON run summary, or `telegram:<chat_id>` |
| `timeout` | `30m` | up to `24h` |
| `catchup` | `false` | `true` runs once after the machine was off at the scheduled time |
