CLI reference¶
assent is a single static binary. Every command below is dispatched by the shipped
binary — this page is pinned to the binary's own help table by a test, so it cannot
drift from the tool.
Install it first (see Install), then check what you have:
assent version
Help output¶
assent --help (also -h, -help, help) prints the command listing on stdout
and exits 0. A bare assent, or an unknown command, prints the same listing on
stderr and exits 2 — the contract wrapper scripts rely on.
assent — deterministic, policy-driven auto-merge for self-service repositories
Usage:
assent <command> [arguments]
Commands:
run
Evaluate a merge request against its policy and reconcile the decision on the forge
usage: GITLAB_TOKEN=<pat> assent run --project <id> --mr <iid> --subject file:<path> --bot-author <user> [flags]
doctor
Report whether this environment can arm auto-merge, and why not when it cannot
usage: assent doctor
lint
Check a repository's .assent/** policy tree for hard errors
usage: assent lint <dir>
test
Run a repository's .assent/tests/** adopter cases against the real engine
usage: assent test [--update] [--coverage] <repo>
compare
Replay a comparison suite of baseline vs candidate policy and apply the promotion gates
usage: assent compare <dir> | assent compare --suite <dir>
catalogue
Emit the generated rule catalogue for a policy tree as JSON on stdout
usage: assent catalogue <dir>
render
Render a committed finding fixture as markdown for local preview
usage: assent render --finding examples/render/<case> [--artifact finding-thread|summary] [--presentation-minimal|--presentation-full]
eval-input
Assemble the EvaluationInput and pinned SHAs from the CI environment
usage: assent eval-input
version
Print the assent version
usage: assent version
help
Print this help listing
usage: assent help
assent run -h, assent compare -h and assent render -h list their flags.
Full command reference: https://platformrelay.github.io/Assent/usage/cli/
assent run¶
Evaluate a merge request against its policy and reconcile the decision on the forge:
read the MR, load the policy from the target ref, diff → classify → aggregate →
build and schema-validate the DecisionRecord, emit the record, then reconcile against
GitLab. The record is emitted before any forge write, so a run whose emit fails
aborts without touching the forge (D-122 — no record, no action).
GITLAB_TOKEN=<pat> assent run --project <id> --mr <iid> --subject file:<path> --bot-author <user> [flags]
The GitLab personal access token is read from the GITLAB_TOKEN environment variable
and is never a flag; without it the command exits 2 before contacting the forge.
assent run -h prints the same flag list.
| Flag | Default | Meaning |
|---|---|---|
-forge |
autodetect | Forge to drive: gitlab or github (E10-S13). Empty autodetects from the endpoint host and fails closed on ambiguity or an unrecognised host — no default forge exists. --forge github reads the token from GITHUB_TOKEN (the read-only pull_request scope suffices for forks per the dossier C17); GitLab keeps GITLAB_TOKEN. On GitHub, -project is an owner/repo pair and -mr is the PR number |
-project |
— | GitLab numeric project id, or GitHub owner/repo (required) |
-mr |
— | merge-request IID / PR number (required) |
-subject |
— | governed-subject entryRef (file:<path>) — the file diffed for evaluation (required) |
-bot-author |
— | bot username for the author-identity filter (required) |
-gitlab-endpoint |
https://gitlab.com |
Forge instance base URL (the default follows the forge: https://api.github.com for --forge github) |
-policy |
.assent/merge-policy.yaml |
MergePolicy path, loaded from the target ref |
-binding |
.assent/ruleset-binding.yaml |
RulesetBinding path, loaded from the target ref |
-config |
— | Config path (loaded from the target ref) — drives provider fact resolution; when set, provider posture is also validated |
-pack |
— | optional Pack path; its spec.phase caps every rule's phase. A phase ceiling is a rollout control, not a safety switch, and it is inert unless --pack is passed — see How to keep assent advisory |
-checkout |
— | local checkout dir (base/ + head/ subtrees) used to enumerate the MR's full changed-file set. The tree must contain no symlinks — see Symlinks in the checkout tree. When unset, the forge snapshot is the sole enumerator — see Checkout-less runs and enumeration completeness |
-emit |
stdout | path to write the DecisionRecord JSON |
-arm |
off | advisory only — it gates nothing. Approve and merge are gated by the forge-probed arming preconditions, which assent doctor reports, not by this flag. See What gates approve and merge |
Exit codes: 0 the run completed and produced a valid receipt (an advisory
REVIEW/BLOCK, or an APPROVE whose forge-probed arming preconditions are unmet, is
still a clean 0); 1 a hard error during orchestration; 2 a missing flag, a
missing GITLAB_TOKEN, or -h.
The trust-model material that used to follow the flag table — What gates approve and merge, How to keep assent advisory, Symlinks in the checkout tree, Known limitation: the checkout is not bound to the evaluated commit and Checkout-less runs and enumeration completeness — now lives in Operating safely.
assent doctor¶
Report whether this environment can arm auto-merge, and why not when it cannot.
assent doctor
"Armed" here means assent itself may approve and merge — immediately and SHA-pinned, on a run that decides APPROVE. It does not mean assent hands the forge a deferred merge-when-pipeline-succeeds instruction to fire later; it never does that. See What gates approve and merge, and Step 6 of the walkthrough.
With GITLAB_TOKEN set (plus CI_PROJECT_ID and CI_MERGE_REQUEST_IID) it probes the
forge for verified capabilities. Without a token it falls back to an env-only
diagnostic and prints an explicit INSECURE banner, because env self-assertions are
spoofable by an author-editable CI job.
Exit codes: 0 arming precondition met; 1 not armed (each blocking reason is
listed); 2 the forge probe could not run.
assent lint¶
Check a repository's .assent/** policy tree for hard errors. The directory argument
is the repository root — assent joins .assent itself.
assent lint <dir>
Exit codes: 0 no error diagnostics; 1 at least one error diagnostic; 2 usage or
discovery failure.
assent test¶
Run a repository's .assent/tests/** adopter cases against the real engine: each case
diffs its base/ ↔ head/ trees with the production differ, stubs facts.yaml into
the resolved-fact envelope, evaluates the pack, and asserts the produced decision
equals expect.yaml.
assent test [--update] [--coverage] <repo>
| Flag | Meaning |
|---|---|
--update |
rewrite each failing case's expect.yaml from the produced actual. Refused when a CI environment variable is set — auto-accepting actuals in CI would ratify a regression. Run it locally and review the diff. |
--coverage |
read-only both-polarity completeness gate. Never writes goldens, and supersedes --update when both are passed. |
Exit codes: 0 every case matched (or, under --update, every failing case was
refreshed); 1 a mismatch, write or load error; 2 usage, discovery or CI-guard
refusal.
assent compare¶
Replay a comparison suite of baseline vs candidate policy and apply the promotion gates: load immutable replay bundles, evaluate both sides through the same engine, classify the deltas, and gate the promotion.
assent compare <dir> | assent compare --suite <dir>
| Flag | Meaning |
|---|---|
--suite |
PolicyComparisonSuite directory, or a suite.yaml/suite.json path |
--baseline-profile |
baseline PolicyProfile name (overrides the suite default) |
--candidate-profile |
candidate PolicyProfile name (overrides the suite default) |
--record |
directory to write one ComparisonRecord JSON per case id |
Exit codes are the promotion-gate contract: 0 all gates pass; 1 a missed
destructive change; 2 a missed authorization/ownership change; 3 an unexpected
obligation removal; 4 auto-merge widening beyond the bound; 5 deltas that were not
explicitly accepted; 6 fail-closed — a load, schema, digest or classification error.
Two paths sit outside that contract and are easy to misread. 6 is also what an
unreadable or missing input directory returns, so a wrapper invoking
assent compare "$DIR" with $DIR unset reports fail-closed rather than a usage
error — check the stderr message before assuming a classification failure. And
assent compare -h prints the flag list and exits 0, which here means "help was
printed", not "all gates pass".
assent catalogue¶
Emit the generated rule catalogue for a policy tree as JSON on stdout, for the docs
pipeline. Catalogue generation is a docs artifact, not a gate, so it is a separate
command rather than a lint flag.
assent catalogue <dir>
Exit codes: 0 catalogue emitted; 2 usage, discovery or load failure.
assent render¶
Render a committed finding fixture as markdown for local preview, without a live merge request.
assent render --finding examples/render/<case> [--artifact finding-thread|summary] [--presentation-minimal|--presentation-full]
| Flag | Default | Meaning |
|---|---|---|
-finding |
— | render fixture directory under examples/render/<case> (required) |
-artifact |
finding-thread |
artifact to render: finding-thread or summary |
-presentation-minimal |
off | omit evaluation details (verbosity minimal) |
-presentation-full |
off | show all evaluation detail blocks (verbosity full) |
Exit codes: 0 markdown emitted; 1 the fixture failed to load or validate; 2 a
usage error.
assent eval-input¶
Assemble the EvaluationInput and pinned SHAs from the CI environment and print a one-line summary. This is the CI-adapter smoke path: it proves the environment boundary end-to-end without touching a policy.
assent eval-input
Exit codes: 0 assembled; 1 a required CI variable is missing or empty.
assent version¶
Print the assent version.
assent version
Release archives and the Homebrew build stamp the real semver at link time. A binary
built with go install reports 0.0.0-dev — see Install.
assent help¶
Print the command listing shown above on stdout and exit 0.
assent help