Skip to content
BETAGuardrails are in beta. The library, the configuration format and the CLI command can still change.

Guardrails / claude

Claude answers CI in a format a program can read

claude/cli-structured-output@v1

Every headless Claude CLI invocation the build executed asked for structured output.

Idclaude/cli-structured-output
Versionv1
Categoryclaude
Default severitywarning
Interpreterpython3
Timeout30 seconds
Violations tolerated0
Collectscommands

Collectors

This guardrail gathers nothing itself. It depends on the collectors below, which the CLI runs once per build before any check, and reads what they found out of GUARDRAIL_FACTS. A collector that collects nothing skips this guardrail rather than failing it.

CollectorGathersInputs it is given
commandsEvery command the build executed, read from the session a running buildnote monitor records on the runner. Gathering is dynamic rather than static: this is what the job actually ran, not what a pipeline file says it would run.none

The inputs above are this guardrail's own, passed straight through. Configuring one in buildnote.json changes what is collected, and two guardrails configured the same way share the one collection.

Configuration

json
{
  "guardrails": {
      "failOn": "error",
      "checks": [
          {
              "use": "claude/cli-structured-output@v1",
              "severity": "warning",
              "with": {
                  "formats": "json,stream-json"
              },
              "exemptions": []
          }
      ]
  }
}

Inputs

InputDescriptionDefaultEnvironment variable
formatsComma separated --output-format values that count as structured.json,stream-jsonGUARDRAIL_INPUT_FORMATS

How to fix

Add --output-format json to the invocation:

bash
claude -p --output-format json 'summarise what changed' > review.json

A headless run is read by a program rather than by a person, and prose is read by guessing at it: a step that greps for FAIL in an answer passes the day the model words it differently. JSON carries the result, the cost and the session id as fields, so the job branches on a value rather than on a phrasing.

More in claude

All 3 claude guardrails

Buildnote Limited
Registered in England and Wales, Reg: 16140412