Skip to content
contract-ops CLI suite

Tool · Python

contract-lint-cli

contract-lint-cli v0.2.4 1 455/wk on npm Latest from PyPI · checked Sun, 07 Jun 2026

A linter for a contract's internal consistency. Point it at one document and it flags the defects that slip past a read-through: leftover placeholders, broken cross-references ("as set out in Section 7.2" pointing at nothing), undefined / unused / duplicate defined terms, heading-number gaps, inconsistent party spellings, and impossible dates. Each defect is a finding (rule, severity, line, excerpt), and it exits non-zero so CI or an agent can gate on it. Fully deterministic — no model, no network, byte-stable output. Stdlib-only, single file.

It works standalone, and also composes with the contract-ops suite as the pre-signature quality gate. Its neighbor compare-cli gates drift between versions; contract-lint gates defects within one document — run both after draft and before sign.

TL;DR — pipx install contract-lint, then contract-lint demo for a zero-config run on a deliberately-flawed sample. Lint your own with contract-lint your-contract.md; gate CI with contract-lint contract.md --check --fail-on error. Deterministic, stdlib-only, no network.
contract-lint demo — linting a flawed contract

Try it live

Paste a contract (or load a flawed sample) and see the findings — leftover placeholders, broken refs, defined-term and numbering issues — in a sandbox, no install.

Runs the real CLI on your input in a sandbox — no setup, nothing stored. Open in a new tab ↗

What it does

  • Eleven deterministic rules. Errors: placeholder (leftover [Bracketed] / {{mustache}} / TBD) and broken-xref (a Section/Exhibit/Schedule reference with no target). Warnings (on by default): unused-definition, double-definition, numbering (gaps), duplicate-heading, party-consistency (variant spellings), date-sanity, number-consistency. Off by default: undefined-term and signature-block (opt in with --enable).
  • One document, five formats. Lints .md / .txt / .html natively and .docx / .pdf; reads - from stdin (pass --format md to tell it the input type).
  • A real CI gate. --fail-on error|warning|none sets the threshold; --check is exit-code-only (no output) for pipelines. Exit 0 clean · 1 findings at/above the threshold · 2 bad usage.
  • Machine-readable output. A human table by default; --json (locked schema, timestamp-free so it's diff-stable) and --sarif (SARIF 2.1.0 for code-scanning) for tools and agents.
  • Tunable. --enable / --disable a rule, or a --config file (the suite-wide ~/.config/contract-ops/ is honored). --why explains a finding on stderr.

Quickstart

install + run
# Install (zero runtime deps; single-file stdlib Python)
pipx install contract-lint
contract-lint --version

# Zero-config: lint a deliberately-flawed bundled contract
contract-lint demo

# Lint your own document; gate CI on errors only
contract-lint your-contract.md
contract-lint your-contract.md --check --fail-on error   # exit 1 if any error

# Machine-readable for tools / code-scanning
contract-lint your-contract.md --json | jq '.summary'
contract-lint your-contract.md --sarif > lint.sarif

For agents and automation

contract-lint answers the suite's discovery contract: contract-lint --catalog json returns {name, bin, version, description, commands[], exitCodes}, and contract-lint rules --json lists every rule (id, severity, default state) — call those at startup instead of hardcoding. The --json output is a locked, timestamp-free schema ({summary, findings[]}), so two runs on the same input diff cleanly. Branch on the exit code: 0 clean, 1 findings at/above --fail-on, 2 bad usage.

recommended agent defaults
contract-lint --catalog json                       # discover commands/flags
contract-lint rules --json                          # the rule catalog (id, severity, default)
contract-lint draft.md --json                       # structured findings to act on
contract-lint draft.md --check --fail-on error      # CI gate (exit 1 on any error)

Where it fits in the workflow

The pre-signature quality gate. After draft-cli fills a template (or you've ingested foreign paper with extract-cli), run contract-lint to catch internal defects and compare-cli to catch drift from the agreed version — two complementary gates before sign-cli seals it: draft → contract-lint / compare → docx2pdf → sign. It also stands alone as a CI check for any team that drafts contracts and wants a deterministic "did we leave a placeholder / break a cross-reference?" gate. See the full workflow.

Repo

github.com/DrBaher/contract-lint-cli · MIT licensed · Stdlib-only Python (single file) · PyPI contract-lint.

Edit this page on GitHub