Skip to content
agentic-pipelines

What lives on disk

The data repo

text
my-data-repo/  pipelines.yaml              # channels: {}, and optionally defaults:  .env                        # secrets, gitignored  .params.local.json          # local params, gitignored (written by `install`)  agents/    <agent-name>.md           # YAML front matter + Markdown prompt  pipelines/    <pipeline-name>/      pipeline.yaml      steps/        <step>.md             # prompts for `agent` steps, by convention  scripts/    <notify-channel>.sh       # scripts invoked from `channels.<x>.run`  .runs/                      # gitignored, generated by the engine  .gitignore                  # must include: .env, .params.local.json, .runs/

pipelines.yaml

It lives at the root of the data repo, not the engine's. It can be empty (channels: {}), but it must exist: it's the marker the engine uses to find the repo root by walking up directories.

yaml
channels:  email:    type: shell    env: [EMAIL_API_KEY]    run: scripts/notify-email.sh

The channel fields and what a channel script receives are in Notifications.

pipelines.yaml also accepts a repo-level defaults: block (on_error, retry, timeout, notify), with the same shape as a pipeline's defaults:. It is currently not applied to pipelines automatically: each pipeline.yaml still declares its own.

Secrets

Never in plaintext in any YAML. A secret is declared by name in requires.env (a pipeline) or channels.<x>.env (a notification channel), and its value is resolved at runtime:

  1. From .env at the root of the data repo (KEY=value lines, # comments, optional quotes). It takes precedence.
  2. If it isn't there, from the process's own environment.

ANTHROPIC_API_KEY is the one value you don't declare: the engine reads it from .env (or the environment) by itself and passes it only to agent steps.

A name in requires.env can depend on params (QA_{{params.app}}_USER); see Secret names that depend on params.

.env and .params.local.json are in the data repo's expected .gitignore; they are never committed.

.runs/

A gitignored directory at the root of the data repo, with one subdirectory per pipeline and per run:

text
.runs/  .locks/    <pipeline>.lock  <pipeline>/    <run-id>/            # ISO 8601 with ':' and '.' replaced by '-'      run.json      <step-1>.log      <step-2>.log      ...

Each <step>.log holds the step's transcript, with any secret value already replaced by [redacted] before it touches disk.

run.json

The run record:

FieldNotes
id, pipeline, pipelineVersion
statusrunning, success, failed or skipped
startedAt, finishedAtISO 8601
paramsThe resolved params this run ran with
stepsMap of step id → step record
totalCostUsdSum of costUsd across all agent steps
skipReasonOnly if status is skipped

And per step:

FieldNotes
status, startedAt, durationMs, attempts
outputsAlready validated against the step's outputs: contract
costUsd, inputTokens, outputTokens, toolsUsedOnly in agent steps
errorFailure message, if any
skipReasonIf the step was skipped by its step-level when:
denialsTools denied by the sandbox hook; see Agent steps and the sandbox

Where everything else lives

WhatWhereNotes
Run history.runs/ in the data repoGitignored. One subdirectory per pipeline and per run.
Locks.runs/.locks/<pipeline>.lockIf a run died holding the lock, run exits with 3 until it's cleared.
Installed params.params.local.json in the data repoGitignored. Written by install --set.
Secrets.env in the data repoGitignored. Only names go in the YAML, never values.
WorkspacesBy convention, ~/Library/Application Support/pipelines/workspaces/<pipeline>/ on macOS and ~/.local/share/pipelines/workspaces/<pipeline>/ on Linux, passed in through a paramEach pipeline's own clones. Pipelines shouldn't work in your checkouts: to see what they produce, git fetch in yours.
Scheduled jobsmacOS: ~/Library/LaunchAgents/cat.start.pipelines.<name>.plist. Linux: ~/.config/systemd/user/cat.start.pipelines.<name>.{service,timer}Derived from triggers.cron. No param values inside.
Job logsmacOS: the path in the plist (StandardOutPath / StandardErrorPath), by default ~/Library/Logs/pipelines-<name>.log. Linux: ~/.local/state/pipelines/logs/pipelines-<name>.logWhat happened before the engine got as far as writing to .runs/.

Written from agentic-pipelines at b8b4db7: README.md, docs/reference.md.