# artifacts

The step-level `artifacts` field declares the files a step is expected to produce. Pair it with [`inputs`](/steps/inputs) (the step's sources) — the two are separate, sibling fields, not one nested inside the other.

```yaml
steps:
  - name: compile
    type: shell
    command: go build -o bin/handler ./cmd/handler
    inputs:
      sources: ["cmd/**/*.go", "go.sum"]
    artifacts:
      paths: ["bin/handler"]
```

If any `artifacts.paths` pattern matches nothing, the step always reruns — regardless of whether `checksum.changed`/`timestamp.changed` say "unchanged" — because a missing output is never "up to date." See [`inputs`](/steps/inputs) for how `artifacts` combines with `sources` to compute freshness, and the implicit `when: checksum.changed` default.

## Fields

- **`paths`** — List of glob patterns (relative to the step's working directory) for this step's expected output files. Named `paths`, not `files`, since artifacts aren't always known file-by-file (e.g. a directory glob).

## Facts exposed to `when`

- **`artifacts`** — The resolved list of files matched by `artifacts.paths`, as structured records (`path`, `mtime`, `checksum`) — see [inputs: Advanced: structured records](/steps/inputs#advanced-structured-records).

`artifacts` can also be used on its own, with no `inputs`, if a step's freshness only depends on whether its output already exists — though most steps declare both.

:::note Custom commands
The same `artifacts` field works identically on [custom command](/cli/configuration/commands) steps.
:::
