Key points
- A step needs exactly one mode.
scriptcannot be combined withgoal,tasks,include, orapproval. steps[].imageoverrides the pipelinecontainer_imagefor that step only.steps[].volumesmounts named Docker volumes or Kubernetes PVCs asvolume:/mount/path; existing storage is reused and missing storage is created.- Mounting the reserved runtime output path
/nopsai/outputsis rejected, and a step may declare at most 32 volumes. - A script step cannot define
mcp_profiles— tools belong to LLM-backed work. - With blocking guardrail or policy knowledge context in scope, the exact command is validated by the model before it executes.
Examples
- name: verify
image: golang:1.24
volumes:
- build-cache:/root/.cache
script: |
go vet ./...
go test ./...name: release-service
description: Build, verify, and publish the payments service.
container_image: alpine:3.20
working_directory: /workspace
timeout: 45m
steps:
- name: build
script: |
make build
- name: verify
image: golang:1.24
volumes:
- build-cache:/root/.cache
script: |
go vet ./...
go test ./... - name: verify
script: go test ./...
goal: Check the tests pass.Field reference
steps[].scriptstep modestringConditionalNone
Direct shell step. With blocking guardrail or policy knowledge context, the exact command is LLM-validated before execution.
script: |
make build
make test- Cannot be combined with
goalortasks. - Cannot define
mcp_profiles. - With
llm_enabled: false, blocking knowledge context on the script is rejected.
steps[].namestepstringRequiredNone
Unique step name. Dependencies and runtime output references address the step by this name.
name: build- Must be unique within the pipeline.
- A step without a name fails validation.
services/nopsai/pkg/validation/pipeline.go
steps[].imagestepstringConditionalPipeline `container_image`
Executable image for this step. Required when the pipeline has no container_image.
image: golang:1.24services/nopsai/pkg/validation/pipeline.go
steps[].volumesstepstring[]OptionalNone
Named Docker volume or Kubernetes PVC mounts in volume:/mount/path form. Existing storage is reused; missing storage is created.
volumes:
- build-cache:/root/.cache- Maximum 32 volumes per step.
- Mounting the reserved runtime output path /nopsai/outputs is rejected.
services/nopsai/pkg/validation/pipeline.go
steps[].volumes (max per step)limitcountOptional32 maximum per step
Maximum volume mounts declared on a single step.
step 'build' has 33 volumes; maximum is 32services/nopsai/pkg/validation/pipeline.go
How it works
Step names are how everything else refers to a step: dependencies, output references, and the run graph all use them. Choose names you are willing to see in a failure message.
Volumes are how work survives between steps that do not share a container. The workspace itself is already shared for the whole run; a volume is for caches and artefacts you want to keep across runs.
Implementation evidence
services/nopsai/pkg/validation/pipeline.goRules the validator enforces on this directive set.
services/agent/internal/app/pipeline.goStep execution and the reserved output mount.

