Verbs are Guard's typed operation interface. A verb fixes a binary, validates
parameters, describes credential and execution plans, declares consequence, and
optionally supplies rollback. The daemon loads an operator catalog through
--verbs or GUARD_VERBS. Foreground servers hot-reload catalog changes. The
packaged Windows service loads its administrator-owned catalog once at startup.
guard verb list
guard verb show restart-service
guard verb run restart-service --param unit=nginxexamples/verbs.yaml contains command-template and
coverage-cell examples. A catalog may declare platform: unix or
platform: windows; Guard rejects a catalog for a different platform during
linting and startup.
On file-backed deployments, operators add one catalog entry from a YAML file containing exactly one verb definition as a top-level YAML mapping:
guard verb add --file inspect-service.yamlFor both verb add --file and verb amend --file, start the file with
name:. Omit the leading - list marker and the catalog's verbs: wrapper.
For example, a single-verb file for inspecting a systemd service contains:
name: inspect-service
binary: systemctl
args: [status, "{unit}", --no-pager]
params:
unit: { pattern: "^[a-zA-Z0-9@._-]+$", required: true }
consequence: reversibleThe daemon validates the candidate and the complete catalog before atomically appending it. The command fails without changing the catalog when the name already exists or the definition is invalid. Generated and reserved verb identities are not accepted through this operator-authored boundary. Adding a verb requires operator authentication.
Operators replace one catalog entry from a YAML file containing exactly one verb definition:
guard verb amend restart-service --file restart-service.yamlThe client reads the live definition first and binds the amendment to its definition digest. The daemon rejects the write if another catalog edit lands between that read and the replacement. It validates the candidate and complete catalog before atomically replacing the catalog file. The replacement must retain the requested name. Runtime-generated, automatically promoted, and reserved-namespace verbs cannot be amended through this command. Like other catalog mutations, amend requires the admin bearer.
The packaged Windows service treats the installed catalog as immutable process input and disables automatic promotion. Administrators update that catalog while the service is stopped, then restart the service to load the new bytes.
guard verb lint validates a catalog file directly, without contacting or
starting a daemon. It reports every invalid verb, naming the verb and the
failing parameter, instead of stopping at the first failure, and exits 1 when
findings exist. Linting a catalog with the new binary before swapping binaries
turns a would-be startup abort into a pre-upgrade report:
guard verb lint --file /var/lib/guard/verbs.yaml
guard verb lint --fixWithout --file, lint reads GUARD_VERBS or the daemon's default catalog
path. A structurally valid catalog whose verbs are not in canonical form also
exits 1 and names each verb needing repair; --fix applies the same
canonicalization the daemon performs at load time (operator-boundary
normalization and generated-authority envelopes) and rewrites the file through
the same atomic replacement path, printing each repaired verb.
A template renders each {param} as one argv element without a shell or word
splitting. Parameter patterns are fully anchored. A value cannot begin with -
unless the parameter explicitly permits it, which prevents parameter and flag
injection.
verbs:
- name: service-status
description: Show one service status
binary: systemctl
args: [status, "{unit}", --no-pager]
params:
unit: { pattern: "^[a-zA-Z0-9@._-]+$", required: true }
consequence: reversible
trusted: truetrusted: true skips the evaluator for a matching operation, but it does not
skip the consequence gate or hard invariants. Untrusted verbs keep the evaluator
as a backstop.
Parameters use token semantics by default and cannot contain whitespace.
Use value_type: single_argv with a required max_length only for a narrow,
bounded value that must retain ordinary spaces inside one argv element, such as
an exact query or selector. single_argv values remain unsplit and reject
control characters and shell operators. Automatically promoted verbs use this
form only when their finite observed values contain whitespace, with the bound
derived from those values.
hold: true routes every matching operation to operator approval after policy
admission, including operations declared reversible. Use it for reads whose
scope or sensitivity requires review, such as bulk account enumeration. The
field defaults to false when omitted.
Coverage cells describe regions of ordinary tool argv. They can constrain exact
required and forbidden tokens, option spellings and values, positional targets,
inventory, namespace, bounded fanout, an exact canonical working directory, and
caller-requested environment bindings.
Their actions are preauthorized, evaluate, or deny; preauthorization
requires a trusted verb.
- name: ansible-baseline
binary: ansible
consequence: reversible
credential_plan: ansible-managed-ssh
trusted: true
coverage:
- name: bounded-check
action: preauthorized
required_args: [--check]
inventory:
options: [-i, --inventory]
values: [/srv/guard/inventory/production]
fanout:
options: [--limit]
max: 2
environment:
- name: ANSIBLE_CONFIG
source: plain
values: [ansible.cfg]
- name: bounded-apply
action: evaluate
forbidden_args: [--check]
fanout:
options: [--limit]
max: 1
override_marker: operator:ansible-applyA non-matching cell has no decision. The check cell above allows its bounded region and does not deny apply mode, SSH inspection, or any other command. Those areas follow their own matching cells or evaluator path.
Recognized local-file operands in command and rollback templates must be
absolute. The bounded grammar covers documented option values and attached
short forms, including key=path and label@path payloads. It preserves
Ansible's non-file forms: inventories may be comma-terminated inline host
lists, extra variables may be inline values, and vault IDs may use prompt.
Referenced variable files, vault clients, module-path entries, credentials, and
configuration files must be absolute under the daemon host's path semantics.
Kubernetes file and kustomization sources are local absolute paths or standard
input, not caller-selected URLs. Executable selectors such as Helm post-renderers
must be fixed absolute paths. Transport passthroughs are fixed literals in exact
templates, never caller-selected generic coverage. Ambiguous command grammars
that cannot be modeled safely do not receive file-path coverage. If an explicit-inventory
Ansible process reports that no inventory was parsed, or that every supplied
source was unusable, Guard converts exit 0 to a failure and emits a diagnostic.
Environment sources are plain, secret, and secret-file. A constraint may
name exact values or a fully anchored pattern. A cell with no environment
constraints cannot preauthorize a request that adds caller-controlled bindings;
that request returns to the evaluator. Automatically promoted cells never
preauthorize environment bindings.
cwd binds a cell to one existing, absolute canonical directory. Guard
canonicalizes the caller directory before coverage resolution and revalidates it
immediately before execution, so a changed directory or symlink retarget cannot
reuse the cell. This bounds tools that discover configuration, plugins, or input
files from a project tree. Cwd-dependent opaque carriers do not enter automatic
verb promotion; an operator-authored typed verb supplies their durable authority.
Raw commands and access intents reverse-match the verb catalog. Guard collects every applicable cell, so the typed catalog remains authoritative without forcing agents to translate familiar commands.
Resolution follows these constraints:
- Hard invariants and explicit sticky operator boundaries are absolute.
- Session coverage applies over baseline coverage only inside activated regions.
- More specific cells win over broader cells in the same scope.
- Compatible matches compose with the most conservative consequence.
- Equally specific incompatible credential, execution, or rollback plans return to the evaluator as one conflict packet.
- If evaluation cannot produce one safe plan, the request holds. Authorization ambiguity fails closed with an escalation handle.
Catalog name order never chooses credentials or rollback. Global generated coverage cannot defeat an explicit operator deny. A live session can evaluate past matching global generated coverage under its own intent, while protocol hard-denies and operator policy remain floors.
Successful human output stays quiet. Machine-readable run results include all applicable cells. Held or denied human output identifies matching verbs and one durable access request. Denials offer ordinary, one-time, and bounded approval; holds offer only one-time approval.
baseline: false keeps a verb inactive until an issued grant names it. A session
may activate that verb or replace matching baseline preauthorization. A baseline
evaluate or deny cell with an override_marker changes only when the session
carries the same operator marker. Automatically generated verbs cannot declare
markers.
This split permits a readonly daemon baseline and a short-lived grant for apply mode on one host without making broad apply authority global.
guard verb create --preview safety-checks and validates a synthesized
candidate, then keeps it only in a bounded in-memory review cache. The preview
does not enter the active catalog. Direct creation and
guard verb create --from-preview enumerate every finite parameter binding and
run each rendered command through the production evaluator admission path with
execution disabled. A denial, non-finite pattern, or candidate set above the
admission bound prevents catalog persistence.
guard access request synthesizes typed coverage when no existing verb matches
the normalized intent. Proposed verbs cannot be baseline or trusted, use a
shell or interpreter binary, or accept unbounded whitespace or shell-control
patterns. A bounded single_argv parameter may carry an exact finite value
with ordinary spaces inside one argv element. Approval promotes only the
reviewed matcher to trusted
session-scoped coverage. The durable request stores the proposal and restores
it from SQLite while its access session is active. Guard derives consequence
locally, so unknown or mutating generated shapes remain irreversible holds. The
operator-authored catalog is unchanged. Equivalent typed shapes are reused
instead of duplicated.
With consequence gating active, repeated eligible evaluator approvals can
promote exact observed, statically read-only shapes into trusted verbs. Parameter
patterns contain only escaped values supported by evidence. Irreversible and
recoverable shapes are not auto-promoted: mutating commands remain under
consequence gating or operator review, and a model-proposed rollback never
creates unattended authority. An auto-promoted verb never carries a consequence
above reversible. Promotion records the evaluator regime, and a
model or prompt change sends stale coverage back to evaluation.
Auto-promoted verbs are marked auto_promoted in guard verb list, and their
coverage provenance states how it was produced: observation_replays record
the observed evaluator decisions a matcher was derived from, plus the
generator's own boundary example. Provenance probes are reserved for checks a
generator actually executed against the finished matcher; automatic promotion
records none.
API traffic uses the same verb vocabulary. Generated API cells bind endpoint, session fingerprint, full session revision, operation, namespace, body shape, protocol authority selectors, evaluator regime, and expiry. Authority selector identity includes attached option aliases, so changing an attached alias or the session revision requires a fresh evaluation. Value-bearing mutations remain evaluator-routed. Inspect or reset generated cells with:
guard verb coverage list
guard verb coverage clearGenerated coverage is an acceleration layer inside existing authority, not a new authority source.