Skip to content

Docs · Policy check

Gate merges on declared policy.

Available · Runs locally

ledgerful policy check evaluates a flat, named rule set against PR/diff/ledger state and exits nonzero on violation — offline, deterministic, no engine network code.

Honest limit

Policy as code is evaluation of declared rules, not a compliance certificate.

Honest limit: policy check evaluates the declared rules over the presented ledger and risk inputs. It is not a compliance verdict, certification, or proof that a change is safe. Chain continuity strengthens the presented ledger; it is still not a substitute for your org's change-management process.

Availability

The command is on the public engine source. Install from source (or a release binary that includes it).

Source install (includes policy check):

cargo install --git https://github.com/Ryan-AI-Studios/Ledgerful --bin ledgerful --locked

The v0.1.8 prebuilt release binaries predate this command. Use a source install, or a later release that ships policy check, until the next numbered release catches up. Confirm with ledgerful policy check --help.

Base-branch policy constraint

Read this before wiring CI.

Bypass-proof default: In CI the enforced policy is the base branch's (or a trusted --policy path), not your PR's. Edits to .ledgerful/policy.toml in a PR branch do not change the gate until they are merged and reviewed on the base branch.

When you run ledgerful policy check --pr origin/main...HEAD, Ledgerful loads .ledgerful/policy.toml via git show <base_ref>:.ledgerful/policy.toml. A policy change only takes effect after it is merged to the base branch. To pin an org-level file instead, pass --policy /path/to/org-policy.toml (trusted path).

Invocation

Human report by default; machine JSON for CI wrappers.

ledgerful policy check
ledgerful policy check --pr origin/main...HEAD
ledgerful policy check --pr origin/main...HEAD --fail-on high
ledgerful policy check --policy .ledgerful/policy.toml
ledgerful policy check --pr origin/main...HEAD --format json
FlagDescription
--pr <range>PR-style range (base...head, base..head, or bare base). Evaluates the committed range only.
--fail-on <level>Override config rules.fail_on for this run: off | low | medium | high.
--policy <path>Trusted policy file (org/CI). Skips base-branch and working-tree resolution.
--format json|textMachine contract (json) or human report (text, default).

Evaluation target

Local mode predicts CI for committed content and still catches pending work before push.

ModeWhat is inspected
--prCommitted range only — risk from the PR diff; committed ledger signatures and bound verification runs when a ledger DB is presented. Does not inspect pending DB transactions or the sidecar.
Local / defaultPending ledger txs, the pending_hook_tx sidecar, and working-tree risk when evaluable.

Git-only vs ledger-backed: .ledgerful/ is gitignored (state stays local). Force-add policy.toml for CI. Clean runners have no ledger.db unless your pipeline presents one. Use CI-safe rules (git-evaluable only) on the base branch unless you restore a ledger artifact.

Built-in rules

Named, parameterized rules in a flat TOML config. No expression-language DSL.

Rule idDefault (local / full)Behavior
require_signed_entriesonAny committed entry with missing or invalid signature/public_key is a violation. Fail-closed if the ledger database is absent (present an artifact or disable the rule).
no_pending_txonLocal only: pending ledger transactions and the pending_hook_tx sidecar are violations. Skipped under --pr (committed range only).
verification_must_passonA bound verification run for the evaluation target must pass. Fail-closed if the ledger database is absent or no bound run exists. Under --pr, every changed path needs a covering bound run (newest covering run is decisive).
max_risk_without_adrhighWhen risk is at or above the threshold, every changed path needs covering ADR evidence for this change set. Set to off to disable.
fail_onhighWhen risk is at or above the threshold, emit a violation. Risk uses the same levels as scan --pr. Set to off to disable.

Config examples

Flat .ledgerful/policy.toml. Force-add it so the base branch can serve it via git show.

CI-safe (recommended base branch)

# .ledgerful/policy.toml  (force-add; .ledgerful/ is gitignored)
preset = "enforce"

[rules]
require_signed_entries = false   # needs presented ledger.db
no_pending_tx = true             # skipped under --pr; useful locally
verification_must_pass = false   # needs presented ledger.db + bound runs
max_risk_without_adr = "high"    # off | low | medium | high
fail_on = "high"                 # off | low | medium | high

Full local / ledger-backed

preset = "enforce"

[rules]
require_signed_entries = true
no_pending_tx = true
verification_must_pass = true
max_risk_without_adr = "high"
fail_on = "high"

Presets: observe evaluates and warns but always exits 0. enforce blocks (nonzero exit) on violations. These presets subsume gate.mode (observe / enforce) without a breaking change — mode transitions still write signed MAINTENANCE ledger entries. Policy and mode never enter the Ed25519 signing basis.

JSON machine contract

--format json is the machine contract for CI wrappers (including the GitHub Action surface). Versioned; camelCase.

{
  "schemaVersion": 1,
  "violations": [
    {
      "ruleId": "no_pending_tx",
      "file": ".ledgerful/state/ledger.db",
      "line": null,
      "message": "pending ledger transaction a1b2c3d4 (entity=src/foo.rs)",
      "severity": "error"
    }
  ],
  "passed": false,
  "mode": "enforce",
  "policySource": "base-branch"
}

Per violation: ruleId, file, line, message, severity. passed is true only when there are zero violations. Optional notes is omitted when empty.

CI usage and permissions

Pairs with the GitHub Action surface: policy check only evaluates and exits; posting comments or check-runs stays in the Action wrapper.

PermissionWhy
contents: readCheckout and git show of the base-branch policy file.
pull-requests: readOptional Action wrapper may read PR metadata for annotations.
checks: writeOptional: native check-run from the 0047 Action wrapper. Not required for policy check itself.
name: Ledgerful policy gate

on:
  pull_request:

permissions:
  contents: read
  pull-requests: read
  checks: write

jobs:
  policy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install ledgerful
        run: cargo install --git https://github.com/Ryan-AI-Studios/Ledgerful --bin ledgerful --locked

      - name: Policy check
        run: |
          ledgerful policy check \
            --pr origin/${{ github.base_ref }}...HEAD \
            --format json \
            --fail-on high
  • Prefer a committed base-branch policy.toml with preset = "enforce" and CI-safe rules. If the base has no policy file, --pr synthesizes the same CI-safe enforce defaults (policySource: "synthesized").
  • fetch-depth: 0 (or an explicit fetch of the base ref) is required so git show can resolve the base policy.
  • To enforce ledger-backed rules in CI, present a ledger artifact and enable those rules on the base branch.
  • The engine path is offline: no network crates on the policy path. Network posting (if any) belongs to the Action wrapper, never the engine.

Related: GitHub Action docs (Action install status is separate from this CLI gate) and the Trust policy-as-code summary.