Skip to content

CLI Reference

Every command accepts -v / --verbose for debug-level logging and --help for detailed usage. --output-format is a global flag taking text (the default), json or markdown.

What --output-format does and does not promise

Read this before you parse Pacto's output in a script.

  • json describes a successful result. When a command cannot produce its result at all — an unreachable reference, a missing pacto.lock — the error goes to stderr as plain text and stdout stays empty, whatever --output-format said. But a verdict of "no" is a result, not a failure: pacto validate on an invalid contract and pacto diff on a breaking change both print their whole JSON document to stdout and exit 1. So the exit code does not tell you whether there is anything to parse — an empty stdout does. Read stdout when it is non-empty; read the exit code for the verdict.
  • markdown is implemented by pacto diff only, for posting a diff as a CI comment. Every other command silently renders text instead.
  • Key casing is not uniform. pacto validate emits capitalised keys ("Path", "Valid", "Errors"); every other command emits camelCase ("path", "root", "upToDate"). Match the command you are calling.
  • An unrecognised value is ignored, not rejected. --output-format yaml prints text and no warning — there is no YAML output — so a typo is indistinguishable from success.

The interactive and side-effecting commands (login, logout, update, mcp, dashboard) inherit the flag from the root command and always emit text.


Global flags

      --config string          config file path
  -h, --help                   help for pacto
      --no-anim                disable animations
      --no-cache               disable OCI bundle cache
      --output-format string   output format (text, json, markdown) (default "text")
  -v, --verbose                enable verbose output

Exit codes

Pacto exits 0 or 1 and nothing else. 0 means the command produced its result and the result was acceptable; 1 means anything else. Because there is no third code, the exit status alone never distinguishes "the check failed" from "the command could not run".

Exits 1 Exits 0
pacto diff where the overall classification is BREAKING a POTENTIAL_BREAKING or NON_BREAKING diff
pacto validate reporting at least one error validation that reported only warnings
pacto lock --check on a stale lockfile, or with none at all (LOCK_MISSING) a lockfile that is up to date
any command that could not run — an unresolvable reference, an unreadable bundle, an unknown flag pacto impact run on declared-only sources, whatever it classifies (see below)

Two rows deserve emphasis, because both silently break a CI gate:

  • A pacto diff against a reference that does not exist exits 1 exactly like a breaking change does.
  • pacto impact exits non-zero only when the change is breaking and a live source shows an incompatible consumer. With declared-only sources there are no consumers to find, so it prints Classification: BREAKING and still exits 0.

Use stdout, not the exit code, to tell a verdict from a failure. A command that produced a verdict writes it to stdout and puts a one-line summary on stderr. A command that could not run writes nothing to stdout:

Invocation Exit stdout stderr
pacto diff --output-format json OLD NEW (breaking) 1 the full JSON result breaking changes detected
pacto diff --output-format json oci://…/absent:1.0.0 NEW 1 empty old contract: artifact not found: …

So the rule for a script is: branch on stdout when it is non-empty, and treat an empty stdout with a non-zero exit as a tool failure rather than a verdict.

JSON key casing is not uniform

pacto validate emits Path, Valid and Errors in PascalCase; every other command emits camelCase (oldPath, classification). One parser will not read both without allowing for it.


OCI version resolution

All commands that accept oci:// references support automatic version resolution. When a reference omits the tag (e.g. oci://ghcr.io/acme/svc-pacto instead of oci://ghcr.io/acme/svc-pacto:1.0.0), pacto queries the registry for available tags and selects the highest semver version.

For dependency references declared with a compatibility constraint, only tags satisfying the constraint are considered. For example, a dependency with compatibility: "^2.0.0" and available tags 1.0.0, 2.0.0, 2.3.0, 3.0.0 resolves to 2.3.0.

Non-semver tags (e.g. latest, main) are ignored during resolution. Digest-pinned references (@sha256:...) and explicitly tagged references are used as-is.

Constraints apply to the CLI's dependency graph, not dashboard discovery

