Skip to main content
Docs navigation

Pack reference

An action pack is a versioned, content-addressed directory of YAML action declarations. The runner loads the pack at boot, advertises every action to the control plane, and refuses anything not in this catalog. This is the contract between your ops team and the LLM.

Layout#

my-pack/
  pack.yaml              # pack-level metadata
  actions/
    nodetool_status.yaml   # one declared action per file
    nodetool_repair.yaml

pack.yaml#

yaml
schema_version: 1
id: cassandra
name: Cassandra operations
version: 0.4.0
description: Cassandra triage + scoped repair
vendor: acme
homepage: https://github.com/acme/cassandra-pack
allow_symlinks: false
actions:
  - actions/nodetool_status.yaml
  - actions/nodetool_repair.yaml

allow_symlinks defaults to false: the loader rejects symlinked action YAMLs and scripts unless you opt in.

An action YAML#

yaml
schema_version: 1
id: linux.grep_log
title: Grep a log file
kind: exec
risk: low

description: >
  Greps an extended regex against a log file under /var/log.
  Read-only. Returns matching lines with line numbers.
side_effects:
  - Reads a log file under /var/log.

args:
  - name: file
    type: path
    required: true
    validation:
      allowed_prefixes: ["/var/log/"]
  - name: pattern
    type: string
    required: true
    validation:
      pattern: "^.{1,512}$"

execution:
  command:
    binary: grep        # bare name — resolved via PATH on the host
    argv: ["-E", "-n", "{{ args.pattern }}", "{{ args.file }}"]
  timeout: 30s
  user: syslog        # optional — run as this lower-privilege local user

output:
  parser: text
  max_stdout_bytes: 524288
  max_stderr_bytes: 8192

# Optional.
examples:
  - title: Search syslog for sshd auth failures
    args:
      file: /var/log/syslog
      pattern: "sshd.*Failed password"
  - title: Tail nginx access for 5xx
    args:
      file: /var/log/nginx/access.log
      pattern: " 5\\d\\d "

Field reference#

  • kindexec (run a binary with an explicit argv) or script (run a script packaged in the pack, its bytes SHA-256-verified at load). There is no shell kind: both run as argv arrays through execve. An exec action may invoke /bin/sh -c for a fixed, pack-authored program. Open-ended strings and paths must reach that program through environment variables or whole positional arguments; only finite choices and two-sided bounded numbers may be substituted into its text. The critical, default-denied shell pack is the break-glass exception where the operator supplies the program itself.
  • risklow | medium | high | critical. The policy engine assigns a default decision per tier; higher tiers must be at least as restrictive as lower tiers. The runner declares risk in the pack; the caller can't override it.
  • args — every argument is declared. Types: string, integer, number, boolean, duration, path, string_array, integer_array. Validation tightens the type: enum, regex pattern, allowed_prefixes / denied_prefixes for paths, max_items for arrays, min/max for numbers, max_duration for durations.
  • execution.user — Linux-only. Drops the child process to that local user's uid and primary gid before exec, so a runner under a privileged service account still runs the action as the declared, lower-privilege user.
  • output.parsertext (default), json, or json (parser_required: true) to force the run to fail if stdout isn't valid JSON.
  • output.max_*_bytes — stdout/stderr ceilings. The cloud can lower these per-call via opts; it can't raise them past the declared maximum.
  • redact — per-action rules layered on top of 20 built-in patterns (AWS keys, GitHub/GitLab/Slack tokens, JWTs, bearer/basic auth, secret assignments). Redaction runs on the runner before output leaves the host; the control plane never sees the raw bytes, and per-rule hit counts are recorded.
  • examples — optional list of {title, args} entries. Each one renders as a clickable hint on the dispatch form, so operators and LLMs see realistic invocations before they type. Examples don't validate any tighter than the declared argument schema — they're documentation, not policy.

Pack trust#

Every pack is content-addressed by a SHA-256 over all its files. The control plane pins the hash an admin trusted; the runner recomputes it and refuses to run a pack whose on-disk bytes don't match. A new, changed, or custom pack blocks dispatch until an admin trusts its hash — a tampered mirror is rejected, not silently run. This is content integrity, not publisher signing: the runner trusts the exact bytes you approved.

  • Ship a host only the packs it needs. A web box has no use for the postgres pack; a smaller catalog is a smaller surface and a shorter list for an agent to reason over.
  • Keep the break-glass pack off production. The shell pack is the one action where the operator supplies the whole command — critical-risk, default-denied — for verifying a fix on staging before you encode it as a real action. Install it on staging; never on a prod runner.

Drift detection#

Once a pack is installed on at least one runner, the in-app Packs page groups every observed (pack_id, version, hash) in your account. Two runners on the same pack version with different hashes means somebody hand-edited a pack on a host — the page flags it as drift. Re-deploy from the canonical source to clear it.

Browse 50+ working packs in the public registry (linux-core, postgres, docker, kubernetes, nginx, redis, the AWS suite, vault, and more) — each shows every action it declares and a hash-pinned install snippet you can paste on a runner host. Want one of your own? Author your own pack.