compatibility constraints are applied by the CLI when resolving a contract's declared dependencies (e.g. pacto graph). The dashboard's version discovery selects the highest semver tag and does not apply per-dependency compatibility constraints. Root-contract pulls (a tagless top-level oci:// ref) also select the highest semver tag with no constraint.


pacto completion

Generate the autocompletion script for pacto for the specified shell. See each sub-command's help for details on how to use the generated script.

pacto completion [flags]

Flags:

  -h, --help   help for completion

pacto dashboard

Launches an operational dashboard that aggregates data from all available sources (local filesystem, Kubernetes, OCI registries).

The dashboard is the exploration and observability layer of the Pacto system. It visualizes the same contracts the CLI manages and the operator verifies, organised around four workflows: an operational Overview, the Services inventory, the Operational Graph, and Change analysis.

Each positional argument is a pacto source reference: - oci://registry/repo → OCI registry source (can be repeated) - ./path/to/dir → local filesystem source (at most one)

When no arguments are given, sources are auto-detected: - local: enabled if pacto.yaml is found in the working directory - k8s: enabled if a valid kubeconfig is found and the cluster is reachable - oci: auto-discovered from K8s status.contract.resolvedRef, or via PACTO_DASHBOARD_REPO env var

Materialized bundles on disk (~/.cache/pacto/oci) are used internally by the OCI source to enrich version data (hash, classification, timestamps) without appearing as a separate source. The --no-cache flag skips pre-existing cache at startup but still allows same-session materialization (e.g. fetch-all-versions).

When running alongside the Kubernetes operator, OCI repositories are automatically discovered from the status.contract.resolvedRef fields of Pacto CRD resources. This provides full contract bundles, version history, interfaces, and diffs — without needing explicit OCI arguments. The result is a hybrid view: runtime truth from the operator combined with contract truth from OCI.

Services are grouped by name across sources and merged using priority rules: - Kubernetes for runtime state (contract status, checks, endpoints) - OCI for contract content and version history - Local for in-progress contract changes

pacto dashboard [sources...] [flags]

Examples:

  # Start dashboard with auto-detected sources
  pacto dashboard

  # Start from a specific directory
  pacto dashboard ./services

  # Include OCI repositories
  pacto dashboard oci://ghcr.io/org/order-service oci://ghcr.io/org/payment-service

  # Mix local and OCI sources
  pacto dashboard ./services oci://ghcr.io/org/payment-service

  # Custom port
  pacto dashboard --port 9090

  # Specify Kubernetes namespace (default: all namespaces)
  pacto dashboard --namespace production

Flags:

      --cors-origin string         explicit cross-origin allowed to call the API (default: same-origin only)
      --diagnostics                enable source diagnostics panel in the dashboard UI
  -h, --help                       help for dashboard
      --host string                bind address for the dashboard server (default "127.0.0.1")
      --namespace string           Kubernetes namespace (empty = all namespaces)
      --port int                   port for the dashboard server (default 3000)
      --trace-source stringArray   named offline OTLP/JSON trace source as NAME=PATH, where NAME is its stable data-source identity (repeatable; also PACTO_DASHBOARD_TRACE_SOURCES)
      --traces stringArray         OTLP/JSON trace file to fold observed dependencies from (repeatable; also PACTO_DASHBOARD_TRACES)

It auto-detects sources: pass OCI repositories as arguments, or run it next to the operator (with a kubeconfig) and it discovers OCI repositories from each Pacto resource's status.contract.resolvedRef. Use --no-cache for a cold start (it skips scanning pre-existing cached bundles; bundles fetched during the session are still cached), and --diagnostics to expose the /api/debug/* endpoints.

For the source model, contract-first merge priority (local > oci > cache) and version-tracking design, see Dashboard architecture. For a tour of what the dashboard surfaces, see For platform engineers; to run it as a container, see Dashboard container.


pacto diff

Compares two contracts (local paths or oci:// references) and produces a classified change set (BREAKING, POTENTIAL_BREAKING, NON_BREAKING).

pacto diff <old> <new> [flags]

Examples:

  # Compare a remote contract with a local one
  pacto diff oci://ghcr.io/acme/svc-pacto:1.0.0 my-service

  # Markdown output for CI comments
  pacto diff --output-format markdown oci://ghcr.io/acme/svc-pacto:1.0.0 my-service

Flags:

  -h, --help                     help for diff
      --new-set stringArray      set a value on the new contract (e.g. --new-set service.version=2.0.0)
      --new-values stringArray   values file to merge into the new contract (can be repeated)
      --old-set stringArray      set a value on the old contract (e.g. --old-set service.version=1.0.0)
      --old-values stringArray   values file to merge into the old contract (can be repeated)

Exit code: 1 when the overall classification is BREAKING — and also 1 when the diff could not be produced at all, so a non-zero exit is not by itself a contract verdict. See Exit codes for how to tell the two apart. A POTENTIAL_BREAKING result exits 0, so a CI gate that wants to stop on it has to read the classification rather than the exit code.

The diff engine performs deep comparison of referenced OpenAPI specs, detecting changes at the path, method, parameter, request body, and response level. The optional docs/ directory is ignored entirely — documentation changes never produce diff entries or affect compatibility classification.

When both bundles include an sbom/ directory with recognized SBOM files (.spdx.json or .cdx.json), pacto diff reports package-level changes — added, removed, or modified packages (version and license). SBOM changes are informational and do not affect the overall classification or exit code.

When dependencies change between the old and new contracts (version upgrades, additions, or removals), a dependency graph diff section is displayed showing the tree of affected nodes.

See Change Classification for the full rules.


pacto doc

Reads a pacto.yaml in the given directory (or oci:// reference) and generates structured Markdown documentation.

pacto doc [dir | oci://ref] [flags]

Examples:

  # Print documentation to stdout
  pacto doc my-service

  # Write documentation to a file
  pacto doc my-service -o docs/

  # Serve documentation in the browser
  pacto doc my-service --serve

  # Serve on a custom port
  pacto doc my-service --serve --port 9090

  # Launch an interactive API explorer (Scalar UI)
  pacto doc my-service --ui swagger

  # Select a specific interface
  pacto doc my-service --ui swagger --interface public-api

  # Point try-it-out requests to a running backend
  pacto doc my-service --ui swagger --target http://localhost:3000

  # Per-interface target mapping
  pacto doc my-service --ui swagger --target public-api=http://localhost:3000 --target admin-api=http://localhost:3001

Flags:

  -h, --help                 help for doc
      --interface string     interface name to display (used with --ui)
  -o, --output string        output directory for generated Markdown; a NAME.html value writes a static documentation site to a NAME/ directory instead
      --port int             port for the documentation server (used with --serve or --ui) (default 8484)
      --serve                serve the offline dashboard-grade documentation site over a local HTTP server
      --set stringArray      set a contract value (e.g. --set service.version=2.0.0)
      --target stringArray   target server URL for try-it-out requests; supports interface=url mapping (used with --ui)
      --ui string            UI type for interactive API explorer (e.g. swagger)
  -f, --values stringArray   values file to merge into the contract (can be repeated; last wins)

The header line reports the contract's own state, not a runtime measurement: pacto doc reads a bundle and never observes a cluster. A contract that has never been runtime-evaluated therefore reads status NotEvaluated, and one that declares no workload reads compliance REFERENCE. Both are the expected result for a freshly scaffolded contract — see Compliance states.

Markdown prints to stdout by default. -o DIR writes DIR/<service>.md. -o NAME.html writes a self-contained static documentation site (a directory) that reuses the dashboard UI offline.

--serve serves that static site locally. --ui swagger launches an interactive API explorer.

--serve, --ui and -o are mutually exclusive. Use --interface to pick one OpenAPI interface with --ui. --target and --target iface=url point try-it-out at a backend.

Sibling dependencies are resolved in parallel. OCI bundles cache under ~/.cache/pacto/oci/. --no-cache bypasses the cache.


pacto evidence

Produce and verify the signed, versioned envelopes that carry a Pacto EvidenceSet from a remote or disconnected environment to a platform that ingests it. Keys are Ed25519; the wire format is defined by pkg/evidenceenvelope.

pacto evidence [flags]

Flags:

  -h, --help   help for evidence

pacto evidence keygen

Writes the private seed to <keyId>.key (base64, 0600) and the public key into --out. With --producer, the public key is written as <producer>__<keyId>.pub, which binds the key to that producer in the trust store — hand that file to the platform. Sign with the SAME --producer and --key-id. With no --producer, a bare <keyId>.pub binds the key to a producer named after the key id (the single-producer default).

pacto evidence keygen [flags]

Flags:

      --force             overwrite existing key files instead of failing
  -h, --help              help for keygen
      --key-id string     key id (defaults to a fingerprint of the public key)
      --out string        directory to write the keypair into (default ".")
      --producer string   producer id to bind the key to (writes <producer>__<keyId>.pub)

pacto evidence send

Reads a signed envelope JSON file and POSTs it to an ingestion host's --url. Prints the host's JSON response and exits non-zero on a non-2xx status.

pacto evidence send <envelope.json> [flags]

Flags:

  -h, --help         help for send
      --url string   ingestion host envelope endpoint URL

pacto evidence serve

Starts an HTTP host that accepts signed evidence envelopes at POST /api/evidence/v1/envelopes, verifies them against --trust, evaluates the carried evidence against its resolved contract and publishes accepted records to the contract registry as OCI 1.1 referrers of the exact contract revision each report is about. Every --subject is an immutable oci://<repo>@sha256:<digest> reference; the registry is the only durable store, so the host keeps no local state and survives restarts. GET .../health is an always-200 liveness probe; .../ready reports 503 while a subject cannot be resolved or its referrers enumerated; .../producers advertises trusted producer ids; .../targets exposes the latest accepted targets. Registry credentials come from the same sources as pacto pull. Exactly one server may write to a subject set. Serves until interrupted.

pacto evidence serve [flags]

Flags:

  -h, --help                    help for serve
      --listen-address string   host:port to listen on (supersedes --port)
      --port int                port to listen on (127.0.0.1); superseded by --listen-address (default 8686)
      --producer stringArray    advertised trusted producer id (repeatable)
      --subject stringArray     exact contract revision evidence is stored on: oci://<repo>@sha256:<digest> (repeatable, required)
      --trust string            trust store: a public-key file or a directory of <keyId>.pub files

pacto evidence sign

Reads an EvidenceSet JSON file, wraps it in an Ed25519-signed envelope and prints the envelope JSON. Only --issued-at is non-deterministic (it defaults to now), so pinning it is enough to make re-signing the same evidence produce a byte-identical envelope.

pacto evidence sign <evidence.json> [flags]

Flags:

  -h, --help                      help for sign
      --id string                 envelope id (defaults to a hash over the API version, producer id, sequence and evidence, so two producers reporting identical evidence never collide)
      --issued-at string          issued-at timestamp (RFC3339; defaults to now)
      --key string                path to the private key file
      --key-id string             producer key id (must match the trust-store entry)
      --producer string           producer id
      --producer-version string   producer version (optional)
      --sequence uint             producer-scoped monotonic sequence; each report must be strictly greater than the producer's last
      --ttl duration              validity window; 0 disables expiry (default 24h0m0s)

pacto evidence verify

Decodes an envelope and verifies its signature, freshness and trust against a --trust public-key file or directory of <keyId>.pub files. Exits non-zero when verification fails.

pacto evidence verify <envelope.json> [flags]

Flags:

  -h, --help           help for verify
      --trust string   trust store: a public-key file or a directory of <keyId>.pub files

pacto explain

Parses a pacto.yaml in the given directory (or oci:// reference) and produces a human-readable summary of the service contract.

pacto explain [dir | oci://ref] [flags]

Examples:

  pacto explain my-service

Flags:

  -h, --help                 help for explain
      --set stringArray      set a contract value (e.g. --set service.version=2.0.0)
  -f, --values stringArray   values file to merge into the contract (can be repeated; last wins)

What it covers. The text output summarises identity, workload, state, capabilities, interfaces, dependencies and readiness. It does not render configurations or policies — read those with pacto doc, or from pacto.yaml directly. metadata is carried by --output-format json only; the text output omits it.

Readiness output. When the contract declares a readiness section (a pactoVersion: "2.0" feature), explain adds a Readiness block: the derived Score, the Gate result (PASS/FAIL with score / minScore), Earned and Total Weight, the partial credit multiplier, the assessment expires date with countdown (or an Expired state), and a per-check table showing each check's declared status (done/partial/not-done/deferred), category, weight, earned weight, and evidence. The Readiness block also includes a revision-history table when history[] is present. --output-format json includes the same data plus doneCount, partialCount, notDoneCount, deferredCount, and expired (boolean). Readiness status is time-dependent — the score is 0 when the current date is past the assessment-level expires.


pacto fleet

Compose contracts, contract revisions and operational targets from local bundles and ingested evidence into a versioned, navigable graph, then search, inspect, traverse and explain it. Every answer reports its as-of time and completeness.

pacto fleet [flags]

Flags:

      --cache                      include every bundle in the local OCI cache as an offline baseline revision
      --evidence-url stringArray   base URL of an Evidence Server to consume its read-only operational-graph contribution over HTTP (repeatable)
      --freshness duration         mark target evidence older than this as stale (0 disables)
  -h, --help                       help for fleet
      --k8s                        include live Pacto CRs from the current Kubernetes cluster as targets
      --local stringArray          local bundle root(s) to scan (repeatable) (default [.])
      --namespace string           namespace to read Pacto CRs from with --k8s (empty = all namespaces)
      --oci stringArray            registry reference to include as a published-baseline revision (repeatable)
      --target-state stringArray   offline target-state fixture file(s) supplying targets — a demo/test adapter, not the signed EvidenceSet protocol (repeatable)
      --traces stringArray         OTLP/JSON trace file supplying runtime-observed dependency edges, folded into the snapshot as observed relationships (repeatable)

pacto fleet explain

Explain the deterministic reasons for a service or target state

pacto fleet explain <subject> [flags]

Flags:

  -h, --help   help for explain

pacto fleet get

Inspect a logical service or an operational target

pacto fleet get [service] [flags]

Flags:

  -h, --help            help for get
      --target string   inspect an operational target by key or name

pacto fleet graph

Traverse the operational graph from an explicit root. Give a service name to aggregate across its revisions, or --revision/--target to root an exact revision (never 'latest').

pacto fleet graph <service> [flags]

Flags:

      --direction string   traversal direction (dependencies, dependents) (default "dependencies")
  -h, --help               help for graph
      --max-depth int      maximum transitive depth (0 = unlimited)
      --revision string    root an exact contract revision key
      --target string      root the revision linked to this target key or name
      --transitive         traverse transitively (cycle-safe)

pacto fleet reconcile

Reconciles what the fleet's contracts declare against what runtime traces prove. Reports matched dependencies, declared-but-not-observed (dormant or unseen — not proof of a dead dependency) and observed-but-not-declared (shadow dependencies).

pacto fleet reconcile [flags]

Examples:

  pacto fleet reconcile --traces traces.json --local .

Flags:

  -h, --help            help for reconcile
      --traces string   OTLP/JSON trace file supplying observed dependencies (required)

Search logical services in the fleet

pacto fleet search [text] [flags]

Flags:

      --compliance string   filter to services with a target of this compliance
      --has-capability      only services declaring a capability
      --has-dependency      only services declaring a dependency
  -h, --help                help for search
      --label stringArray   filter by label key=value (repeatable)
      --limit int           maximum results (0 = 100, capped at 500)
      --not-ready           only services whose readiness gate does not pass (below minScore, expired or undeclared)
      --offset int          result offset for paging
      --owner string        filter by owner (team, DRI or contact)
      --ready               only services whose readiness gate passes (score >= minScore, not expired)
      --scope string        correlate to a target with this scope
      --source string       filter by observing source
      --status string       filter by aggregate status (Compliant, Invalid, NonCompliant, NotEvaluated, Reference, Unknown, Warning)
      --workload string     filter by workload (service, job, scheduled)

pacto fleet snapshot

Emit the whole fleet snapshot

pacto fleet snapshot [flags]

Flags:

  -h, --help   help for snapshot

pacto fleet status

Report services and targets needing attention

pacto fleet status [flags]

Flags:

  -h, --help                help for status
      --invalid             report structurally invalid contracts
      --limit int           maximum results (0 = 200)
      --missing-readiness   report revisions without a readiness assessment
      --needs-attention     report every attention category
      --non-compliant       report non-compliant targets
      --stale               report targets with stale evidence
      --unknown             report targets with unknown compliance
      --unresolved-deps     report unresolved declared dependencies

pacto generate

Invokes a pacto-plugin-<name> binary to generate deployment manifests, documentation, or other artifacts from a contract directory or oci:// reference.

pacto generate <plugin> [dir | oci://ref] [flags]

Examples:

  pacto generate schema-infer my-service --option file=config.yaml -o out/

Flags:

  -h, --help                 help for generate
      --option stringArray   plugin option as key=value (can be repeated)
  -o, --output string        output directory (default: <plugin>-output/)
      --set stringArray      set a contract value (e.g. --set service.version=2.0.0)
  -f, --values stringArray   values file to merge into the contract (can be repeated; last wins)

pacto generate <plugin> invokes the pacto-plugin-<plugin> binary. See Plugins for plugin discovery, the plugin registry, and the official plugins bundled with Pacto.


pacto graph

Resolves the dependency tree from a pacto.yaml in the given directory (or oci:// reference) and displays the graph, cycles, and version conflicts.

pacto graph [dir | oci://ref] [flags]

Examples:

  pacto graph my-service
  pacto graph --with-references
  pacto graph --only-references

Flags:

  -h, --help                 help for graph
      --only-references      Show only config/policy reference edges (no dependencies)
      --set stringArray      set a contract value (e.g. --set service.version=2.0.0)
  -f, --values stringArray   values file to merge into the contract (can be repeated; last wins)
      --with-references      Include config/policy reference edges alongside dependencies

Dependencies resolved from local paths are annotated with [local]. Shared dependencies (referenced by multiple parents) are annotated with (shared).

Reports cycles, version conflicts, and unreachable dependencies.

Sibling dependencies are resolved in parallel. OCI bundles are cached locally in ~/.cache/pacto/oci/ for faster subsequent operations. Use --no-cache to bypass the cache.


pacto impact

Composes a semantic contract diff (old→new) with the operational graph to answer what a change's real blast radius is: which consumers are affected, how strong the evidence is and whether their declared compatibility still holds.

Exit status is non-zero when the change is BREAKING and at least one ACTIVE consumer is incompatible with the new version (mirrors pacto diff). Active means the snapshot knows of somewhere that consumer is deployed — at least one operational target. A consumer that is incompatible on paper but is running nowhere the snapshot can see does not fail the command, so a declared-only run over --local bundles alone exits 0 no matter how incompatible it says the consumers are. The Active targets line in the output is the tell: no line, no non-zero exit. Supply targets with --target-state (or query a live fleet with pacto fleet) to make the exit code mean something.

pacto impact <old> <new> [flags]

Examples:

  # Impact of upgrading a local service against the local fleet
  pacto impact ./svc-v1 ./svc-v2 --local .

  # Include observed (runtime) evidence and emit JSON
  pacto impact oci://ghcr.io/acme/svc:1.0.0 ./svc --include-observed --output-format json

Flags:

      --freshness duration         mark target evidence older than this as stale (0 disables)
  -h, --help                       help for impact
      --include-observed           let observed (runtime) relationships raise consumer confidence
      --local stringArray          local bundle root(s) to scan (repeatable) (default [.])
      --new-set stringArray        set a value on the new contract (e.g. --new-set service.version=2.0.0)
      --new-values stringArray     values file to merge into the new contract (can be repeated)
      --old-set stringArray        set a value on the old contract (e.g. --old-set service.version=1.0.0)
      --old-values stringArray     values file to merge into the old contract (can be repeated)
      --target-state stringArray   offline target-state fixture file(s) supplying targets (repeatable)
      --traces string              OTLP/JSON trace file; its observed edges corroborate and surface consumers (implies --include-observed)

pacto init

Creates a new directory with pacto.yaml and the bundle directory structure (interfaces/, configuration/).

pacto init <name> [flags]

Examples:

  pacto init my-service

Flags:

  -h, --help   help for init

Scaffolds three files: a valid pacto.yaml, a placeholder OpenAPI spec at interfaces/openapi.yaml, and a configuration JSON Schema at configuration/schema.json.

<name> is the service name, not a path: it becomes the directory and service.name, which must match ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$. pacto init fleet/checkout-web therefore scaffolds a bundle that does not validate — service.name gets the whole path and fails SCHEMA_VIOLATION. To scaffold inside a directory, cd there first and pass the bare name.

All three are required by the scaffolded contract, because its interfaces: and configurations: sections point at the other two files. Deleting a directory without also deleting the section that references it fails validation with FILE_NOT_FOUND. A contract that declares neither section needs only pacto.yaml, so drop the section and the directory together.

The scaffold does not pass validate --readiness, by design

Its two placeholder readiness claims are not-done, which scores 0 against the scaffolded minScore: 80 and fails with READINESS_GATE_UNMET. Plain pacto validate passes, because the gate is opt-in. Fill the claims in as the work lands — the placeholder is the starting position of a real assessment, not a template to delete.


pacto lock

Resolves the full transitive dependency and reference closure and writes a committed pacto.lock pinning each to its OCI digest. With --check, verifies the existing lock without writing.

pacto lock [dir] [flags]

Examples:

  pacto lock
  pacto lock --update
  pacto lock --update-name auth
  pacto lock --check

Flags:

      --check                     verify pacto.lock is up to date without writing (non-zero exit on drift)
  -h, --help                      help for lock
      --set stringArray           set a contract value (e.g. --set service.version=2.0.0)
      --update                    re-resolve dependencies to the newest version within their constraint
      --update-name stringArray   re-resolve only the named dependency, preserving all other pins (repeatable)
  -f, --values stringArray        values file to merge into the contract (can be repeated; last wins)

See Lockfile for the lock model, drift enforcement, and how .pactoignore keeps a pacto.lock out of a pushed bundle.


pacto login

Stores credentials for an OCI registry in ~/.config/pacto/config.json.

pacto login <registry> [flags]

Examples:

  pacto login ghcr.io -u my-username

Flags:

  -h, --help              help for login
  -p, --password string   registry password
  -u, --username string   registry username

Credentials are stored in ~/.config/pacto/config.json (or $XDG_CONFIG_HOME/pacto/config.json), keeping them separate from Docker's configuration.

GitHub Container Registry (ghcr.io)

For GitHub registries (ghcr.io and docker.pkg.github.com), pacto can automatically reuse credentials from the GitHub CLI — no pacto login required.

If you already have gh installed and authenticated, pacto will use gh auth token to obtain a token transparently. To verify your setup:

# Check if gh is authenticated
gh auth status

# Verify the token is available
gh auth token

To push container images or packages, your token needs the write:packages scope. If you authenticated gh without it, refresh your scopes:

gh auth refresh --scopes write:packages

After this, pacto push oci://ghcr.io/... will work without any additional login step.

If gh is not installed or not authenticated, pacto silently falls back to the next credential source in the chain.


pacto logout

Removes credentials for an OCI registry from ~/.config/pacto/config.json.

pacto logout <registry> [flags]

Examples:

  pacto logout ghcr.io

Flags:

  -h, --help   help for logout

pacto mcp

Starts a Model Context Protocol (MCP) server exposing Pacto tools for AI agents. Supports stdio (default) and HTTP transports.

When a bundle reference (local directory or oci:// ref) is given, the server also exposes one executable tool per OpenAPI operation in the bundle's openapi interfaces, plus a pacto_skill tool for any skills/*.md domain knowledge. Read-only (GET/HEAD) operations are exposed by default; pass --allow-writes to expose mutating operations.

With --root, the server instead exposes a read-only contract catalog: the given roots plus their dependency closure, resolved once at startup and then frozen, so a registry tag that moves later does not change the session. Roots that do not resolve stay visible as partial knowledge. Discovery is not authorization and nothing in the catalog executes.

A bundle reference, --root and --fleet select different servers and cannot be combined.

pacto mcp [bundle-ref] [flags]

Examples:

  # Start MCP server over stdio (default)
  pacto mcp

  # Start MCP server over HTTP
  pacto mcp -t http

  # Expose a bundle's OpenAPI operations as agent tools
  pacto mcp ./my-service --base-url https://api.example.com

  # Include mutating operations and an auth credential
  pacto mcp oci://ghcr.io/acme/svc:1.0.0 --base-url https://api.example.com \
    --auth bearerAuth=$TOKEN --allow-writes

  # Expose a contract catalog discovered from explicit roots
  pacto mcp --root oci://ghcr.io/acme/platform:1.4.0 --root ./experimental-platform

Flags:

      --allow-writes               expose mutating operations (POST/PUT/PATCH/DELETE) as tools
      --auth stringArray           credential for a security scheme as name=value (repeatable)
      --base-url string            base URL for live invocation (overrides the OpenAPI servers[] URL)
      --cache                      include the local OCI cache as offline baseline revisions (--fleet)
      --evidence-url stringArray   base URL of an Evidence Server to consume over HTTP for --fleet (repeatable)
      --fleet                      expose read-only operational-graph (fleet) query tools
      --freshness duration         mark target evidence older than this as stale (--fleet)
  -h, --help                       help for mcp
      --k8s                        include live Pacto CRs from the current Kubernetes cluster (--fleet)
      --local stringArray          local bundle root(s) for --fleet (repeatable) (default [.])
      --namespace string           namespace for --k8s (empty = all namespaces)
      --oci stringArray            registry reference to include as a published-baseline revision for --fleet (repeatable)
      --port int                   port for HTTP transport (default 8585)
      --root stringArray           contract root to discover a read-only catalog from: a local bundle path or an oci:// reference (repeatable)
      --target-state stringArray   offline target-state fixture file(s) for --fleet — a demo/test adapter (repeatable)
  -t, --transport string           transport type: stdio or http (default "stdio")

The default server exposes the four authoring tools below. Three flags select a different server, each with its own tools -- see Server modes immediately after this table:

Tool Description
pacto_create Create a new contract from intent-level inputs (name, description, interfaces, runtime semantics). Supports dry run.
pacto_edit Edit an existing contract — add/remove interfaces and dependencies, change runtime, update metadata. Supports dry run.
pacto_check Validate a contract and return errors, warnings, and actionable improvement suggestions.
pacto_schema Return the Pacto format explanation and full JSON Schema reference.

These four authoring tools operate on local contract directories (they read and write pacto.yaml on disk) and do not resolve oci:// refs.

Server modes

The default server exposes the authoring tools above. Three flags select a different server instead, and they cannot be combined — passing more than one is an error, never a silent choice:

Invocation Server
pacto mcp Authoring tools.
pacto mcp <bundle-ref> Authoring tools plus the bundle's OpenAPI operations as executable agent tools, alongside a pacto_skill tool for any bundled skills.
pacto mcp --fleet Authoring tools plus read-only operational-graph query tools.
pacto mcp --root <ref> [--root <ref>] A read-only contract catalog discovered from the named roots, and nothing else: catalog mode registers no authoring tools, so nothing reachable in it writes to disk.

--root is repeatable and takes a local bundle directory or an oci:// reference. The roots and their dependency closure are resolved once, at startup, through the same reference parsing, credentials and cache the rest of the CLI uses; after that the session is frozen, so a tag that moves in a registry does not change any answer. Roots that do not resolve stay visible with a classified reason and the catalog reports itself as partial. Nothing is crawled, nothing is refreshed and nothing is persisted.

See MCP Integration for detailed setup with Claude and other AI tools, Agent capabilities for serving a bundle's operations as tools, and Contract catalog discovery for the catalog surface.


pacto otel

Observe runtime dependencies from OpenTelemetry traces

pacto otel [flags]

Flags:

  -h, --help   help for otel

pacto otel observe

Reads an OTLP/JSON trace export and derives the service dependency edges its outbound spans prove. By default it prints the observed edges as text; add --output-format json for machine-readable output. With --evidence it emits one EvidenceSet per calling service -- a JSON array, and each set's ContractRef is empty because traces do not name a contract revision. Signing is therefore not a pipe: pacto evidence sign reads one EvidenceSet from a file, so write the array out, split it, and set each ContractRef to the revision it describes before signing (pacto evidence sign) and reporting (pacto evidence send).

pacto otel observe <traces.json> [flags]

Examples:

  pacto otel observe traces.json
  pacto otel observe traces.json --evidence --output-format json > sets.json

Flags:

      --evidence        emit signable EvidenceSets instead of raw edges
  -h, --help            help for observe
      --source string   collector/source name recorded as provenance (default "otel")

pacto pack

Validates the contract in the given directory and creates a tar.gz archive of the bundle, ready for distribution.

pacto pack [dir] [flags]

Examples:

  pacto pack my-service

Flags:

  -h, --help                 help for pack
  -o, --output string        output file path (default: <name>-<version>.tar.gz)
      --set stringArray      set a contract value (e.g. --set service.version=2.0.0)
  -f, --values stringArray   values file to merge into the contract (can be repeated; last wins)

The contract is validated before packing. If validation fails, no archive is created.

Files matched by .pactoignore are excluded from the archive — see Packaging ignore.


pacto pull

Pulls a contract bundle from the specified OCI reference and extracts it to a local directory.

pacto pull <ref> [flags]

Examples:

  # Pull a specific version
  pacto pull oci://ghcr.io/acme/my-service-pacto:1.0.0

  # Pull the latest available version
  pacto pull oci://ghcr.io/acme/my-service-pacto

Flags:

  -h, --help            help for pull
  -o, --output string   output directory (default: service name)

pacto push

Validates the contract (including remote policy and config refs), builds an OCI artifact, and pushes it to the specified registry reference.

pacto push <ref> [flags]

Examples:

  # Push with auto-tag (uses contract version)
  pacto push oci://ghcr.io/acme/my-service-pacto -p my-service

  # Push with explicit tag
  pacto push oci://ghcr.io/acme/my-service-pacto:latest -p my-service

  # Force overwrite an existing artifact
  pacto push oci://ghcr.io/acme/my-service-pacto -p my-service --force

Flags:

  -f, --force                overwrite existing artifact in registry
  -h, --help                 help for push
  -p, --path string          path to contract directory (default: current directory)
      --set stringArray      set a contract value (e.g. --set service.version=2.0.0)
      --values stringArray   values file to merge into the contract (can be repeated; last wins)

If the artifact already exists in the registry, pacto push prints a warning and exits successfully without pushing. Use --force to overwrite.

--values has no -f shorthand on push

On every other override-taking command -f is the shorthand for --values. On pacto push, -f is --force, so --values must be spelled out in full here.


pacto update

Downloads and installs the specified version of pacto. If no version is given, updates to the latest release.

pacto update [version] [flags]

Examples:

  # Update to the latest release
  pacto update

  # Update to a specific version
  pacto update v1.1.0

Flags:

  -h, --help   help for update

Note

pacto update is not available on dev builds. If you built from source without version injection, install a release build first.

Update notifications

When a newer version is available, pacto displays a notification after any command:

A new version of pacto is available: v1.0.0 -> v1.2.0
Run 'pacto update' to update.

The check runs asynchronously and adds no latency. Results are cached for 24 hours in ~/.config/pacto/update-check.json.

Notifications are suppressed when:

  • Running a dev build
  • Using --output-format json or --output-format markdown (the notice shows only for text output)
  • The PACTO_NO_UPDATE_CHECK=1 environment variable is set

pacto validate

Validates a pacto.yaml in the given directory (or oci:// reference) against the specification, running the three validation layers: structural, cross-field, and policy.

pacto validate [dir | oci://ref] [flags]

Examples:

  # Validate a local contract
  pacto validate my-service

  # Validate from current directory
  pacto validate

  # Validate from an OCI registry
  pacto validate oci://ghcr.io/acme/my-service-pacto:1.0.0

  # JSON output
  pacto validate --output-format json my-service

  # Also enforce the readiness gate (fail if score < minScore)
  pacto validate --readiness my-service

Flags:

  -h, --help                 help for validate
      --readiness            also enforce the readiness gate: fail if the derived readiness score is below the declared (or default 100) minScore. Opt-in because gate evaluation is time-dependent (check expiry is compared against the run time), which would otherwise make plain validation non-deterministic
      --set stringArray      set a contract value (e.g. --set service.version=2.0.0)
  -f, --values stringArray   values file to merge into the contract (can be repeated; last wins)

The --readiness gate is opt-in because it is time-dependent: it compares the assessment's single readiness.expires date against the run time, which would make plain validate non-deterministic. Expiry is declared once for the whole assessment — individual claims carry no expires field, and adding one fails to load with PARSE_ERROR. Without the flag, validation only checks the contract's structure and rules (readiness checks are still validated for shape, but the freshness gate is not enforced). See the readiness reference for the score and gate semantics.

Exit code: Non-zero if validation fails.


pacto version

Prints the current pacto version.

pacto version [flags]

Examples:

  pacto version

Flags:

  -h, --help   help for version

Environment variables

Boolean variables are parsed the way Go parses a boolean: 1, t, T, true, TRUE and True enable them. Anything else — including yes and on — reads as off, silently. The two exceptions are called out in the table.

Variable Description
PACTO_CACHE_DIR Cache directory for the pacto dashboard bundle scan. The core CLI cache location is controlled by XDG_CACHE_HOME (see below).
PACTO_NO_CACHE Boolean. Disable OCI bundle caching (equivalent to --no-cache)
PACTO_NO_ANIM Any non-empty value disables spinners and animations (equivalent to --no-anim). PACTO_NO_ANIM=0 also disables them.
PACTO_NO_UPDATE_CHECK Exactly 1 disables automatic update checks. No other value has any effect.
PACTO_REGISTRY_USERNAME Registry username for authentication
PACTO_REGISTRY_PASSWORD Registry password for authentication
PACTO_REGISTRY_TOKEN Registry token for authentication
PACTO_INSECURE_REGISTRIES Comma-separated registry hosts the Evidence Server may reach over plain HTTP instead of HTTPS. Scoped per host, so HTTPS registries are unaffected, and scoped to the evidence commands — pacto push and pacto pull do not read it. Loopback hosts are already plain HTTP without being listed. Intended for a controlled in-cluster registry, never the public internet: it disables transport encryption, so credentials and payloads travel in the clear.
PACTO_EVIDENCE_SOURCE_URL Base URL of an Evidence Server whose read-only operational-graph contribution pacto dashboard should consume. Set by the operator when it wires a managed Evidence Server; unset means no evidence source configured, which is not the same as an unavailable one.
XDG_CONFIG_HOME Override config directory (default: ~/.config). Affects pacto login credentials and update check cache
XDG_CACHE_HOME Override cache directory (default: ~/.cache). Affects OCI bundle cache location

Dashboard environment variables

The following variables configure the dashboard when set (see also Dashboard Container). Each mirrors the flag named beside it: an explicitly passed flag wins, and otherwise the variable overrides that flag's default.

Variable Flag Description
PACTO_DASHBOARD_REPO (positional args) Comma-separated OCI repositories, used only when no positional oci:// argument is given
PACTO_DASHBOARD_HOST --host Bind address (default: 127.0.0.1)
PACTO_DASHBOARD_PORT --port HTTP port (default: 3000)
PACTO_DASHBOARD_NAMESPACE --namespace Kubernetes namespace filter (empty = all)
PACTO_DASHBOARD_DIAGNOSTICS --diagnostics Boolean. Expose the /api/debug/* endpoints and the source diagnostics panel
PACTO_DASHBOARD_CORS_ORIGIN --cors-origin One explicit origin allowed to call the API. Unset means same-origin only.
PACTO_DASHBOARD_TRACES --traces OTLP/JSON trace files to fold observed dependencies from
PACTO_DASHBOARD_TRACE_SOURCES --trace-source Named offline trace sources as NAME=PATH

The two list variables split on whitespace, not commas

PACTO_DASHBOARD_TRACES and PACTO_DASHBOARD_TRACE_SOURCES go through the same generic flag binding as every other dashboard variable, which splits a multi-valued string on spaces. PACTO_DASHBOARD_TRACES="a.json b.json" supplies two files; PACTO_DASHBOARD_TRACES=a.json,b.json supplies one, named a.json,b.json. PACTO_DASHBOARD_REPO is the odd one out — it is read directly and does split on commas.

Neither mistake stops the dashboard: a trace file it cannot read is skipped and the server still starts, so the symptom is missing observed dependencies rather than an error. Check the snapshot's reported limitations if the operational graph looks emptier than you expect.


Authentication

Pacto follows this credential resolution chain:

  1. Environment variables (PACTO_REGISTRY_TOKEN, or PACTO_REGISTRY_USERNAME + PACTO_REGISTRY_PASSWORD)
  2. Pacto config (~/.config/pacto/config.json, written by pacto login — where --username / --password are persisted)
  3. GitHub CLI (gh auth token, for ghcr.io and docker.pkg.github.com only)
  4. Docker config (~/.docker/config.json) and credential helpers (including cloud-registry helpers for ECR, GCR and ACR)
  5. Anonymous fallback

For GitHub registries, step 3 means you can skip pacto login entirely if you have gh authenticated with the write:packages scope (see pacto login above).

No credentials are ever stored in contract files.